@students-dev/audify-js 1.0.0 → 1.0.2

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.
Files changed (50) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +93 -310
  3. package/dist/AudioEngine.js +232 -0
  4. package/dist/cjs/index.js +1497 -1392
  5. package/dist/cjs/index.js.map +1 -1
  6. package/dist/constants/index.js +35 -0
  7. package/dist/engine/Filters.js +137 -0
  8. package/dist/engine/MockAudioContext.js +53 -0
  9. package/dist/engine/Player.js +209 -0
  10. package/dist/esm/index.js +1490 -1389
  11. package/dist/esm/index.js.map +1 -1
  12. package/dist/events/EventBus.js +61 -0
  13. package/dist/index.js +18 -0
  14. package/dist/interfaces/index.js +1 -0
  15. package/dist/plugins/Plugin.js +27 -0
  16. package/dist/plugins/PluginManager.js +106 -0
  17. package/dist/providers/LavalinkProvider.js +81 -0
  18. package/dist/providers/LocalProvider.js +70 -0
  19. package/dist/providers/ProviderRegistry.js +20 -0
  20. package/dist/providers/SpotifyProvider.js +59 -0
  21. package/dist/providers/YouTubeProvider.js +48 -0
  22. package/dist/queue/Queue.js +186 -0
  23. package/dist/queue/Track.js +54 -0
  24. package/dist/types/AudioEngine.d.ts +107 -0
  25. package/dist/types/constants/index.d.ts +39 -0
  26. package/dist/types/engine/AudioEngine.d.ts +44 -1
  27. package/dist/types/engine/Filters.d.ts +25 -24
  28. package/dist/types/engine/MockAudioContext.d.ts +43 -0
  29. package/dist/types/engine/Player.d.ts +25 -21
  30. package/dist/types/events/EventBus.d.ts +17 -15
  31. package/dist/types/index.d.ts +17 -13
  32. package/dist/types/interfaces/index.d.ts +31 -0
  33. package/dist/types/plugins/Plugin.d.ts +11 -43
  34. package/dist/types/plugins/PluginManager.d.ts +19 -19
  35. package/dist/types/providers/LavalinkProvider.d.ts +17 -0
  36. package/dist/types/providers/LocalProvider.d.ts +11 -22
  37. package/dist/types/providers/ProviderRegistry.d.ts +10 -0
  38. package/dist/types/providers/SpotifyProvider.d.ts +14 -0
  39. package/dist/types/providers/YouTubeProvider.d.ts +11 -28
  40. package/dist/types/queue/Queue.d.ts +28 -22
  41. package/dist/types/queue/Track.d.ts +18 -16
  42. package/dist/types/utils/Logger.d.ts +12 -16
  43. package/dist/types/utils/Metadata.d.ts +16 -15
  44. package/dist/types/utils/Probe.d.ts +7 -7
  45. package/dist/types/utils/Time.d.ts +9 -9
  46. package/dist/utils/Logger.js +59 -0
  47. package/dist/utils/Metadata.js +90 -0
  48. package/dist/utils/Probe.js +59 -0
  49. package/dist/utils/Time.js +54 -0
  50. package/package.json +19 -9
@@ -0,0 +1,81 @@
1
+ import { Track } from '../queue/Track';
2
+ import { LavalinkManager } from 'lavalink-client';
3
+ export class LavalinkProvider {
4
+ constructor(options = {}) {
5
+ this.name = 'lavalink';
6
+ this.version = '1.0.0';
7
+ this.engine = null;
8
+ this.manager = null;
9
+ this.node = null;
10
+ this.options = options;
11
+ }
12
+ async initialize(engine) {
13
+ this.engine = engine;
14
+ this.manager = new LavalinkManager({
15
+ nodes: [{
16
+ host: this.options.host || 'localhost',
17
+ port: this.options.port || 2333,
18
+ // @ts-ignore
19
+ password: this.options.password || 'youshallnotpass',
20
+ secure: this.options.secure || false,
21
+ id: 'main'
22
+ }],
23
+ sendToShard: (guildId, payload) => {
24
+ // Mock
25
+ }
26
+ });
27
+ // @ts-ignore
28
+ if (this.manager.connect)
29
+ await this.manager.connect();
30
+ // @ts-ignore
31
+ this.node = this.manager.nodes ? this.manager.nodes.get('main') : this.manager.node;
32
+ }
33
+ async resolve(identifier) {
34
+ if (!this.node)
35
+ throw new Error('Lavalink not connected');
36
+ const result = await this.node.rest.loadTracks(identifier);
37
+ if (result.loadType === 'TRACK_LOADED') {
38
+ return this._formatTrack(result.tracks[0]);
39
+ }
40
+ else if (result.loadType === 'PLAYLIST_LOADED' || result.loadType === 'SEARCH_RESULT') {
41
+ return result.tracks.map((t) => this._formatTrack(t));
42
+ }
43
+ return [];
44
+ }
45
+ async play(track) {
46
+ throw new Error('Lavalink play() requires guild/channel context. Use createPlayer() directly.');
47
+ }
48
+ createPlayer(guildId, channelId) {
49
+ if (!this.manager)
50
+ throw new Error('Not initialized');
51
+ return this.manager.createPlayer({
52
+ guildId,
53
+ voiceChannelId: channelId
54
+ });
55
+ }
56
+ async stop() {
57
+ // Stop all?
58
+ }
59
+ destroy() {
60
+ if (this.manager) {
61
+ // @ts-ignore
62
+ if (this.manager.destroy)
63
+ this.manager.destroy();
64
+ }
65
+ }
66
+ _formatTrack(lavalinkTrack) {
67
+ const info = lavalinkTrack.info;
68
+ return new Track(info.uri, {
69
+ id: lavalinkTrack.track,
70
+ title: info.title,
71
+ artist: info.author,
72
+ duration: Math.floor(info.length / 1000),
73
+ thumbnail: info.artworkUrl,
74
+ source: 'lavalink',
75
+ metadata: {
76
+ lavalinkTrack: lavalinkTrack.track,
77
+ identifier: info.identifier
78
+ }
79
+ });
80
+ }
81
+ }
@@ -0,0 +1,70 @@
1
+ import { promises as fs } from 'fs';
2
+ import { extname } from 'path';
3
+ import { Track } from '../queue/Track';
4
+ export class LocalProvider {
5
+ constructor() {
6
+ this.name = 'local';
7
+ this.version = '1.0.0';
8
+ this.engine = null;
9
+ }
10
+ async initialize(engine) {
11
+ this.engine = engine;
12
+ }
13
+ async resolve(path) {
14
+ if (!await this.exists(path)) {
15
+ throw new Error('File not found');
16
+ }
17
+ // Node.js specific checks
18
+ const stats = await fs.stat(path);
19
+ if (!stats.isFile()) {
20
+ throw new Error('Path is not a file');
21
+ }
22
+ const track = new Track(`file://${path}`, {
23
+ title: path.split('/').pop()?.replace(extname(path), '') || 'Unknown',
24
+ source: 'local',
25
+ metadata: {
26
+ size: stats.size,
27
+ modified: stats.mtime
28
+ }
29
+ });
30
+ return track;
31
+ }
32
+ async play(track) {
33
+ if (!this.engine)
34
+ throw new Error('Provider not initialized');
35
+ // For local files, we assume the player can handle file:// URLs or we might need to read it into a buffer here?
36
+ // The previous Player implementation used fetch(url). fetch supports file:// in some envs but not all.
37
+ // However, given the hybrid nature, we'll assume the engine's player handles the URL.
38
+ // Actually, Player.ts uses fetch(). fetch('file://...') might fail in Node if not polyfilled or configured.
39
+ // But let's stick to the architecture: Provider calls engine.player.load(track).
40
+ // Wait, AudioEngine.ts in JS called `player.play(track)`.
41
+ // So the Provider.play just needs to confirm it CAN play or do setup?
42
+ // If AudioEngine delegates to Provider, then Provider MUST do the work.
43
+ // "AudioEngine calls provider.play(track)" -> Provider must make sound happen.
44
+ // So LocalProvider should call this.engine.player.play(track).
45
+ // BUT checking for infinite loop: Engine calls Provider.play -> Provider calls Engine.player.play?
46
+ // Engine needs to know NOT to call Provider again.
47
+ // Engine.play(track) -> check provider -> provider.play(track)
48
+ // Provider.play(track) -> engine.player.loadSource(track.url) -> source.start()
49
+ // We need to expose `loadSource` or similar on engine/player.
50
+ // For now, I'll assume engine.player has low-level methods.
51
+ // Let's assume the Player has a `playStream(url)` method.
52
+ // I'll type cast engine.player for now.
53
+ await this.engine.player.playStream(track);
54
+ }
55
+ async stop() {
56
+ // Local provider doesn't manage state separate from engine
57
+ }
58
+ destroy() {
59
+ // No cleanup needed
60
+ }
61
+ async exists(path) {
62
+ try {
63
+ await fs.access(path);
64
+ return true;
65
+ }
66
+ catch {
67
+ return false;
68
+ }
69
+ }
70
+ }
@@ -0,0 +1,20 @@
1
+ export class ProviderRegistry {
2
+ constructor() {
3
+ this.providers = new Map();
4
+ }
5
+ register(provider) {
6
+ this.providers.set(provider.name, provider);
7
+ }
8
+ unregister(name) {
9
+ this.providers.delete(name);
10
+ }
11
+ get(name) {
12
+ return this.providers.get(name);
13
+ }
14
+ getAll() {
15
+ return Array.from(this.providers.values());
16
+ }
17
+ has(name) {
18
+ return this.providers.has(name);
19
+ }
20
+ }
@@ -0,0 +1,59 @@
1
+ import { Track } from '../queue/Track';
2
+ import SpotifyWebApi from 'spotify-web-api-node';
3
+ export class SpotifyProvider {
4
+ constructor(options = {}) {
5
+ this.name = 'spotify';
6
+ this.version = '1.0.0';
7
+ this.engine = null;
8
+ this.spotifyApi = new SpotifyWebApi({
9
+ clientId: options.clientId,
10
+ clientSecret: options.clientSecret,
11
+ redirectUri: options.redirectUri,
12
+ accessToken: options.accessToken,
13
+ refreshToken: options.refreshToken
14
+ });
15
+ }
16
+ async initialize(engine) {
17
+ this.engine = engine;
18
+ }
19
+ async resolve(query) {
20
+ // Check if query is ID or URL or Search
21
+ if (query.includes('spotify.com/track/')) {
22
+ const id = query.split('track/')[1].split('?')[0];
23
+ const data = await this.spotifyApi.getTrack(id);
24
+ return this._formatTrack(data.body);
25
+ }
26
+ // Default to search
27
+ const data = await this.spotifyApi.searchTracks(query);
28
+ return data.body.tracks?.items.map(t => this._formatTrack(t)) || [];
29
+ }
30
+ async play(track) {
31
+ if (!this.engine)
32
+ throw new Error('Provider not initialized');
33
+ // Spotify playback usually requires Web SDK or resolving to another source
34
+ // Here we can throw or try to resolve if Preview URL is available
35
+ if (track.metadata.preview_url) {
36
+ await this.engine.player.playStream({ ...track, url: track.metadata.preview_url });
37
+ }
38
+ else {
39
+ throw new Error('Spotify full playback not supported in this provider version (preview only)');
40
+ }
41
+ }
42
+ async stop() { }
43
+ destroy() { }
44
+ _formatTrack(spotifyTrack) {
45
+ return new Track(spotifyTrack.external_urls.spotify, {
46
+ id: spotifyTrack.id,
47
+ title: spotifyTrack.name,
48
+ artist: spotifyTrack.artists.map((a) => a.name).join(', '),
49
+ duration: Math.floor(spotifyTrack.duration_ms / 1000),
50
+ thumbnail: spotifyTrack.album.images[0]?.url,
51
+ source: 'spotify',
52
+ metadata: {
53
+ spotifyId: spotifyTrack.id,
54
+ preview_url: spotifyTrack.preview_url,
55
+ popularity: spotifyTrack.popularity
56
+ }
57
+ });
58
+ }
59
+ }
@@ -0,0 +1,48 @@
1
+ import { Track } from '../queue/Track';
2
+ export class YouTubeProvider {
3
+ constructor() {
4
+ this.name = 'youtube';
5
+ this.version = '1.0.0';
6
+ this.engine = null;
7
+ }
8
+ async initialize(engine) {
9
+ this.engine = engine;
10
+ }
11
+ async resolve(query) {
12
+ if (query.includes('youtube.com') || query.includes('youtu.be')) {
13
+ const videoId = this.extractVideoId(query);
14
+ if (!videoId)
15
+ throw new Error('Invalid YouTube URL');
16
+ return new Track(query, {
17
+ title: `YouTube Video ${videoId}`,
18
+ thumbnail: `https://img.youtube.com/vi/${videoId}/maxresdefault.jpg`,
19
+ source: 'youtube',
20
+ metadata: { videoId }
21
+ });
22
+ }
23
+ // Search not implemented in this mock
24
+ throw new Error('Search not implemented');
25
+ }
26
+ async play(track) {
27
+ if (!this.engine)
28
+ throw new Error('Provider not initialized');
29
+ // In a real app, resolve stream URL here (e.g. ytdl-core)
30
+ // const streamUrl = await ytdl(track.url);
31
+ // await this.engine.player.playStream(streamUrl);
32
+ throw new Error('Stream URL extraction requires additional dependencies (ytdl-core)');
33
+ }
34
+ async stop() { }
35
+ destroy() { }
36
+ extractVideoId(url) {
37
+ try {
38
+ const urlObj = new URL(url);
39
+ if (urlObj.hostname === 'youtu.be') {
40
+ return urlObj.pathname.slice(1);
41
+ }
42
+ return urlObj.searchParams.get('v');
43
+ }
44
+ catch {
45
+ return null;
46
+ }
47
+ }
48
+ }
@@ -0,0 +1,186 @@
1
+ import { Track } from './Track';
2
+ import { EventBus } from '../events/EventBus';
3
+ import { EVENTS } from '../constants';
4
+ /**
5
+ * Audio queue management
6
+ */
7
+ export class Queue {
8
+ constructor() {
9
+ this.tracks = [];
10
+ this.currentIndex = -1;
11
+ this.eventBus = new EventBus();
12
+ }
13
+ /**
14
+ * Add track(s) to queue
15
+ * @param tracks - Track(s) to add
16
+ * @param position - Position to insert (optional)
17
+ */
18
+ add(tracks, position) {
19
+ const trackArray = Array.isArray(tracks) ? tracks : [tracks];
20
+ const processedTracks = trackArray.map(track => {
21
+ if (typeof track === 'string') {
22
+ return new Track(track);
23
+ }
24
+ if (track instanceof Track) {
25
+ return track;
26
+ }
27
+ // It's ITrack or similar object
28
+ return new Track(track.url, track);
29
+ });
30
+ if (position !== undefined && position >= 0 && position <= this.tracks.length) {
31
+ this.tracks.splice(position, 0, ...processedTracks);
32
+ }
33
+ else {
34
+ this.tracks.push(...processedTracks);
35
+ }
36
+ processedTracks.forEach(track => {
37
+ this.eventBus.emit(EVENTS.TRACK_ADD, track);
38
+ });
39
+ this.eventBus.emit(EVENTS.QUEUE_UPDATE, this.tracks);
40
+ }
41
+ /**
42
+ * Remove track from queue
43
+ * @param identifier - Track index or ID
44
+ * @returns Removed track
45
+ */
46
+ remove(identifier) {
47
+ let index;
48
+ if (typeof identifier === 'number') {
49
+ index = identifier;
50
+ }
51
+ else {
52
+ index = this.tracks.findIndex(track => track.id === identifier);
53
+ }
54
+ if (index < 0 || index >= this.tracks.length)
55
+ return null;
56
+ const removed = this.tracks.splice(index, 1)[0];
57
+ if (this.currentIndex > index) {
58
+ this.currentIndex--;
59
+ }
60
+ else if (this.currentIndex === index) {
61
+ this.currentIndex = -1;
62
+ }
63
+ this.eventBus.emit(EVENTS.TRACK_REMOVE, removed);
64
+ this.eventBus.emit(EVENTS.QUEUE_UPDATE, this.tracks);
65
+ return removed;
66
+ }
67
+ /**
68
+ * Shuffle the queue
69
+ */
70
+ shuffle() {
71
+ if (this.tracks.length <= 1)
72
+ return;
73
+ let currentTrack = null;
74
+ if (this.currentIndex >= 0) {
75
+ currentTrack = this.tracks[this.currentIndex];
76
+ }
77
+ for (let i = this.tracks.length - 1; i > 0; i--) {
78
+ const j = Math.floor(Math.random() * (i + 1));
79
+ [this.tracks[i], this.tracks[j]] = [this.tracks[j], this.tracks[i]];
80
+ }
81
+ if (currentTrack) {
82
+ this.currentIndex = this.tracks.indexOf(currentTrack);
83
+ }
84
+ else {
85
+ this.currentIndex = -1;
86
+ }
87
+ this.eventBus.emit(EVENTS.QUEUE_UPDATE, this.tracks);
88
+ }
89
+ /**
90
+ * Clear the queue
91
+ */
92
+ clear() {
93
+ this.tracks = [];
94
+ this.currentIndex = -1;
95
+ this.eventBus.emit(EVENTS.QUEUE_UPDATE, this.tracks);
96
+ }
97
+ /**
98
+ * Jump to specific track
99
+ * @param index - Track index
100
+ * @returns Track at index
101
+ */
102
+ jump(index) {
103
+ if (index < 0 || index >= this.tracks.length)
104
+ return null;
105
+ this.currentIndex = index;
106
+ return this.tracks[index];
107
+ }
108
+ /**
109
+ * Get current track
110
+ * @returns Current track
111
+ */
112
+ getCurrent() {
113
+ return this.currentIndex >= 0 ? this.tracks[this.currentIndex] : null;
114
+ }
115
+ /**
116
+ * Get next track
117
+ * Moves cursor forward
118
+ * @param loop - Whether to loop back to start
119
+ * @returns Next track
120
+ */
121
+ next(loop = false) {
122
+ if (this.tracks.length === 0)
123
+ return null;
124
+ let nextIndex = this.currentIndex + 1;
125
+ if (nextIndex >= this.tracks.length) {
126
+ if (loop) {
127
+ nextIndex = 0;
128
+ }
129
+ else {
130
+ return null;
131
+ }
132
+ }
133
+ this.currentIndex = nextIndex;
134
+ return this.tracks[this.currentIndex];
135
+ }
136
+ /**
137
+ * Get previous track
138
+ * Moves cursor backward
139
+ * @param loop - Whether to loop to end
140
+ * @returns Previous track
141
+ */
142
+ previous(loop = false) {
143
+ if (this.tracks.length === 0)
144
+ return null;
145
+ let prevIndex = this.currentIndex - 1;
146
+ if (prevIndex < 0) {
147
+ if (loop) {
148
+ prevIndex = this.tracks.length - 1;
149
+ }
150
+ else {
151
+ return null;
152
+ }
153
+ }
154
+ this.currentIndex = prevIndex;
155
+ return this.tracks[this.currentIndex];
156
+ }
157
+ /**
158
+ * Get all tracks
159
+ * @returns Array of tracks
160
+ */
161
+ getTracks() {
162
+ return [...this.tracks];
163
+ }
164
+ /**
165
+ * Get queue size
166
+ * @returns Number of tracks
167
+ */
168
+ size() {
169
+ return this.tracks.length;
170
+ }
171
+ /**
172
+ * Check if queue is empty
173
+ * @returns Is empty
174
+ */
175
+ isEmpty() {
176
+ return this.tracks.length === 0;
177
+ }
178
+ /**
179
+ * Get track at index
180
+ * @param index - Track index
181
+ * @returns Track at index
182
+ */
183
+ getTrack(index) {
184
+ return index >= 0 && index < this.tracks.length ? this.tracks[index] : null;
185
+ }
186
+ }
@@ -0,0 +1,54 @@
1
+ import { MetadataUtils } from '../utils/Metadata';
2
+ /**
3
+ * Represents an audio track
4
+ */
5
+ export class Track {
6
+ /**
7
+ * @param url - Track URL or file path
8
+ * @param options - Additional options
9
+ */
10
+ constructor(url, options = {}) {
11
+ const extracted = MetadataUtils.extract(url);
12
+ this.url = url;
13
+ this.title = options.title || extracted.title || 'Unknown Title';
14
+ this.artist = options.artist || extracted.artist;
15
+ this.duration = options.duration || extracted.duration;
16
+ this.thumbnail = options.thumbnail || extracted.thumbnail;
17
+ this.source = options.source || extracted.source || 'unknown';
18
+ this.metadata = options.metadata || {};
19
+ this.id = options.id || Math.random().toString(36).substr(2, 9);
20
+ }
21
+ /**
22
+ * Get track info
23
+ * @returns Track information
24
+ */
25
+ getInfo() {
26
+ return {
27
+ id: this.id,
28
+ url: this.url,
29
+ title: this.title,
30
+ artist: this.artist,
31
+ duration: this.duration,
32
+ thumbnail: this.thumbnail,
33
+ source: this.source,
34
+ metadata: this.metadata
35
+ };
36
+ }
37
+ /**
38
+ * Update track metadata
39
+ * @param metadata - New metadata
40
+ */
41
+ updateMetadata(metadata) {
42
+ Object.assign(this, metadata);
43
+ if (metadata.metadata) {
44
+ Object.assign(this.metadata, metadata.metadata);
45
+ }
46
+ }
47
+ /**
48
+ * Check if track is valid
49
+ * @returns Is valid
50
+ */
51
+ isValid() {
52
+ return !!(this.url && this.title);
53
+ }
54
+ }
@@ -0,0 +1,107 @@
1
+ import { Player } from './engine/Player';
2
+ import { Filters } from './engine/Filters';
3
+ import { Queue } from './queue/Queue';
4
+ import { EventBus } from './events/EventBus';
5
+ import { ProviderRegistry } from './providers/ProviderRegistry';
6
+ import { PluginManager } from './plugins/PluginManager';
7
+ import { LoopMode } from './constants';
8
+ import { IAudioEngine, IProvider, ITrack } from './interfaces';
9
+ /**
10
+ * Main audio engine class
11
+ */
12
+ export declare class AudioEngine implements IAudioEngine {
13
+ options: any;
14
+ player: Player;
15
+ filters: Filters;
16
+ queue: Queue;
17
+ eventBus: EventBus;
18
+ providers: ProviderRegistry;
19
+ plugins: PluginManager;
20
+ isReady: boolean;
21
+ constructor(options?: any);
22
+ /**
23
+ * Initialize the audio engine
24
+ */
25
+ initialize(): Promise<void>;
26
+ registerProvider(provider: IProvider): Promise<void>;
27
+ getProvider(name: string): IProvider | undefined;
28
+ /**
29
+ * Play track or resume playback
30
+ * @param track - Track to play or track identifier
31
+ */
32
+ play(track?: ITrack | string): Promise<void>;
33
+ /**
34
+ * Pause playback
35
+ */
36
+ pause(): void;
37
+ /**
38
+ * Stop playback
39
+ */
40
+ stop(): void;
41
+ /**
42
+ * Seek to position
43
+ * @param time - Time in seconds
44
+ */
45
+ seek(time: number): void;
46
+ /**
47
+ * Set volume
48
+ * @param volume - Volume level (0-1)
49
+ */
50
+ setVolume(volume: number): void;
51
+ /**
52
+ * Add track(s) to queue
53
+ * @param tracks - Track(s) to add
54
+ */
55
+ add(tracks: ITrack | ITrack[] | string | string[]): void;
56
+ /**
57
+ * Remove track from queue
58
+ * @param identifier - Track index or ID
59
+ */
60
+ remove(identifier: number | string): ITrack | null;
61
+ /**
62
+ * Skip to next track
63
+ */
64
+ next(): void;
65
+ /**
66
+ * Go to previous track
67
+ */
68
+ previous(): void;
69
+ /**
70
+ * Shuffle queue
71
+ */
72
+ shuffle(): void;
73
+ /**
74
+ * Clear queue
75
+ */
76
+ clear(): void;
77
+ /**
78
+ * Jump to track in queue
79
+ * @param index - Track index
80
+ */
81
+ jump(index: number): void;
82
+ /**
83
+ * Apply audio filter
84
+ * @param type - Filter type
85
+ * @param options - Filter options
86
+ */
87
+ applyFilter(type: any, options: any): void;
88
+ /**
89
+ * Remove audio filter
90
+ * @param type - Filter type
91
+ */
92
+ removeFilter(type: any): void;
93
+ /**
94
+ * Set loop mode
95
+ * @param mode - Loop mode
96
+ */
97
+ setLoopMode(mode: LoopMode): void;
98
+ /**
99
+ * Get current state
100
+ * @returns Engine state
101
+ */
102
+ getState(): any;
103
+ /**
104
+ * Destroy the engine
105
+ */
106
+ destroy(): void;
107
+ }
@@ -0,0 +1,39 @@
1
+ export declare const EVENTS: {
2
+ readonly READY: "ready";
3
+ readonly ERROR: "error";
4
+ readonly PLAY: "play";
5
+ readonly PAUSE: "pause";
6
+ readonly STOP: "stop";
7
+ readonly TRACK_START: "trackStart";
8
+ readonly TRACK_END: "trackEnd";
9
+ readonly TRACK_ADD: "trackAdd";
10
+ readonly TRACK_REMOVE: "trackRemove";
11
+ readonly QUEUE_UPDATE: "queueUpdate";
12
+ readonly FILTER_APPLIED: "filterApplied";
13
+ readonly VOLUME_CHANGE: "volumeChange";
14
+ readonly SEEK: "seek";
15
+ };
16
+ export type EventType = typeof EVENTS[keyof typeof EVENTS];
17
+ export declare const LOOP_MODES: {
18
+ readonly OFF: "off";
19
+ readonly TRACK: "track";
20
+ readonly QUEUE: "queue";
21
+ };
22
+ export type LoopMode = typeof LOOP_MODES[keyof typeof LOOP_MODES];
23
+ export declare const PLAYER_STATES: {
24
+ readonly IDLE: "idle";
25
+ readonly PLAYING: "playing";
26
+ readonly PAUSED: "paused";
27
+ readonly BUFFERING: "buffering";
28
+ };
29
+ export type PlayerState = typeof PLAYER_STATES[keyof typeof PLAYER_STATES];
30
+ export declare const FILTER_TYPES: {
31
+ readonly BASSBOOST: "bassboost";
32
+ readonly NIGHTCORE: "nightcore";
33
+ readonly VAPORWAVE: "vaporwave";
34
+ readonly ROTATE_8D: "8d";
35
+ readonly PITCH: "pitch";
36
+ readonly SPEED: "speed";
37
+ readonly REVERB: "reverb";
38
+ };
39
+ export type FilterType = typeof FILTER_TYPES[keyof typeof FILTER_TYPES];