@aceandgaming/swarmfm-api 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,63 @@
1
+ # SwarmFMApi
2
+ `SwarmFMApi` is a lightweight JavaScript/TypeScript API for integrating and controlling [SwarmFM](https://player.sw.arm.fm/)
3
+ music playback in your web applications. It allows you to embed the SwarmFM player via an iframe, control playback programmatically, and respond to metadata and playback events.
4
+
5
+ **Note: This api is unofficial and not affiliated with SwarmFM or boop.**
6
+
7
+ This api uses server-side injection and thus the normal SwarmFM domains won't work. If creating the iframe manually you must use `swarmfm.swarmtunes.com`.
8
+
9
+ ## Usage
10
+ ```TS
11
+ import SwarmFMApi from 'swarmfm-api';
12
+
13
+ // Create an instance
14
+ const api = new SwarmFMApi();
15
+
16
+ // Create and attach iframe
17
+ const iframe = api.CreateIFrame({ silent: 'injector', autoplay: false, controls: true });
18
+ document.body.appendChild(iframe);
19
+
20
+ api.WaitForReady().then(() => {
21
+ // Play or pause
22
+ api.Play();
23
+ api.Pause();
24
+ })
25
+
26
+
27
+ // Listen to events
28
+ api.addEventListener('onplay', () => console.log('Music started playing'));
29
+ api.addEventListener('onmetadatachange', (metadata) => console.log('Now playing:', metadata.current));
30
+ ```
31
+
32
+ ## API
33
+
34
+ ### Properties
35
+
36
+ |Property|Type|Description|
37
+ |--------|----|-----------|
38
+ |`Playing` |`boolean`| Get or set whether the player is currently playing. Setting `true` plays, false `pauses`.|
39
+ |`Paused` |`boolean`| Get or set whether the player is paused. Inverse of `Playing`.|
40
+ |`Current` |`TrackMetadata?`| Returns metadata of the currently playing track.|
41
+ |`Previous` |`TrackMetadata?`| Returns metadata of the previous track.|
42
+ |`Next` |`TrackMetadata?`| Returns metadata of the next track.|
43
+
44
+ ### Methods
45
+
46
+ |Method|Description|
47
+ |------|-----------|
48
+ |`CreateIFrame(options?)`| Creates a iframe and automaticly attaches it|
49
+ |`Attach(iframe: HTMLIFrameElement)`| Attaches the API to an existing SwarmFM iframe and listens for events.
50
+ |`Play()`| Sends a message to the iframe to start playback.|
51
+ |`Pause()`| Sends a message to the iframe to pause playback.|
52
+ |`WaitForReady()`| A async function that resolves when the player is ready|
53
+ |`addEventListener(event: string, callback: Function)`|Registers an event listener.
54
+ |`removeEventListener(event: string, callback: Function)`|Removes a previously registered listener.|
55
+
56
+ ### Events
57
+
58
+ | Event | Arguments | Description |
59
+ | ------------------ | --------------------------- | ---------------------------------------------------------------- |
60
+ | `onplay` | None | Triggered when playback starts. |
61
+ | `onpause` | None | Triggered when playback is paused. |
62
+ | `onmetadatachange` | `metadata: SwarmFMMetadata` | Triggered when track metadata updates (current, previous, next). |
63
+ | `onready` | None | Triggered when the player is ready for playback. |
@@ -0,0 +1,47 @@
1
+ export type SwarmFMSong = {
2
+ artist: string;
3
+ bpm: number;
4
+ duration: number;
5
+ id: string;
6
+ name: string;
7
+ singer: string[];
8
+ album_cover_id?: string;
9
+ };
10
+ export type SwarmFMMetadata = {
11
+ previous: SwarmFMSong;
12
+ current: SwarmFMSong;
13
+ next: SwarmFMSong;
14
+ position: number;
15
+ };
16
+ interface SwarmFMEventMap {
17
+ "onplay": () => void;
18
+ "onpause": () => void;
19
+ "onmetadatachange": (metadata: SwarmFMMetadata) => void;
20
+ "onready": () => void;
21
+ }
22
+ export default class SwarmFMApi {
23
+ get Playing(): boolean;
24
+ get Paused(): boolean;
25
+ set Playing(playing: boolean);
26
+ set Paused(paused: boolean);
27
+ get Current(): SwarmFMSong | undefined;
28
+ get Previous(): SwarmFMSong | undefined;
29
+ get Next(): SwarmFMSong | undefined;
30
+ private metadata?;
31
+ private iframe?;
32
+ private playing;
33
+ private callbacks;
34
+ Attach(iframe: HTMLIFrameElement): void;
35
+ CreateIFrame(ops?: {
36
+ silent: "site" | "injector" | "all";
37
+ "autoplay": boolean;
38
+ "controls": boolean;
39
+ }): HTMLIFrameElement;
40
+ Play(): void;
41
+ Pause(): void;
42
+ WaitForReady(): Promise<void>;
43
+ addEventListener(event: keyof SwarmFMEventMap, callback: SwarmFMEventMap[keyof SwarmFMEventMap]): void;
44
+ removeEventListener(event: keyof SwarmFMEventMap, callback: SwarmFMEventMap[keyof SwarmFMEventMap]): void;
45
+ private dispatchEvent;
46
+ }
47
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,115 @@
1
+ export default class SwarmFMApi {
2
+ constructor() {
3
+ this.playing = false;
4
+ this.callbacks = {};
5
+ }
6
+ get Playing() {
7
+ return this.playing;
8
+ }
9
+ get Paused() {
10
+ return !this.playing;
11
+ }
12
+ set Playing(playing) {
13
+ if (playing) {
14
+ this.Play();
15
+ }
16
+ else {
17
+ this.Pause();
18
+ }
19
+ }
20
+ set Paused(paused) {
21
+ this.Playing = !paused;
22
+ }
23
+ get Current() {
24
+ var _a;
25
+ return (_a = this.metadata) === null || _a === void 0 ? void 0 : _a.current;
26
+ }
27
+ get Previous() {
28
+ var _a;
29
+ return (_a = this.metadata) === null || _a === void 0 ? void 0 : _a.previous;
30
+ }
31
+ get Next() {
32
+ var _a;
33
+ return (_a = this.metadata) === null || _a === void 0 ? void 0 : _a.next;
34
+ }
35
+ Attach(iframe) {
36
+ this.iframe = iframe;
37
+ window.onmessage = (event) => {
38
+ if (event.origin !== "https://swarmfm.swarmtunes.com") {
39
+ return;
40
+ }
41
+ switch (event.data.type) {
42
+ case "SWARMFM_METADATA":
43
+ this.metadata = event.data.data;
44
+ if (this.metadata) {
45
+ this.dispatchEvent("onmetadatachange", this.metadata);
46
+ }
47
+ break;
48
+ case "SWARMFM_PLAYING":
49
+ this.playing = true;
50
+ this.dispatchEvent("onplay");
51
+ break;
52
+ case "SWARMFM_PAUSED":
53
+ this.playing = false;
54
+ this.dispatchEvent("onpause");
55
+ break;
56
+ case "SWARMFM_READY":
57
+ this.dispatchEvent("onready");
58
+ break;
59
+ }
60
+ };
61
+ }
62
+ CreateIFrame(ops = { silent: "injector", autoplay: false, controls: true }) {
63
+ const iframe = document.createElement("iframe");
64
+ const prams = new URLSearchParams();
65
+ prams.set("silent", ops.silent);
66
+ prams.set("autoplay", ops.autoplay.toString());
67
+ prams.set("nocontrols", (!ops.controls).toString());
68
+ iframe.src = `https://swarmfm.swarmtunes.com/${prams.toString()}`;
69
+ this.Attach(iframe);
70
+ return iframe;
71
+ }
72
+ Play() {
73
+ var _a, _b;
74
+ (_b = (_a = this.iframe) === null || _a === void 0 ? void 0 : _a.contentWindow) === null || _b === void 0 ? void 0 : _b.postMessage({
75
+ type: "SWARMFM_PLAY"
76
+ }, "*");
77
+ }
78
+ Pause() {
79
+ var _a, _b;
80
+ (_b = (_a = this.iframe) === null || _a === void 0 ? void 0 : _a.contentWindow) === null || _b === void 0 ? void 0 : _b.postMessage({
81
+ type: "SWARMFM_PAUSE"
82
+ }, "*");
83
+ }
84
+ WaitForReady() {
85
+ return new Promise((resolve) => {
86
+ this.addEventListener("onready", () => {
87
+ resolve();
88
+ });
89
+ });
90
+ }
91
+ addEventListener(event, callback) {
92
+ if (this.callbacks[event] == null) {
93
+ this.callbacks[event] = [];
94
+ }
95
+ this.callbacks[event].push(callback);
96
+ }
97
+ removeEventListener(event, callback) {
98
+ if (this.callbacks[event] == null) {
99
+ return;
100
+ }
101
+ const index = this.callbacks[event].indexOf(callback);
102
+ if (index > -1) {
103
+ this.callbacks[event].splice(index, 1);
104
+ }
105
+ }
106
+ dispatchEvent(event, ...args) {
107
+ if (this.callbacks[event] == null) {
108
+ return;
109
+ }
110
+ for (const callback of this.callbacks[event]) {
111
+ // @ts-ignore
112
+ callback(...args);
113
+ }
114
+ }
115
+ }
package/package.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "@aceandgaming/swarmfm-api",
3
+ "version": "1.0.0",
4
+ "description": "A API for integrating and controlling SwarmFM",
5
+ "main": "dist/index.ts",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "scripts": {
11
+ "build": "tsc"
12
+ },
13
+ "keywords": [
14
+ "swarmfm",
15
+ "music",
16
+ "iframe",
17
+ "api",
18
+ "typescript"
19
+ ],
20
+ "author": "aceandgaming",
21
+ "license": "MIT",
22
+ "type": "commonjs",
23
+ "devDependencies": {
24
+ "typescript": "^6.0.2"
25
+ }
26
+ }