I'm developing a WebRTC application using JavaScript, where I programmatically disable video and audio tracks (MediaStreamTrack.enabled = false) before sending them to peers. Despite setting the enabled property of tracks to false locally and confirming the state post-replacement, the receiving peers always get the track with enabled set to true. I'm using the replaceTrack method to update tracks in an ongoing RTCPeerConnection. Here's a simplified version of my code:
const replacePartyAvStreamTracks = (
newStream: MediaStream,
currentPartyAvCalls: Map<string, MediaConnection>,
) => {
currentPartyAvCalls.forEach((call) => {
const peerConnection = call.peerConnection;
const audioTrack = newStream.getAudioTracks()[0] || null;
const videoTrack = newStream.getVideoTracks()[0] || null;
if (!peerConnection.getSenders()) return;
peerConnection.getSenders().forEach((sender) => {
if (!sender.track) return;
let newTrack: MediaStreamTrack | null = null;
if (sender.track.kind === 'audio') {
newTrack = audioTrack;
newTrack.enabled = false;
} else if (sender.track.kind === 'video') {
newTrack = videoTrack;
newTrack.enabled = false;
}
if (newTrack !== null) {
sender
.replaceTrack(newTrack)
.then(() => {
console.log('Track replaced and disabled', newTrack!.enabled);
})
.catch((err) => {
console.error(`Error replacing ${sender.track!.kind} track:`, err);
});
} else {
console.log(`No new ${sender.track.kind} track available to replace.`);
}
});
});
};
Despite the console log confirming the track is disabled (false) after replacement, the receiving peers always interpret the track as enabled (true).
Questions:
Additional Context:
The issue occurs across multiple browsers.
The enabled property is confirmed to be false immediately after the replaceTrack operation, as indicated by the console log.
Other aspects of the signaling and track replacement process work as expected, only the synchronization of the enabled state poses an issue.
I am using the PeerJS package as a dependancy, in case this is a known issue of the package. Looking through their documentation, discussions, and git issues, I have not yet identified the package to be the problem.
I'm looking for insights or suggestions on how to ensure the enabled state of tracks is correctly handled and transmitted in WebRTC peer connections. Thank you for any help!
This is expected, there is nothing in the underyling RTP/RTCP protocols that transmits this "enabled" or synchronized its state. You will need to send a "I enabled/disabled this track" notification either over the signaling channel or a datachannel (same for the initial state).
If you look at the specification this is also expected:
https://www.w3.org/TR/mediacapture-streams/#life-cycle
setting enabled
to false sends blackness or silence but does send something.