1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-11-26 17:03:12 +03:00

More VoIP connectivity fixes

* Don't ignore other candidates when we see a null one (continue
   rather than return)
 * await on addICECandidate()
 * Don't add ice candidates until we've set a remote description
 * More & better logging
This commit is contained in:
David Baker
2021-03-16 19:13:03 +00:00
parent 12050b14f0
commit 702e16e3df

View File

@@ -541,6 +541,7 @@ export class MatrixCall extends EventEmitter {
this.chooseOpponent(event); this.chooseOpponent(event);
try { try {
await this.peerConn.setRemoteDescription(invite.offer); await this.peerConn.setRemoteDescription(invite.offer);
await this.addBufferedIceCandidates();
} catch (e) { } catch (e) {
logger.debug("Failed to set remote description", e); logger.debug("Failed to set remote description", e);
this.terminate(CallParty.Local, CallErrorCode.SetRemoteDescription, false); this.terminate(CallParty.Local, CallErrorCode.SetRemoteDescription, false);
@@ -985,7 +986,7 @@ export class MatrixCall extends EventEmitter {
private gotLocalIceCandidate = (event: RTCPeerConnectionIceEvent) => { private gotLocalIceCandidate = (event: RTCPeerConnectionIceEvent) => {
if (event.candidate) { if (event.candidate) {
logger.debug( logger.debug(
"Got local ICE " + event.candidate.sdpMid + " candidate: " + "Call " + this.callId + " got local ICE " + event.candidate.sdpMid + " candidate: " +
event.candidate.candidate, event.candidate.candidate,
); );
@@ -1019,7 +1020,7 @@ export class MatrixCall extends EventEmitter {
} }
}; };
onRemoteIceCandidatesReceived(ev: MatrixEvent) { async onRemoteIceCandidatesReceived(ev: MatrixEvent) {
if (this.callHasEnded()) { if (this.callHasEnded()) {
//debuglog("Ignoring remote ICE candidate because call has ended"); //debuglog("Ignoring remote ICE candidate because call has ended");
return; return;
@@ -1051,7 +1052,7 @@ export class MatrixCall extends EventEmitter {
return; return;
} }
this.addIceCandidates(cands); await this.addIceCandidates(cands);
} }
/** /**
@@ -1059,7 +1060,10 @@ export class MatrixCall extends EventEmitter {
* @param {Object} msg * @param {Object} msg
*/ */
async onAnswerReceived(event: MatrixEvent) { async onAnswerReceived(event: MatrixEvent) {
logger.debug(`Got answer for call ID ${this.callId} from party ID ${event.getContent().party_id}`);
if (this.callHasEnded()) { if (this.callHasEnded()) {
logger.debug(`Ignoring answer because call ID ${this.callId} has ended`);
return; return;
} }
@@ -1072,6 +1076,7 @@ export class MatrixCall extends EventEmitter {
} }
this.chooseOpponent(event); this.chooseOpponent(event);
await this.addBufferedIceCandidates();
this.setState(CallState.Connecting); this.setState(CallState.Connecting);
@@ -1520,7 +1525,10 @@ export class MatrixCall extends EventEmitter {
} }
} }
async transfer(targetUserId: string, targetRoomId?: string) { /*
* Transfers this call to another user
*/
async transfer(targetUserId: string) {
// Fetch the target user's global profile info: their room avatar / displayname // Fetch the target user's global profile info: their room avatar / displayname
// could be different in whatever room we shae with them. // could be different in whatever room we shae with them.
const profileInfo = await this.client.getProfileInfo(targetUserId); const profileInfo = await this.client.getProfileInfo(targetUserId);
@@ -1537,11 +1545,16 @@ export class MatrixCall extends EventEmitter {
create_call: replacementId, create_call: replacementId,
} as MCallReplacesEvent; } as MCallReplacesEvent;
if (targetRoomId) body.target_room = targetRoomId;
return this.sendVoipEvent(EventType.CallReplaces, body); return this.sendVoipEvent(EventType.CallReplaces, body);
} }
/*
* Transfers this call to the target call, effectively 'joining' the
* two calls (so the remote parties on each call are connected together).
*/
async transferToCall(transferTargetCall?: MatrixCall) {
}
private async terminate(hangupParty: CallParty, hangupReason: CallErrorCode, shouldEmit: boolean) { private async terminate(hangupParty: CallParty, hangupReason: CallErrorCode, shouldEmit: boolean) {
if (this.callHasEnded()) return; if (this.callHasEnded()) return;
@@ -1722,6 +1735,8 @@ export class MatrixCall extends EventEmitter {
// I choo-choo-choose you // I choo-choo-choose you
const msg = ev.getContent(); const msg = ev.getContent();
logger.debug(`Choosing party ID ${msg.party_id} for call ID ${this.callId}`);
this.opponentVersion = msg.version; this.opponentVersion = msg.version;
if (this.opponentVersion === 0) { if (this.opponentVersion === 0) {
// set to null to indicate that we've chosen an opponent, but because // set to null to indicate that we've chosen an opponent, but because
@@ -1735,30 +1750,32 @@ export class MatrixCall extends EventEmitter {
} }
this.opponentCaps = msg.capabilities || {}; this.opponentCaps = msg.capabilities || {};
this.opponentMember = ev.sender; this.opponentMember = ev.sender;
}
private async addBufferedIceCandidates() {
const bufferedCands = this.remoteCandidateBuffer.get(this.opponentPartyId); const bufferedCands = this.remoteCandidateBuffer.get(this.opponentPartyId);
if (bufferedCands) { if (bufferedCands) {
logger.info(`Adding ${bufferedCands.length} buffered candidates for opponent ${this.opponentPartyId}`); logger.info(`Adding ${bufferedCands.length} buffered candidates for opponent ${this.opponentPartyId}`);
this.addIceCandidates(bufferedCands); await this.addIceCandidates(bufferedCands);
} }
this.remoteCandidateBuffer = null; this.remoteCandidateBuffer = null;
} }
private addIceCandidates(cands: RTCIceCandidate[]) { private async addIceCandidates(cands: RTCIceCandidate[]) {
for (const cand of cands) { for (const cand of cands) {
if ( if (
(cand.sdpMid === null || cand.sdpMid === undefined) && (cand.sdpMid === null || cand.sdpMid === undefined) &&
(cand.sdpMLineIndex === null || cand.sdpMLineIndex === undefined) (cand.sdpMLineIndex === null || cand.sdpMLineIndex === undefined)
) { ) {
logger.debug("Ignoring remote ICE candidate with no sdpMid or sdpMLineIndex"); logger.debug("Ignoring remote ICE candidate with no sdpMid or sdpMLineIndex");
return; continue;
} }
logger.debug("Got remote ICE " + cand.sdpMid + " candidate: " + cand.candidate); logger.debug("Call " + this.callId + " got remote ICE " + cand.sdpMid + " candidate: " + cand.candidate);
try { try {
this.peerConn.addIceCandidate(cand); await this.peerConn.addIceCandidate(cand);
} catch (err) { } catch (err) {
if (!this.ignoreOffer) { if (!this.ignoreOffer) {
logger.info("Failed to add remore ICE candidate", err); logger.info("Failed to add remote ICE candidate", err);
} }
} }
} }