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 {User} user The user that has started/stopped speaking
* @param {boolean} speaking Whether or not the user is 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); guild._memberSpeakUpdate(user_id, speaking);
} }

View File

@@ -11,10 +11,18 @@ class PacketHandler extends EventEmitter {
this.streams = new Map(); this.streams = new Map();
} }
makeStream(user) { _stoppedSpeaking(userID) {
if (this.streams.has(user)) return this.streams.get(user); 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(); const stream = new Readable();
this.streams.set(user, stream); stream.on('end', () => this.streams.delete(user));
this.streams.set(user, { stream, end });
return stream; return stream;
} }
@@ -49,8 +57,9 @@ class PacketHandler extends EventEmitter {
const ssrc = buffer.readUInt32BE(8); const ssrc = buffer.readUInt32BE(8);
const user = this.userFromSSRC(ssrc); const user = this.userFromSSRC(ssrc);
if (!user) return; if (!user) return;
const stream = this.streams.get(user.id); let stream = this.streams.get(user.id);
if (!stream) return; if (!stream) return;
stream = stream.stream;
const opusPacket = this.parseBuffer(buffer); const opusPacket = this.parseBuffer(buffer);
if (opusPacket instanceof Error) { if (opusPacket instanceof Error) {
this.emit('error', opusPacket); 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 * @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 * the packets for you. You can set this to 'pcm' so that the stream's output will be 16-bit little-endian stereo
* audio * 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. * @param {ReceiveStreamOptions} options Options.
* @returns {ReadableStream} * @returns {ReadableStream}
*/ */
createStream(user, { mode = 'opus' } = {}) { createStream(user, { mode = 'opus', end = 'silence' } = {}) {
user = this.connection.client.users.resolve(user); user = this.connection.client.users.resolve(user);
if (!user) throw new Error('VOICE_USER_MISSING'); 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') { if (mode === 'pcm') {
const decoder = new prism.opus.Decoder({ channels: 2, rate: 48000, frameSize: 960 }); const decoder = new prism.opus.Decoder({ channels: 2, rate: 48000, frameSize: 960 });
stream.pipe(decoder); stream.pipe(decoder);