voice: add end param to describe how a voice receive stream should end

This commit is contained in:
Amish Shah
2018-03-31 11:52:48 +01:00
parent 623d4c0076
commit a5e8f05d01
3 changed files with 25 additions and 7 deletions

View File

@@ -423,7 +423,14 @@ class VoiceConnection extends EventEmitter {
* @param {User} user The user that has started/stopped speaking
* @param {boolean} speaking Whether or not the user is speaking
*/
if (this.status === VoiceStatus.CONNECTED) this.emit('speaking', user, speaking);
if (this.status === VoiceStatus.CONNECTED) {
this.emit('speaking', user, speaking);
if (!speaking) {
for (const receiver of this.receivers) {
receiver.packets._stoppedSpeaking(user_id);
}
}
}
guild._memberSpeakUpdate(user_id, speaking);
}

View File

@@ -11,10 +11,18 @@ class PacketHandler extends EventEmitter {
this.streams = new Map();
}
makeStream(user) {
if (this.streams.has(user)) return this.streams.get(user);
_stoppedSpeaking(userID) {
if (this.streams.has(userID)) {
const { stream, end } = this.streams.get(userID);
if (end === 'silence') stream.push(null);
}
}
makeStream(user, end) {
if (this.streams.has(user)) return this.streams.get(user).stream;
const stream = new Readable();
this.streams.set(user, stream);
stream.on('end', () => this.streams.delete(user));
this.streams.set(user, { stream, end });
return stream;
}
@@ -49,8 +57,9 @@ class PacketHandler extends EventEmitter {
const ssrc = buffer.readUInt32BE(8);
const user = this.userFromSSRC(ssrc);
if (!user) return;
const stream = this.streams.get(user.id);
let stream = this.streams.get(user.id);
if (!stream) return;
stream = stream.stream;
const opusPacket = this.parseBuffer(buffer);
if (opusPacket instanceof Error) {
this.emit('error', opusPacket);

View File

@@ -30,6 +30,8 @@ class VoiceReceiver extends EventEmitter {
* @property {string} [mode='opus'] The mode for audio output. This defaults to opus, meaning discord.js won't decode
* the packets for you. You can set this to 'pcm' so that the stream's output will be 16-bit little-endian stereo
* audio
* @property {string} [end='silence'] When the stream should be destroyed. If `silence`, this will be when the user
* stops talking. Otherwise, if `manual`, this should be handled by you.
*/
/**
@@ -39,10 +41,10 @@ class VoiceReceiver extends EventEmitter {
* @param {ReceiveStreamOptions} options Options.
* @returns {ReadableStream}
*/
createStream(user, { mode = 'opus' } = {}) {
createStream(user, { mode = 'opus', end = 'silence' } = {}) {
user = this.connection.client.users.resolve(user);
if (!user) throw new Error('VOICE_USER_MISSING');
const stream = this.packets.makeStream(user.id);
const stream = this.packets.makeStream(user.id, end);
if (mode === 'pcm') {
const decoder = new prism.opus.Decoder({ channels: 2, rate: 48000, frameSize: 960 });
stream.pipe(decoder);