mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-18 04:23:31 +01:00
start work with broadcast streams
This commit is contained in:
85
src/client/voice/VoiceBroadcast.js
Normal file
85
src/client/voice/VoiceBroadcast.js
Normal file
@@ -0,0 +1,85 @@
|
||||
const EventEmitter = require('events').EventEmitter;
|
||||
const Prism = require('prism-media');
|
||||
|
||||
const ffmpegArguments = [
|
||||
'-analyzeduration', '0',
|
||||
'-loglevel', '0',
|
||||
'-f', 's16le',
|
||||
'-ar', '48000',
|
||||
'-ac', '2',
|
||||
];
|
||||
|
||||
class VoiceBroadcast extends EventEmitter {
|
||||
constructor(client) {
|
||||
super();
|
||||
this.client = client;
|
||||
this.dispatchers = [];
|
||||
this.prism = new Prism();
|
||||
this.currentTranscoder = null;
|
||||
}
|
||||
|
||||
get _playableStream() {
|
||||
if (!this.currentTranscoder) return null;
|
||||
return this.currentTranscoder.transcoder.output || this.currentTranscoder.options.stream;
|
||||
}
|
||||
|
||||
registerDispatcher(dispatcher) {
|
||||
if (!this.dispatchers.includes(dispatcher)) this.dispatchers.push(dispatcher);
|
||||
}
|
||||
|
||||
killCurrentTranscoder() {
|
||||
if (this.currentTranscoder) {
|
||||
if (this.currentTranscoder.transcoder) this.currentTranscoder.transcoder.kill();
|
||||
this.currentTranscoder = null;
|
||||
}
|
||||
}
|
||||
|
||||
playStream(stream, { seek = 0, volume = 1, passes = 1 } = {}) {
|
||||
const options = { seek, volume, passes };
|
||||
options.stream = stream;
|
||||
return this._playTranscodable(stream, options);
|
||||
}
|
||||
|
||||
playFile(file, { seek = 0, volume = 1, passes = 1 } = {}) {
|
||||
const options = { seek, volume, passes };
|
||||
return this._playTranscodable(file, options);
|
||||
}
|
||||
|
||||
_playTranscodable(media, options) {
|
||||
this.killCurrentTranscoder();
|
||||
const transcoder = this.prism.transcode({
|
||||
type: 'ffmpeg',
|
||||
media,
|
||||
ffmpegArguments: ffmpegArguments.concat(['-ss', String(options.seek)]),
|
||||
});
|
||||
transcoder.once('error', e => this.emit('error', e));
|
||||
transcoder.once('end', () => this.killCurrentTranscoder());
|
||||
this.currentTranscoder = {
|
||||
transcoder,
|
||||
options,
|
||||
};
|
||||
transcoder.output.once('readable', () => this._startPlaying());
|
||||
return this;
|
||||
}
|
||||
|
||||
playConvertedStream(stream, { seek = 0, volume = 1, passes = 1 } = {}) {
|
||||
this.killCurrentTranscoder();
|
||||
const options = { seek, volume, passes, stream };
|
||||
this.currentTranscoder = { options };
|
||||
stream.once('readable', () => this._startPlaying());
|
||||
return this;
|
||||
}
|
||||
|
||||
_startPlaying() {
|
||||
if (!this._playableStream) return;
|
||||
const stream = this._playableStream;
|
||||
const buffer = stream.read(1920 * 2);
|
||||
|
||||
for (const dispatcher of this.dispatchers) {
|
||||
setImmediate(() => dispatcher.process(buffer, true));
|
||||
}
|
||||
setTimeout(this._startPlaying.bind(this), 20);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = VoiceBroadcast;
|
||||
Reference in New Issue
Block a user