diff --git a/kernel/packages/voice-chat-codec/VoiceCommunicator.ts b/kernel/packages/voice-chat-codec/VoiceCommunicator.ts index ea0fc61c3b..00fed87961 100644 --- a/kernel/packages/voice-chat-codec/VoiceCommunicator.ts +++ b/kernel/packages/voice-chat-codec/VoiceCommunicator.ts @@ -283,28 +283,27 @@ export class VoiceCommunicator { this.input?.workletNode.port.postMessage({ topic: topic }) } - private createRTCLoopbackConnection( - currentRetryNumber: number = 0 - ): { src: RTCPeerConnection; dst: RTCPeerConnection } { + private createRTCLoopbackConnection(retryNumber: number = 0): { src: RTCPeerConnection; dst: RTCPeerConnection } { const src = new RTCPeerConnection() const dst = new RTCPeerConnection() - let retryNumber = currentRetryNumber + // Apparently the RTCPeerConnection can be 'undefined' until the user accepts/blocks the microphone usage in the browser (https://github.com/webRTC-io/webrtc.io-client/issues/30#issuecomment-15991572) + // @ts-ignore + if (!dst || !src) { + return this.createRTCLoopbackConnection(retryNumber + 1) + } - ;(async () => { + (async () => { // When having an error, we retry in a couple of seconds. Up to 10 retries. src.onconnectionstatechange = (e) => { if ( src.connectionState === 'closed' || src.connectionState === 'disconnected' || - (src.connectionState === 'failed' && currentRetryNumber < 10) + (src.connectionState === 'failed' && retryNumber < 10) ) { // Just in case, we close connections to free resources this.closeLoopbackConnections() - this.loopbackConnections = this.createRTCLoopbackConnection(retryNumber) - } else if (src.connectionState === 'connected') { - // We reset retry number when the connection succeeds - retryNumber = 0 + this.loopbackConnections = this.createRTCLoopbackConnection(retryNumber + 1) } } @@ -317,20 +316,26 @@ export class VoiceCommunicator { const offer = await src.createOffer() - await src.setLocalDescription(offer) + await src.setLocalDescription(offer).catch((err) => { + return Promise.reject(err) + }) - await dst.setRemoteDescription(offer) + await dst.setRemoteDescription(offer).catch((err) => { + return Promise.reject(err) + }) const answer = await dst.createAnswer() const answerSdp = parse(answer.sdp!) - answerSdp.media[0].fmtp[0].config = 'ptime=5;stereo=1;sprop-stereo=1;maxaveragebitrate=256000' - answer.sdp = write(answerSdp) - await dst.setLocalDescription(answer) + await dst.setLocalDescription(answer).catch((err) => { + return Promise.reject(err) + }) - await src.setRemoteDescription(answer) + await src.setRemoteDescription(answer).catch((err) => { + return Promise.reject(err) + }) })().catch((e) => { defaultLogger.error('Error creating loopback connection', e) })