From 3c160c8a37c2c429f913ae2dc0cf3999b527c53a Mon Sep 17 00:00:00 2001 From: Bruno Windels <274386+bwindels@users.noreply.github.com> Date: Fri, 11 Mar 2022 16:35:32 +0100 Subject: [PATCH] handle remote ice candidates --- src/matrix/calls/PeerCall.ts | 48 +++++++++++++++++++++++++++++++----- src/matrix/calls/TODO.md | 1 + 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/src/matrix/calls/PeerCall.ts b/src/matrix/calls/PeerCall.ts index 270e0fa4..fa56601e 100644 --- a/src/matrix/calls/PeerCall.ts +++ b/src/matrix/calls/PeerCall.ts @@ -105,7 +105,7 @@ export class PeerCall implements IDisposable { log(...args) { console.log.apply(console, ["WebRTC log:", ...args])}, warn(...args) { console.log.apply(console, ["WebRTC warn:", ...args])}, error(...args) { console.error.apply(console, ["WebRTC error:", ...args])}, - } + }; } get state(): CallState { return this._state; } @@ -214,9 +214,9 @@ export class PeerCall implements IDisposable { case EventType.Answer: await this.handleAnswer(message.content, partyId); break; - //case EventType.Candidates: - // await this.handleRemoteIceCandidates(message.content, partyId); - // break; + case EventType.Candidates: + await this.handleRemoteIceCandidates(message.content, partyId); + break; case EventType.Hangup: default: throw new Error(`Unknown event type for call: ${message.type}`); @@ -296,7 +296,7 @@ export class PeerCall implements IDisposable { } }; - private async handleInviteGlare(content: MCallInvite, partyId: PartyId): Promise { + private async handleInviteGlare(content: MCallInvite, partyId: PartyId): Promise { // this is only called when the ids are different const newCallId = content.call_id; if (this.callId! > newCallId) { @@ -386,7 +386,7 @@ export class PeerCall implements IDisposable { } } - private async handleAnswer(content: MCallAnswer, partyId: PartyId): Promise { + private async handleAnswer(content: MCallAnswer, partyId: PartyId): Promise { this.logger.debug(`Got answer for call ID ${this.callId} from party ID ${partyId}`); if (this._state === CallState.Ended) { @@ -424,6 +424,42 @@ export class PeerCall implements IDisposable { } } + async handleRemoteIceCandidates(content: MCallCandidates, partyId) { + if (this.state === CallState.Ended) { + //debuglog("Ignoring remote ICE candidate because call has ended"); + return; + } + + const candidates = content.candidates; + if (!candidates) { + this.logger.info(`Call ${this.callId} Ignoring candidates event with no candidates!`); + return; + } + + const fromPartyId = content.version === 0 ? null : partyId || null; + + if (this.opponentPartyId === undefined) { + // we haven't picked an opponent yet so save the candidates + this.logger.info(`Call ${this.callId} Buffering ${candidates.length} candidates until we pick an opponent`); + const bufferedCandidates = this.remoteCandidateBuffer!.get(fromPartyId) || []; + bufferedCandidates.push(...candidates); + this.remoteCandidateBuffer!.set(fromPartyId, bufferedCandidates); + return; + } + + if (this.opponentPartyId !== partyId) { + this.logger.info( + `Call ${this.callId} `+ + `Ignoring candidates from party ID ${partyId}: ` + + `we have chosen party ID ${this.opponentPartyId}`, + ); + + return; + } + + await this.addIceCandidates(candidates); + } + // private async onNegotiateReceived(event: MatrixEvent): Promise { // const content = event.getContent(); // const description = content.description; diff --git a/src/matrix/calls/TODO.md b/src/matrix/calls/TODO.md index 83d706f6..23306c56 100644 --- a/src/matrix/calls/TODO.md +++ b/src/matrix/calls/TODO.md @@ -103,6 +103,7 @@ DONE: Make it possible to olm encrypt the messages Do work needed for state events - DONEish: receiving (almost done?) - DONEish: sending +logging Expose call objects expose volume events from audiotrack to group call Write view model