Added voice disconnect

This commit is contained in:
Amish Shah
2016-10-25 14:18:20 +01:00
parent b0921ae0ef
commit 91ba59c43d
8 changed files with 56 additions and 11 deletions

View File

@@ -243,6 +243,7 @@ class ClientVoiceManager {
this.connections.set(channel.guild.id, voiceConnection);
voiceConnection.once('ready', () => resolve(voiceConnection));
voiceConnection.once('error', reject);
voiceConnection.once('disconnected', () => this.connections.delete(channel.guild.id));
});
});
}

View File

@@ -42,7 +42,6 @@ class VoiceConnection extends EventEmitter {
this.player.on('error', e => {
this.emit('warn', e);
console.log('so yeah uh' + e);
this.player.cleanup();
});
@@ -63,9 +62,26 @@ class VoiceConnection extends EventEmitter {
speaking: true,
delay: 0,
},
})
.catch(e => {
this.emit('debug', e);
});
}
disconnect() {
this.emit('closing');
this.voiceManager.client.ws.send({
op: Constants.OPCodes.VOICE_STATE_UPDATE,
d: {
guild_id: this.channel.guild.id,
channel_id: null,
self_mute: false,
self_deaf: false,
},
});
this.emit('disconnected');
}
connect() {
if (this.sockets.ws) {
throw new Error('There is already an existing WebSocket connection!');

View File

@@ -49,6 +49,17 @@ class VoiceConnectionUDPClient extends EventEmitter {
* @type {?string}
*/
this.localPort = null;
this.voiceConnection.on('closing', this.shutdown.bind(this));
}
shutdown() {
if (this.socket) {
try {
this.socket.close();
} catch (e) {
return;
}
this.socket = null;
}
}
/**
* The port of the discord voice server
@@ -57,7 +68,6 @@ class VoiceConnectionUDPClient extends EventEmitter {
get discordPort() {
return this.voiceConnection.authentication.port;
}
/**
* Tries to resolve the voice server endpoint to an address
* @returns {Promise<string>}

View File

@@ -22,6 +22,15 @@ class VoiceWebSocket extends EventEmitter {
*/
this.attempts = 0;
this.connect();
this.dead = false;
this.voiceConnection.on('closing', this.shutdown.bind(this));
}
shutdown() {
this.dead = true;
this.reset();
}
/**
@@ -50,6 +59,9 @@ class VoiceWebSocket extends EventEmitter {
* Starts connecting to the Voice WebSocket Server.
*/
connect() {
if (this.dead) {
return;
}
if (this.ws) {
this.reset();
}
@@ -76,7 +88,7 @@ class VoiceWebSocket extends EventEmitter {
*/
send(data) {
return new Promise((resolve, reject) => {
if (this.ws.readyState === WebSocket.OPEN) {
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
this.ws.send(data, null, error => {
if (error) {
reject(error);
@@ -85,7 +97,7 @@ class VoiceWebSocket extends EventEmitter {
}
});
} else {
reject(new Error('websocket not open'));
reject(new Error('websocket not open for ' + data));
}
});
}
@@ -140,7 +152,7 @@ class VoiceWebSocket extends EventEmitter {
*/
onClose(event) {
// #todo see if the connection is open before reconnecting
this.client.setTimeout(this.connect.bind(this), this.attempts * 1000);
if (!this.dead) this.client.setTimeout(this.connect.bind(this), this.attempts * 1000);
}
/**

View File

@@ -134,7 +134,10 @@ class StreamDispatcher extends EventEmitter {
_sendBuffer(buffer, sequence, timestamp) {
let repeats = this.passes;
const packet = this._createPacket(sequence, timestamp, this.player.opusEncoder.encode(buffer));
while (repeats--) this.player.voiceConnection.sockets.udp.send(packet).catch(e => console.log('so uhhh', e));
while (repeats--) {
this.player.voiceConnection.sockets.udp.send(packet)
.catch(e => this.emit('debug', `failed to send a packet ${e}`));
}
}
_createPacket(sequence, timestamp, buffer) {

View File

@@ -20,12 +20,13 @@ class AudioPlayer extends EventEmitter {
timestamp: 0,
pausedTime: 0,
};
this.voiceConnection.on('closing', () => this.cleanup(null, 'voice connection is closing'));
}
playUnknownStream(stream, { seek = 0, volume = 1, passes = 1 } = {}) {
const options = { seek, volume, passes };
stream.on('end', () => {
console.log(Date.now(), 'real input stream ended');
this.emit('debug', 'input stream to converter has ended');
});
stream.on('error', e => this.emit('error', e));
const conversionProcess = this.audioToPCM.createConvertStream(options.seek);
@@ -36,7 +37,7 @@ class AudioPlayer extends EventEmitter {
cleanup(checkStream, reason) {
// cleanup is a lot less aggressive than v9 because it doesn't try to kill every single stream it is aware of
console.log(Date.now(), 'clean up triggered due to', reason);
this.emit('debug', `clean up triggered due to ${reason}`);
const filter = checkStream && this.currentDispatcher && this.currentDispatcher.stream === checkStream;
if (this.currentConverter && (checkStream ? filter : true)) {
this.currentConverter.destroy();
@@ -46,9 +47,7 @@ class AudioPlayer extends EventEmitter {
playPCMStream(stream, converter, { seek = 0, volume = 1, passes = 1 } = {}) {
const options = { seek, volume, passes };
stream.on('end', () => {
console.log(Date.now(), 'pcm input stream ended');
});
stream.on('end', () => this.emit('debug', 'pcm input stream ended'));
this.cleanup(null, 'outstanding play stream');
this.currentConverter = converter;
if (this.currentDispatcher) {

View File

@@ -101,6 +101,9 @@ class VoiceConnectionPlayer extends EventEmitter {
speaking: true,
delay: 0,
},
})
.catch(e => {
this.emit('debug', e);
});
}

View File

@@ -160,6 +160,7 @@ let disp, con;
client.on('message', msg => {
if (msg.content.startsWith('/play')) {
console.log('I am now going to play', msg.content);
const chan = msg.content.split(' ').slice(1).join(' ');
con.playStream(ytdl(chan, {filter : 'audioonly'}), { passes : 4 });
}