VoiceBroadcast.js (3350B)
1 'use strict'; 2 3 const EventEmitter = require('events'); 4 const BroadcastAudioPlayer = require('./player/BroadcastAudioPlayer'); 5 const PlayInterface = require('./util/PlayInterface'); 6 const { Events } = require('../../util/Constants'); 7 8 /** 9 * A voice broadcast can be played across multiple voice connections for improved shared-stream efficiency. 10 * 11 * Example usage: 12 * ```js 13 * const broadcast = client.voice.createBroadcast(); 14 * broadcast.play('./music.mp3'); 15 * // Play "music.mp3" in all voice connections that the client is in 16 * for (const connection of client.voice.connections.values()) { 17 * connection.play(broadcast); 18 * } 19 * ``` 20 * @implements {PlayInterface} 21 * @extends {EventEmitter} 22 */ 23 class VoiceBroadcast extends EventEmitter { 24 constructor(client) { 25 super(); 26 /** 27 * The client that created the broadcast 28 * @type {Client} 29 */ 30 this.client = client; 31 /** 32 * The subscribed StreamDispatchers of this broadcast 33 * @type {StreamDispatcher[]} 34 */ 35 this.subscribers = []; 36 this.player = new BroadcastAudioPlayer(this); 37 } 38 39 /** 40 * The current master dispatcher, if any. This dispatcher controls all that is played by subscribed dispatchers. 41 * @type {?BroadcastDispatcher} 42 * @readonly 43 */ 44 get dispatcher() { 45 return this.player.dispatcher; 46 } 47 48 /** 49 * Play an audio resource. 50 * @param {ReadableStream|string} resource The resource to play. 51 * @param {StreamOptions} [options] The options to play. 52 * @example 53 * // Play a local audio file 54 * broadcast.play('/home/hydrabolt/audio.mp3', { volume: 0.5 }); 55 * @example 56 * // Play a ReadableStream 57 * broadcast.play(ytdl('https://www.youtube.com/watch?v=ZlAU_w7-Xp8', { filter: 'audioonly' })); 58 * @example 59 * // Using different protocols: https://ffmpeg.org/ffmpeg-protocols.html 60 * broadcast.play('http://www.sample-videos.com/audio/mp3/wave.mp3'); 61 * @returns {BroadcastDispatcher} 62 */ 63 play() { 64 return null; 65 } 66 67 /** 68 * Ends the broadcast, unsubscribing all subscribed channels and deleting the broadcast 69 */ 70 end() { 71 for (const dispatcher of this.subscribers) this.delete(dispatcher); 72 const index = this.client.voice.broadcasts.indexOf(this); 73 if (index !== -1) this.client.voice.broadcasts.splice(index, 1); 74 } 75 76 add(dispatcher) { 77 const index = this.subscribers.indexOf(dispatcher); 78 if (index === -1) { 79 this.subscribers.push(dispatcher); 80 /** 81 * Emitted whenever a stream dispatcher subscribes to the broadcast. 82 * @event VoiceBroadcast#subscribe 83 * @param {StreamDispatcher} subscriber The subscribed dispatcher 84 */ 85 this.emit(Events.VOICE_BROADCAST_SUBSCRIBE, dispatcher); 86 return true; 87 } else { 88 return false; 89 } 90 } 91 92 delete(dispatcher) { 93 const index = this.subscribers.indexOf(dispatcher); 94 if (index !== -1) { 95 this.subscribers.splice(index, 1); 96 dispatcher.destroy(); 97 /** 98 * Emitted whenever a stream dispatcher unsubscribes to the broadcast. 99 * @event VoiceBroadcast#unsubscribe 100 * @param {StreamDispatcher} dispatcher The unsubscribed dispatcher 101 */ 102 this.emit(Events.VOICE_BROADCAST_UNSUBSCRIBE, dispatcher); 103 return true; 104 } 105 return false; 106 } 107 } 108 109 PlayInterface.applyToClass(VoiceBroadcast); 110 111 module.exports = VoiceBroadcast;