Using TCP only, because TeaSpeak does not really support UDP yet (missing packet resend for SCTP)

canary
WolverinDEV 2020-04-19 23:21:37 +02:00
parent 37bd67af85
commit 0abd6c3178
1 changed files with 31 additions and 32 deletions

View File

@ -385,8 +385,9 @@ export class VoiceConnection extends AbstractVoiceConnection {
let config: RTCConfiguration = {};
config.iceServers = [];
config.iceServers.push({ urls: 'stun:stun.l.google.com:19302' });
//config.iceServers.push({ urls: "stun:stun.teaspeak.de:3478" });
this.rtcPeerConnection = new RTCPeerConnection(config);
const dataChannelConfig = { ordered: true, maxRetransmits: 0 };
const dataChannelConfig = { ordered: false, maxRetransmits: 0 };
this.dataChannel = this.rtcPeerConnection.createDataChannel('main', dataChannelConfig);
this.dataChannel.onmessage = this.on_data_channel_message.bind(this);
@ -430,8 +431,26 @@ export class VoiceConnection extends AbstractVoiceConnection {
this.connection.client.update_voice_status(undefined);
}
private registerRemoteICECandidate(candidate: RTCIceCandidate) {
if(candidate.candidate === "") {
console.log("Adding end candidate");
this.rtcPeerConnection.addIceCandidate(null).catch(error => {
log.info(LogCategory.VOICE, tr("Failed to add remote cached ice candidate finish: %o"), error);
});
return;
}
const pcandidate = new RTCIceCandidate(candidate);
if(pcandidate.protocol !== "tcp") return; /* UDP does not work currently */
log.info(LogCategory.VOICE, tr("Add remote ice! (%o)"), pcandidate);
this.rtcPeerConnection.addIceCandidate(pcandidate).catch(error => {
log.info(LogCategory.VOICE, tr("Failed to add remote cached ice candidate %o: %o"), candidate, error);
});
}
private _ice_use_cache: boolean = true;
private _ice_cache: any[] = [];
private _ice_cache: RTCIceCandidate[] = [];
handleControlPacket(json) {
if(json["request"] === "answer") {
const session_description = new RTCSessionDescription(json["msg"]);
@ -439,41 +458,20 @@ export class VoiceConnection extends AbstractVoiceConnection {
this.rtcPeerConnection.setRemoteDescription(session_description).then(() => {
log.info(LogCategory.VOICE, tr("Answer applied successfully. Applying ICE candidates (%d)."), this._ice_cache.length);
this._ice_use_cache = false;
for(let msg of this._ice_cache) {
this.rtcPeerConnection.addIceCandidate(new RTCIceCandidate(msg)).catch(error => {
log.info(LogCategory.VOICE, tr("Failed to add remote cached ice candidate %s: %o"), msg, error);
});
}
console.log("Applying finish notification");
this.rtcPeerConnection.addIceCandidate(new RTCIceCandidate({ candidate: "", sdpMLineIndex: 0, sdpMid: "0" })).catch(error => {
log.info(LogCategory.VOICE, tr("Failed to add signal a ICE candidate finish: %o"), error);
});
this.rtcPeerConnection.addIceCandidate(new RTCIceCandidate({ candidate: "", sdpMLineIndex: 1, sdpMid: "1" })).catch(error => {
log.info(LogCategory.VOICE, tr("Failed to add signal a ICE candidate finish: %o"), error);
});
for(let candidate of this._ice_cache)
this.registerRemoteICECandidate(candidate);
this._ice_cache = [];
}).catch(error => {
log.info(LogCategory.VOICE, tr("Failed to apply remote description: %o"), error); //FIXME error handling!
});
} else if(json["request"] === "ice") {
} else if(json["request"] === "ice" || json["request"] === "ice_finish") {
const candidate = new RTCIceCandidate(json["msg"]);
if(!this._ice_use_cache) {
log.info(LogCategory.VOICE, tr("Add remote ice! (%o)"), json["msg"]);
this.rtcPeerConnection.addIceCandidate(new RTCIceCandidate(json["msg"])).catch(error => {
log.info(LogCategory.VOICE, tr("Failed to add remote ice candidate %s: %o"), json["msg"], error);
});
this.registerRemoteICECandidate(candidate);
} else {
log.info(LogCategory.VOICE, tr("Cache remote ice! (%o)"), json["msg"]);
this._ice_cache.push(json["msg"]);
}
} else if(json["request"] === "ice_finish") {
if(!this._ice_use_cache) {
log.info(LogCategory.VOICE, tr("Remote signalled ice candidate finished: %o"), json["msg"]);
this.rtcPeerConnection.addIceCandidate(new RTCIceCandidate(json["msg"])).catch(error => {
log.info(LogCategory.VOICE, tr("Failed to add signal a ICE candidate finish: %o"), error);
});
} else {
log.info(LogCategory.VOICE, tr("Cache remote ice finish."));
this._ice_cache.push(json["msg"]);
this._ice_cache.push(candidate);
}
} else if(json["request"] == "status") {
if(json["state"] == "failed") {
@ -495,17 +493,18 @@ export class VoiceConnection extends AbstractVoiceConnection {
private on_local_ice_candidate(event: RTCPeerConnectionIceEvent) {
if (event) {
if(event.candidate && event.candidate.protocol !== "udp")
if(event.candidate && event.candidate.protocol !== "tcp")
return;
log.info(LogCategory.VOICE, tr("Gathered local ice candidate %o."), event.candidate);
if(event.candidate) {
log.info(LogCategory.VOICE, tr("Gathered local ice candidate for stream %d: %s"), event.candidate.sdpMLineIndex, event.candidate.candidate);
this.connection.sendData(JSON.stringify({
type: 'WebRTC',
request: "ice",
msg: event.candidate,
}));
} else {
log.info(LogCategory.VOICE, tr("Local ICE candidate gathering finish."));
this.connection.sendData(JSON.stringify({
type: 'WebRTC',
request: "ice_finish"