surfrock66
surfrock66

Reputation: 79

How do you re-add a track to a RTCRtpSender for an RTCRtpPeerConnection, instead of creating a new/second RTCRtpSender?

I've polished a front end around an existing webRTC/SIP javascript API and it works well, but I've discovered a bug in the underlying API around hold/resume and it's causing me to have to dip into the WebRTC stuff which is well outside my comfort zone.

As it is, calls work. If I place the call on hold, I can see that my RTCPeerConnection has a sender and that sender's track becomes null. I have an RTCRtpTransceiver, and that never enters the "stopped" state. The SIP server acknowledges the hold. This is done with a "removeTrack()" of the sender. When I go to resume the call, the API calls an "addTrack()" on the peerconnection. What happens is now I have 2 RTCRtpSenders, and 2 RTCRtpTransceivers, with the track showing up under the 2nd of each. The actual user experience is that the remote audio resumes, but my mic never returns to the call.

My understanding is, I want the mediaStreamTrack to reconnect to the original RTCRtpSender, right? Looking here, there's conditions to reuse a sender but it's not happening; my read of the original API source code makes it look like they expect to reattach to the existing sender: https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/addTrack

One thing I tried doing was issuing a "stop()" to the RTCRtpTransceiver, but that actually causes the connection to the SIP server to fail and it sends an ack back that the hold failed.

I wasn't able to get anywhere with setStreams, and replaceTrack would require making enough of a switch to making things asynchronous that I didn't want to proceed down that road yet.

I fully admit the webRTC stuff is over my head; we added things like AD Integration and some DB stuff to store chats/call history, but squashing a bug in how the API handles WebRTC stuff is a bit out of reach for me.

Does anyone have some recommendation for how to handle this? It's tricky because we can't make our demo public, but I can provide debug.

The source is here, starting on 406: https://github.com/L1kMakes/sipml5-ng/blob/master/src/tinyMEDIA/src/tmedia_session_jsep.js

Upvotes: 0

Views: 681

Answers (1)

surfrock66
surfrock66

Reputation: 79

The solution was switching to replaceTrack. I need to clean this up a bit, but this prototype works:

const sender = this.o_pc.getSenders()[0];
const track = This.o_local_stream.getTracks()[0];
sender.replaceTrack(track)
    .then(() => {
        console.log("tmedia_session_jsep - resume - Successful Stream Replace!");
    })
    .catch( e => console.log("tmedia_session_jsep - resume - Error: " + e));
this.o_pc.getTransceivers()[0].direction = "sendrecv";

Upvotes: 0

Related Questions