disvoice 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.
Files changed (39) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +410 -0
  3. package/dist/MusicPlayer.d.ts +81 -0
  4. package/dist/MusicPlayer.d.ts.map +1 -0
  5. package/dist/MusicPlayer.js +258 -0
  6. package/dist/MusicPlayer.js.map +1 -0
  7. package/dist/Queue.d.ts +69 -0
  8. package/dist/Queue.d.ts.map +1 -0
  9. package/dist/Queue.js +149 -0
  10. package/dist/Queue.js.map +1 -0
  11. package/dist/index.d.ts +9 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +34 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/sources/BaseSource.d.ts +22 -0
  16. package/dist/sources/BaseSource.d.ts.map +1 -0
  17. package/dist/sources/BaseSource.js +19 -0
  18. package/dist/sources/BaseSource.js.map +1 -0
  19. package/dist/sources/SoundCloudSource.d.ts +10 -0
  20. package/dist/sources/SoundCloudSource.d.ts.map +1 -0
  21. package/dist/sources/SoundCloudSource.js +124 -0
  22. package/dist/sources/SoundCloudSource.js.map +1 -0
  23. package/dist/sources/SpotifySource.d.ts +12 -0
  24. package/dist/sources/SpotifySource.d.ts.map +1 -0
  25. package/dist/sources/SpotifySource.js +129 -0
  26. package/dist/sources/SpotifySource.js.map +1 -0
  27. package/dist/sources/YouTubeSource.d.ts +14 -0
  28. package/dist/sources/YouTubeSource.d.ts.map +1 -0
  29. package/dist/sources/YouTubeSource.js +174 -0
  30. package/dist/sources/YouTubeSource.js.map +1 -0
  31. package/dist/types/index.d.ts +47 -0
  32. package/dist/types/index.d.ts.map +1 -0
  33. package/dist/types/index.js +11 -0
  34. package/dist/types/index.js.map +1 -0
  35. package/dist/utils/TimeFormat.d.ts +3 -0
  36. package/dist/utils/TimeFormat.d.ts.map +1 -0
  37. package/dist/utils/TimeFormat.js +29 -0
  38. package/dist/utils/TimeFormat.js.map +1 -0
  39. package/package.json +57 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 disvoice
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,410 @@
1
+ # disvoice 🎵
2
+
3
+ Universal music player for Discord bots with support for **YouTube**, **Spotify**, **SoundCloud** and more platforms.
4
+
5
+ ## Features
6
+
7
+ ✨ **Multi-Platform Support**
8
+ - 🎥 YouTube (videos & playlists)
9
+ - 🎵 Spotify (tracks, albums & playlists)
10
+ - 🔊 SoundCloud (tracks & playlists)
11
+
12
+ 🎮 **Complete Playback Control**
13
+ - Play, pause, resume, stop
14
+ - Skip tracks
15
+ - Volume control
16
+ - Queue management (shuffle, loop, history)
17
+
18
+ 🚀 **Easy to Use**
19
+ - Simple API
20
+ - TypeScript support
21
+ - Event-based system
22
+ - Auto-disconnect on idle
23
+
24
+ ## Installation
25
+
26
+ ```bash
27
+ npm install disvoice
28
+ ```
29
+
30
+ ### Required Dependencies
31
+
32
+ ```bash
33
+ npm install discord.js @discordjs/voice
34
+ ```
35
+
36
+ You also need to install additional dependencies for audio processing:
37
+
38
+ ```bash
39
+ npm install sodium-native # or libsodium-wrappers
40
+ npm install @discordjs/opus # or opusscript
41
+ npm install ffmpeg-static
42
+ ```
43
+
44
+ ## Quick Start
45
+
46
+ ```javascript
47
+ const { Client, GatewayIntentBits } = require('discord.js');
48
+ const { MusicPlayer } = require('disvoice');
49
+
50
+ const client = new Client({
51
+ intents: [
52
+ GatewayIntentBits.Guilds,
53
+ GatewayIntentBits.GuildVoiceStates,
54
+ GatewayIntentBits.GuildMessages,
55
+ GatewayIntentBits.MessageContent
56
+ ]
57
+ });
58
+
59
+ const player = new MusicPlayer({
60
+ leaveOnEmpty: true,
61
+ leaveOnEmptyCooldown: 60000,
62
+ volume: 50
63
+ });
64
+
65
+ client.on('messageCreate', async (message) => {
66
+ if (message.content.startsWith('!play')) {
67
+ const query = message.content.slice(6);
68
+ const channel = message.member?.voice.channel;
69
+
70
+ if (!channel) {
71
+ return message.reply('You need to be in a voice channel!');
72
+ }
73
+
74
+ try {
75
+ const result = await player.play(query, message.author, channel);
76
+
77
+ if (result.playlist) {
78
+ message.reply(`Added **${result.tracks.length}** tracks from playlist: **${result.playlist.name}**`);
79
+ } else {
80
+ message.reply(`Added to queue: **${result.tracks[0].title}**`);
81
+ }
82
+ } catch (error) {
83
+ message.reply(`Error: ${error.message}`);
84
+ }
85
+ }
86
+ });
87
+
88
+ client.login('YOUR_BOT_TOKEN');
89
+ ```
90
+
91
+ ## API Reference
92
+
93
+ ### MusicPlayer
94
+
95
+ Main class for music playback.
96
+
97
+ #### Constructor
98
+
99
+ ```typescript
100
+ const player = new MusicPlayer(options?: PlayerOptions);
101
+ ```
102
+
103
+ **PlayerOptions:**
104
+ ```typescript
105
+ {
106
+ leaveOnEmpty?: boolean; // Leave when queue is empty (default: true)
107
+ leaveOnEmptyCooldown?: number; // Cooldown before leaving in ms (default: 60000)
108
+ leaveOnEnd?: boolean; // Leave when track ends and queue is empty (default: true)
109
+ volume?: number; // Default volume 0-100 (default: 100)
110
+ }
111
+ ```
112
+
113
+ #### Methods
114
+
115
+ ##### play(query, requester, channel?)
116
+ Play a track or add to queue.
117
+
118
+ ```typescript
119
+ await player.play(
120
+ 'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
121
+ message.author,
122
+ voiceChannel
123
+ );
124
+ ```
125
+
126
+ **Supported formats:**
127
+ - YouTube URLs (videos & playlists)
128
+ - Spotify URLs (tracks, albums & playlists)
129
+ - SoundCloud URLs (tracks & playlists)
130
+ - Search queries (searches YouTube)
131
+
132
+ ##### skip()
133
+ Skip current track.
134
+
135
+ ```typescript
136
+ const nextTrack = player.skip();
137
+ ```
138
+
139
+ ##### pause()
140
+ Pause playback.
141
+
142
+ ```typescript
143
+ player.pause();
144
+ ```
145
+
146
+ ##### resume()
147
+ Resume playback.
148
+
149
+ ```typescript
150
+ player.resume();
151
+ ```
152
+
153
+ ##### stop()
154
+ Stop playback and clear queue.
155
+
156
+ ```typescript
157
+ player.stop();
158
+ ```
159
+
160
+ ##### setVolume(volume)
161
+ Set volume (0-100).
162
+
163
+ ```typescript
164
+ player.setVolume(75);
165
+ ```
166
+
167
+ ##### getVolume()
168
+ Get current volume.
169
+
170
+ ```typescript
171
+ const volume = player.getVolume();
172
+ ```
173
+
174
+ ##### disconnect()
175
+ Disconnect from voice channel.
176
+
177
+ ```typescript
178
+ player.disconnect();
179
+ ```
180
+
181
+ ##### getQueue()
182
+ Get the queue instance.
183
+
184
+ ```typescript
185
+ const queue = player.getQueue();
186
+ const tracks = queue.getTracks();
187
+ ```
188
+
189
+ ##### getCurrentTrack()
190
+ Get currently playing track.
191
+
192
+ ```typescript
193
+ const track = player.getCurrentTrack();
194
+ ```
195
+
196
+ ### Queue
197
+
198
+ Queue management system.
199
+
200
+ #### Methods
201
+
202
+ ##### add(track)
203
+ Add a track to queue.
204
+
205
+ ```typescript
206
+ queue.add(track);
207
+ ```
208
+
209
+ ##### addMany(tracks)
210
+ Add multiple tracks.
211
+
212
+ ```typescript
213
+ queue.addMany([track1, track2, track3]);
214
+ ```
215
+
216
+ ##### skip()
217
+ Skip current track.
218
+
219
+ ```typescript
220
+ const nextTrack = queue.skip();
221
+ ```
222
+
223
+ ##### clear()
224
+ Clear entire queue.
225
+
226
+ ```typescript
227
+ queue.clear();
228
+ ```
229
+
230
+ ##### shuffle()
231
+ Shuffle the queue.
232
+
233
+ ```typescript
234
+ queue.shuffle();
235
+ ```
236
+
237
+ ##### getTracks()
238
+ Get all tracks in queue.
239
+
240
+ ```typescript
241
+ const tracks = queue.getTracks();
242
+ ```
243
+
244
+ ##### size()
245
+ Get queue size.
246
+
247
+ ```typescript
248
+ const size = queue.size();
249
+ ```
250
+
251
+ ##### setOptions(options)
252
+ Set queue options.
253
+
254
+ ```typescript
255
+ queue.setOptions({
256
+ loop: true,
257
+ loopQueue: false,
258
+ shuffle: false
259
+ });
260
+ ```
261
+
262
+ ## Events
263
+
264
+ The MusicPlayer emits various events you can listen to:
265
+
266
+ ```typescript
267
+ // Track started playing
268
+ player.on('trackStart', (track) => {
269
+ console.log(`Now playing: ${track.title}`);
270
+ });
271
+
272
+ // Track ended
273
+ player.on('trackEnd', (track) => {
274
+ console.log(`Finished: ${track.title}`);
275
+ });
276
+
277
+ // Queue ended (no more tracks)
278
+ player.on('queueEnd', () => {
279
+ console.log('Queue is empty');
280
+ });
281
+
282
+ // Error occurred
283
+ player.on('error', (error, track) => {
284
+ console.error('Error:', error.message);
285
+ });
286
+
287
+ // Volume changed
288
+ player.on('volumeChange', (oldVolume, newVolume) => {
289
+ console.log(`Volume: ${oldVolume} → ${newVolume}`);
290
+ });
291
+ ```
292
+
293
+ ## Examples
294
+
295
+ ### Play YouTube Video
296
+
297
+ ```javascript
298
+ await player.play(
299
+ 'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
300
+ message.author,
301
+ voiceChannel
302
+ );
303
+ ```
304
+
305
+ ### Play Spotify Playlist
306
+
307
+ ```javascript
308
+ await player.play(
309
+ 'https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M',
310
+ message.author,
311
+ voiceChannel
312
+ );
313
+ ```
314
+
315
+ ### Search and Play
316
+
317
+ ```javascript
318
+ await player.play(
319
+ 'lofi hip hop radio',
320
+ message.author,
321
+ voiceChannel
322
+ );
323
+ ```
324
+
325
+ ### Queue Management
326
+
327
+ ```javascript
328
+ // Get queue
329
+ const queue = player.getQueue();
330
+
331
+ // Show queue
332
+ const tracks = queue.getTracks();
333
+ tracks.forEach((track, i) => {
334
+ console.log(`${i + 1}. ${track.title} - ${track.author}`);
335
+ });
336
+
337
+ // Shuffle queue
338
+ queue.shuffle();
339
+
340
+ // Enable loop
341
+ queue.setOptions({ loop: true });
342
+
343
+ // Clear queue
344
+ queue.clear();
345
+ ```
346
+
347
+ ### Full Bot Example
348
+
349
+ See [examples/basic-bot.js](examples/basic-bot.js) for a complete working example.
350
+
351
+ ## Platform Support
352
+
353
+ ### YouTube
354
+ - ✅ Direct video links
355
+ - ✅ Playlist links
356
+ - ✅ Search queries
357
+ - ✅ Live streams
358
+
359
+ ### Spotify
360
+ - ✅ Track links
361
+ - ✅ Album links
362
+ - ✅ Playlist links
363
+ - ⚠️ Searches YouTube to find equivalent tracks (Spotify doesn't provide audio streams)
364
+
365
+ ### SoundCloud
366
+ - ✅ Track links
367
+ - ✅ Playlist links
368
+ - ✅ Search queries
369
+
370
+ ## TypeScript Support
371
+
372
+ This package is written in TypeScript and includes type definitions.
373
+
374
+ ```typescript
375
+ import { MusicPlayer, Track, PlayerOptions, Queue } from 'disvoice';
376
+
377
+ const player: MusicPlayer = new MusicPlayer({
378
+ volume: 50
379
+ });
380
+ ```
381
+
382
+ ## Troubleshooting
383
+
384
+ ### Bot doesn't join voice channel
385
+ Make sure your bot has the necessary permissions:
386
+ - `CONNECT` - to join voice channels
387
+ - `SPEAK` - to play audio
388
+
389
+ ### No audio playing
390
+ 1. Install required voice dependencies:
391
+ ```bash
392
+ npm install sodium-native @discordjs/opus ffmpeg-static
393
+ ```
394
+
395
+ 2. Make sure FFmpeg is installed on your system
396
+
397
+ ### Spotify tracks not playing
398
+ Spotify links are automatically converted to YouTube searches. If a track doesn't play, it might not be available on YouTube.
399
+
400
+ ## License
401
+
402
+ MIT
403
+
404
+ ## Contributing
405
+
406
+ Contributions are welcome! Please feel free to submit a Pull Request.
407
+
408
+ ## Support
409
+
410
+ For issues and questions, please open an issue on GitHub.
@@ -0,0 +1,81 @@
1
+ import { VoiceConnection } from '@discordjs/voice';
2
+ import { VoiceBasedChannel, User } from 'discord.js';
3
+ import { EventEmitter } from 'events';
4
+ import { Queue } from './Queue';
5
+ import { Track, PlayerOptions, SearchResult } from './types';
6
+ export declare class MusicPlayer extends EventEmitter {
7
+ private connection;
8
+ private player;
9
+ private queue;
10
+ private options;
11
+ private sources;
12
+ private currentVolume;
13
+ private leaveTimeout;
14
+ private isPlaying;
15
+ constructor(options?: PlayerOptions);
16
+ /**
17
+ * Connect to a voice channel
18
+ */
19
+ connect(channel: VoiceBasedChannel): VoiceConnection;
20
+ /**
21
+ * Play a track or search query
22
+ */
23
+ play(query: string, requester: User, channel?: VoiceBasedChannel): Promise<SearchResult>;
24
+ /**
25
+ * Play the next track in queue
26
+ */
27
+ private playNext;
28
+ /**
29
+ * Skip the current track
30
+ */
31
+ skip(): Track | null;
32
+ /**
33
+ * Pause playback
34
+ */
35
+ pause(): boolean;
36
+ /**
37
+ * Resume playback
38
+ */
39
+ resume(): boolean;
40
+ /**
41
+ * Stop playback and clear queue
42
+ */
43
+ stop(): void;
44
+ /**
45
+ * Set volume (0-100)
46
+ */
47
+ setVolume(volume: number): void;
48
+ /**
49
+ * Get current volume
50
+ */
51
+ getVolume(): number;
52
+ /**
53
+ * Get the queue
54
+ */
55
+ getQueue(): Queue;
56
+ /**
57
+ * Disconnect from voice channel
58
+ */
59
+ disconnect(): void;
60
+ /**
61
+ * Schedule automatic leave
62
+ */
63
+ private scheduleLeave;
64
+ /**
65
+ * Setup player event handlers
66
+ */
67
+ private setupPlayerEvents;
68
+ /**
69
+ * Get current track
70
+ */
71
+ getCurrentTrack(): Track | null;
72
+ /**
73
+ * Check if player is connected
74
+ */
75
+ isConnected(): boolean;
76
+ /**
77
+ * Check if currently playing
78
+ */
79
+ isCurrentlyPlaying(): boolean;
80
+ }
81
+ //# sourceMappingURL=MusicPlayer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MusicPlayer.d.ts","sourceRoot":"","sources":["../src/MusicPlayer.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,eAAe,EAKhB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,KAAK,EAAE,aAAa,EAAgB,YAAY,EAAc,MAAM,SAAS,CAAC;AAMvF,qBAAa,WAAY,SAAQ,YAAY;IAC3C,OAAO,CAAC,UAAU,CAAgC;IAClD,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,aAAa,CAAe;IACpC,OAAO,CAAC,YAAY,CAA+B;IACnD,OAAO,CAAC,SAAS,CAAkB;gBAEvB,OAAO,GAAE,aAAkB;IAyBvC;;OAEG;IACH,OAAO,CAAC,OAAO,EAAE,iBAAiB,GAAG,eAAe;IA4BpD;;OAEG;IACG,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,CAAC;IAsC9F;;OAEG;YACW,QAAQ;IAwCtB;;OAEG;IACH,IAAI,IAAI,KAAK,GAAG,IAAI;IAMpB;;OAEG;IACH,KAAK,IAAI,OAAO;IAIhB;;OAEG;IACH,MAAM,IAAI,OAAO;IAIjB;;OAEG;IACH,IAAI,IAAI,IAAI;IAMZ;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAe/B;;OAEG;IACH,SAAS,IAAI,MAAM;IAInB;;OAEG;IACH,QAAQ,IAAI,KAAK;IAIjB;;OAEG;IACH,UAAU,IAAI,IAAI;IAWlB;;OAEG;IACH,OAAO,CAAC,aAAa;IAYrB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAgBzB;;OAEG;IACH,eAAe,IAAI,KAAK,GAAG,IAAI;IAI/B;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;OAEG;IACH,kBAAkB,IAAI,OAAO;CAG9B"}