Start/Stop speaking events on UDP packets (#3578)

* Start/Stop speaking using incomming UDP packets

* Fix ESLint errors

* Updates for styling consistency

Co-Authored-By: Gryffon Bellish <owenbellish@gmail.com>

* Minor improvements

* Acutally use previousTimeout

* Use BaseClient setTimeout and refresh()

* Update README to match node version for refresh()

* Update comment to match startSpeaking

* Correctly report Priority bit

* Fix ESlint errors
This commit is contained in:
sillyfrog
2019-12-06 21:59:57 +10:00
committed by Amish Shah
parent bb8333a4f9
commit 4585d965b4
4 changed files with 36 additions and 12 deletions

View File

@@ -3,6 +3,10 @@
const secretbox = require('../util/Secretbox');
const EventEmitter = require('events');
// The delay between packets when a user is considered to have stopped speaking
// https://github.com/discordjs/discord.js/issues/3524#issuecomment-540373200
const DISCORD_SPEAKING_DELAY = 250;
class Readable extends require('stream').Readable { _read() {} } // eslint-disable-line no-empty-function
class PacketHandler extends EventEmitter {
@@ -11,6 +15,7 @@ class PacketHandler extends EventEmitter {
this.nonce = Buffer.alloc(24);
this.receiver = receiver;
this.streams = new Map();
this.speakingTimeouts = new Map();
}
get connection() {
@@ -72,13 +77,29 @@ class PacketHandler extends EventEmitter {
return packet;
}
userFromSSRC(ssrc) { return this.connection.client.users.get(this.connection.ssrcMap.get(ssrc)); }
push(buffer) {
const ssrc = buffer.readUInt32BE(8);
const user = this.userFromSSRC(ssrc);
if (!user) return;
let stream = this.streams.get(user.id);
const userStat = this.connection.ssrcMap.get(ssrc);
if (!userStat) return;
let speakingTimeout = this.speakingTimeouts.get(ssrc);
if (typeof speakingTimeout === 'undefined') {
this.connection.onSpeaking({ user_id: userStat.userID, ssrc: ssrc, speaking: userStat.speaking });
speakingTimeout = this.receiver.connection.client.setTimeout(() => {
try {
this.connection.onSpeaking({ user_id: userStat.userID, ssrc: ssrc, speaking: 0 });
this.receiver.connection.client.clearTimeout(speakingTimeout);
this.speakingTimeouts.delete(ssrc);
} catch (ex) {
// Connection already closed, ignore
}
}, DISCORD_SPEAKING_DELAY);
this.speakingTimeouts.set(ssrc, speakingTimeout);
} else {
speakingTimeout.refresh();
}
let stream = this.streams.get(userStat.userID);
if (!stream) return;
stream = stream.stream;
const opusPacket = this.parseBuffer(buffer);