Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ discord.js is a powerful [Node.js](https://nodejs.org) module that allows you to
- 100% coverage of the Discord API

## Installation
**Node.js 10.0.0 or newer is required.**
**Node.js 10.2.0 or newer is required.**
Copy link
Contributor

@PyroTechniac PyroTechniac Nov 15, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't change until an official announcement is made about a version bump

Unless @iCrawl is okay with this I should mention

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the feedback! :)

I'll wait for confirmation from @iCrawl , however this change does rely on v10.2 because of the use of refresh(). Let me know the best way to approach things if we can't bump the version (maybe even a note to say this feature requires v10.2?).

Cheers.

Ignore any warnings about unmet peer dependencies, as they're all optional.

Without voice support: `npm install discordjs/discord.js`
Expand Down
11 changes: 7 additions & 4 deletions src/client/voice/VoiceConnection.js
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ class VoiceConnection extends EventEmitter {
udp.on('error', err => this.emit('error', err));
ws.on('ready', this.onReady.bind(this));
ws.on('sessionDescription', this.onSessionDescription.bind(this));
ws.on('speaking', this.onSpeaking.bind(this));
ws.on('startSpeaking', this.onStartSpeaking.bind(this));

this.sockets.ws.connect();
}
Expand Down Expand Up @@ -465,16 +465,19 @@ class VoiceConnection extends EventEmitter {
});
}

onStartSpeaking({ user_id, ssrc, speaking }) {
this.ssrcMap.set(+ssrc, { userID: user_id, speaking: speaking });
}

/**
* Invoked when a speaking event is received.
* @param {Object} data The received data
* @private
*/
onSpeaking({ user_id, ssrc, speaking }) {
onSpeaking({ user_id, speaking }) {
speaking = new Speaking(speaking).freeze();
const guild = this.channel.guild;
const user = this.client.users.get(user_id);
this.ssrcMap.set(+ssrc, user_id);
const old = this._speaking.get(user_id);
this._speaking.set(user_id, speaking);
/**
Expand Down Expand Up @@ -504,7 +507,7 @@ class VoiceConnection extends EventEmitter {
}
}

play() {} // eslint-disable-line no-empty-function
play() { } // eslint-disable-line no-empty-function
}

PlayInterface.applyToClass(VoiceConnection);
Expand Down
4 changes: 2 additions & 2 deletions src/client/voice/networking/VoiceWebSocket.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,9 +201,9 @@ class VoiceWebSocket extends EventEmitter {
/**
* Emitted whenever a speaking packet is received.
* @param {Object} data
* @event VoiceWebSocket#speaking
* @event VoiceWebSocket#startSpeaking
*/
this.emit('speaking', packet.d);
this.emit('startSpeaking', packet.d);
break;
default:
/**
Expand Down
31 changes: 26 additions & 5 deletions src/client/voice/receiver/PacketHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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() {
Expand Down Expand Up @@ -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);
Expand Down