I've written a very minimal HTML+JS sample to test different strategies for muting audio/video streams:
https://github.com/Kurento/experiments/tree/master/WebRTC/mute-tracksOne of the tests is to call RtcPeerConnection.addTrack()/removeTrack() methods, but it is not working as expected under some circumstances, on Chromium 65.0.3325.181 (running on LinuxMint 18.3 64-bit).
To run the test: clone the repo, open the HTML file, optionally check the "Force sendonly/recvonly in SDP", hit Start, and then check/uncheck the "Remove AUDIO track" checkbox while watching the JS Console.
As you'll see in the JS code, if PC1.onnegotiationneeded calls "PC1.createOffer()" without options then PC1 will generate an SDP Offer with "a=sendrecv", regardless of whether the peer will be only sending and not really receiving. I've observed that the receiving peer will then set "a=recvonly" on its "PC2.createAnswer()". Later, after removing the audio track, these become "a=recvonly" and "a=inactive", respectively. Lastly, when re-adding the audio track, these become again "a=sendrecv" and "a=recvonly". Everything works fine in this case.
If PC1.onnegotiationneeded calls "PC1.createOffer({offerToReceiveAudio:false})" then the SDP Offer from PC1 gets an "a=sendonly" and the receiving side still sets "a=recvonly", as expected. Later, after removing the audio track, these become "a=inactive" at both sides, also as expected. Lastly, when re-adding the audio track, there is an error because PC2 didn't generate its SDP Answer with the required attributes "a=ice-ufrag" and "a=ice-pwd":
On pc2.createAnswer().then(pc2.setLocalDescription(answer)):
OperationError: Failed to set local answer sdp: Called with SDP without ice-ufrag and ice-pwd.
Feels like a bug but I didn't file one yet because first I wanted to ask and validate if this is an error in my code. I've been very careful to follow all documentation of each respective methods, but maybe I'm missing something. Firefox 59 works fine.
Pastebin with all logs and SDP messages:
https://pastebin.com/XbXaYVh1