diff --git a/src/client/voice/VoiceConnection.js b/src/client/voice/VoiceConnection.js index 1f1c7a18a..064d1c8f9 100644 --- a/src/client/voice/VoiceConnection.js +++ b/src/client/voice/VoiceConnection.js @@ -3,7 +3,7 @@ const VoiceUDP = require('./VoiceUDPClient'); const Util = require('../../util/Util'); const { OPCodes, VoiceOPCodes, VoiceStatus } = require('../../util/Constants'); const AudioPlayer = require('./player/AudioPlayer'); -const VoiceReceiver = require('./receiver/VoiceReceiver'); +const VoiceReceiver = require('./receiver/Receiver'); const EventEmitter = require('events'); const { Error } = require('../../errors'); diff --git a/src/client/voice/receiver/PacketHandler.js b/src/client/voice/receiver/PacketHandler.js index b6eb09378..27e094557 100644 --- a/src/client/voice/receiver/PacketHandler.js +++ b/src/client/voice/receiver/PacketHandler.js @@ -1,8 +1,18 @@ const nonce = Buffer.alloc(24); +const Readable = require('./VoiceReadable'); +const secretbox = require('../util/Secretbox'); class PacketHandler { constructor(receiver) { this.receiver = receiver; + this.streams = new Map(); + } + + makeStream(user) { + if (this.streams.has(user)) return this.streams.get(user); + const stream = new Readable(); + this.streams.set(user, stream); + return stream; } parseBuffer(buffer) { @@ -36,8 +46,11 @@ class PacketHandler { const ssrc = buffer.readUInt32BE(8); const user = this.userFromSSRC(ssrc); if (!user) return; + const stream = this.streams.get(user.id); + if (!stream) return; const opusPacket = this.parseBuffer(buffer); if (opusPacket instanceof Error) return; + stream.push(opusPacket); } } diff --git a/src/client/voice/receiver/Receiver.js b/src/client/voice/receiver/Receiver.js index fa386c06a..cfa217be4 100644 --- a/src/client/voice/receiver/Receiver.js +++ b/src/client/voice/receiver/Receiver.js @@ -1,15 +1,30 @@ const EventEmitter = require('events'); +const prism = require('prism-media'); +const PacketHandler = require('./PacketHandler'); class VoiceReceiver extends EventEmitter { constructor(connection) { super(); this.connection = connection; - this.packets = new PacketHandler(this); + this.packets = new PacketHandler(this); this.connection.sockets.udp.socket.on('message', buffer => this.packets.push(buffer)); } createStream(user, pcm=false) { + user = this.connection.client.users.resolve(user); + if (!user) throw new Error('VOICE_USER_MISSING'); + console.log('making stream for', user.tag); + const stream = this.packets.makeStream(user.id); + if (pcm) { + const decoder = new prism.opus.Decoder({ channels: 2, rate: 48000, frameSize: 1920 }); + stream.pipe(decoder); + return decoder; + } + return stream; + } + stoppedSpeaking() { + console.log('remember to remove this :)'); } } diff --git a/test/voice.js b/test/voice.js index 29e1eacc9..2f57ee8dc 100644 --- a/test/voice.js +++ b/test/voice.js @@ -1,11 +1,6 @@ /* eslint no-console: 0 */ 'use strict'; -var profiler = require('gc-profiler'); -profiler.on('gc', function (info) { - console.log(info); -}); - const Discord = require('../'); const ytdl = require('ytdl-core'); const prism = require('prism-media'); @@ -32,22 +27,6 @@ async function wait(time = 1000) { var count = 0; -client.on('ready', async () => { - for (const guild of client.guilds.values()) { - const channels = guild.channels.filter(c => c.type === 'voice' && c.joinable && c.members.size === 0); - const channel = channels.first(); - if (channel) { - channel.join().then(conn => { - conn.playOpusStream(fs.createReadStream('C:/users/amish/downloads/z.ogg').pipe(new prism.OggOpusDemuxer())); - }); - count++; - console.log(`Playing in ${channel.name} in ${channel.guild.name} at count ${count} ${process.memoryUsage().rss / (1024 * 1024)}`); - await wait(); - } - } - console.log('done!'); -}); - process.on('unhandledRejection', console.log); client.on('message', m => { @@ -57,6 +36,8 @@ client.on('message', m => { const channel = m.guild.channels.get(m.content.split(' ')[1]) || m.member.voiceChannel; if (channel && channel.type === 'voice') { channel.join().then(conn => { + const receiver = conn.createReceiver(); + receiver.createStream(m.author, true).on('data', b => console.log(b.toString())); conn.player.on('error', (...e) => console.log('player', ...e)); if (!connections.has(m.guild.id)) connections.set(m.guild.id, { conn, queue: [] }); m.reply('ok!');