From 6058ea488890267403f22362b35955035e5cc588 Mon Sep 17 00:00:00 2001 From: Amish Shah Date: Fri, 19 Jan 2018 17:45:37 +0000 Subject: [PATCH] Start voice receive rewrite --- src/client/voice/receiver/PacketHandler.js | 44 ++++++++++++++++++++++ src/client/voice/receiver/Receiver.js | 16 ++++++++ src/client/voice/receiver/VoiceReceiver.js | 2 +- 3 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 src/client/voice/receiver/PacketHandler.js create mode 100644 src/client/voice/receiver/Receiver.js diff --git a/src/client/voice/receiver/PacketHandler.js b/src/client/voice/receiver/PacketHandler.js new file mode 100644 index 000000000..b6eb09378 --- /dev/null +++ b/src/client/voice/receiver/PacketHandler.js @@ -0,0 +1,44 @@ +const nonce = Buffer.alloc(24); + +class PacketHandler { + constructor(receiver) { + this.receiver = receiver; + } + + parseBuffer(buffer) { + // reuse nonce + buffer.copy(nonce, 0, 0, 12); + + let packet = secretbox.methods.open(buffer.slice(12), nonce, this.receiver.connection.authentication.secretKey); + if (!packet) return Error('Failed to decrypt voice packet'); + packet = Buffer.from(packet); + + // Strip RTP Header Extensions (one-byte only) + if (packet[0] === 0xBE && packet[1] === 0xDE && packet.length > 4) { + const headerExtensionLength = packet.readUInt16BE(2); + let offset = 4; + for (let i = 0; i < headerExtensionLength; i++) { + const byte = packet[offset]; + offset++; + if (byte === 0) continue; + offset += 1 + (0b1111 & (byte >> 4)); + } + while (packet[offset] === 0) offset++; + packet = packet.slice(offset); + } + + return packet; + } + + userFromSSRC(ssrc) { return this.receiver.connection.ssrcMap.get(ssrc); } + + push(buffer) { + const ssrc = buffer.readUInt32BE(8); + const user = this.userFromSSRC(ssrc); + if (!user) return; + const opusPacket = this.parseBuffer(buffer); + if (opusPacket instanceof Error) return; + } +} + +module.exports = PacketHandler; diff --git a/src/client/voice/receiver/Receiver.js b/src/client/voice/receiver/Receiver.js new file mode 100644 index 000000000..fa386c06a --- /dev/null +++ b/src/client/voice/receiver/Receiver.js @@ -0,0 +1,16 @@ +const EventEmitter = require('events'); + +class VoiceReceiver extends EventEmitter { + constructor(connection) { + super(); + this.connection = connection; + this.packets = new PacketHandler(this); + this.connection.sockets.udp.socket.on('message', buffer => this.packets.push(buffer)); + } + + createStream(user, pcm=false) { + + } +} + +module.exports = VoiceReceiver; diff --git a/src/client/voice/receiver/VoiceReceiver.js b/src/client/voice/receiver/VoiceReceiver.js index bc7a87061..07c4894bd 100644 --- a/src/client/voice/receiver/VoiceReceiver.js +++ b/src/client/voice/receiver/VoiceReceiver.js @@ -131,7 +131,7 @@ class VoiceReceiver extends EventEmitter { return stream; } - /** + /** * Creates a readable stream for a user that provides PCM data while the user is speaking. When the user * stops speaking, the stream is destroyed. The stream is 32-bit signed stereo PCM at 48KHz. * @param {UserResolvable} user The user to create the stream for