From f4fec356a390bb4440ae0214529c2c572964e1a8 Mon Sep 17 00:00:00 2001 From: Pierre Lehnen Date: Tue, 4 Nov 2025 16:01:18 -0300 Subject: [PATCH] chore: trigger a renegotiation when a call is put on hold --- .../src/lib/services/webrtc/Processor.ts | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/packages/media-signaling/src/lib/services/webrtc/Processor.ts b/packages/media-signaling/src/lib/services/webrtc/Processor.ts index 0606cf8b37b29..1a521c9999391 100644 --- a/packages/media-signaling/src/lib/services/webrtc/Processor.ts +++ b/packages/media-signaling/src/lib/services/webrtc/Processor.ts @@ -148,6 +148,8 @@ export class MediaCallWebRTCProcessor implements IWebRTCProcessor { this._held = held; this.localStream.setEnabled(!held && !this._muted); this.remoteStream.setEnabled(!held); + + this.updateAudioDirectionWithoutNegotiation(); } public stop(): void { @@ -301,6 +303,34 @@ export class MediaCallWebRTCProcessor implements IWebRTCProcessor { await new Promise((resolve) => setTimeout(resolve, 30)); } + private updateAudioDirectionWithoutNegotiation(): void { + // If the signaling state is not stable, then a negotiation is already happening and the audio direction will be updated by them + if (this.peer.signalingState !== 'stable') { + return; + } + + const desiredDirection = this.held ? 'sendonly' : 'sendrecv'; + const acceptableDirection = this.held ? 'inactive' : 'recvonly'; + + const transceivers = this.getAudioTransceivers(); + for (const transceiver of transceivers) { + // If the last direction we requested still matches our current requirements, then we don't need to change our request + if ([desiredDirection, acceptableDirection, 'stopped'].includes(transceiver.direction)) { + continue; + } + + // If the current state of the call doesn't match what we are requesting here, the browser will trigger the negotiation-needed event for us + this.config.logger?.debug(`Changing desired audio direction from ${transceiver.direction} to ${desiredDirection}.`); + transceiver.direction = desiredDirection; + } + } + + private getAudioTransceivers(): RTCRtpTransceiver[] { + return this.peer + .getTransceivers() + .filter((transceiver) => transceiver.sender.track?.kind === 'audio' || transceiver.receiver.track?.kind === 'audio'); + } + private registerPeerEvents() { const { peer } = this;