Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WebRTC: how to detect when a stream or track gets removed from a PeerConnection, in Firefox?

onremovestream has been deprecated (and removed from Firefox), while onremovetrack is not yet implemented in Firefox.

How do I detect when a stream or track is being removed in Firefox?

like image 212
Daniele Molinari Avatar asked Mar 11 '20 12:03

Daniele Molinari


People also ask

What is WebRTC transceiver?

The WebRTC interface RTCRtpTransceiver describes a permanent pairing of an RTCRtpSender and an RTCRtpReceiver , along with some shared state. Each SDP media section describes one bidirectional SRTP ("Secure Real Time Protocol") stream (excepting the media section for RTCDataChannel , if present).

What is WebRTC Peerconnection?

The RTCPeerConnection interface represents a WebRTC connection between the local computer and a remote peer. It provides methods to connect to a remote peer, maintain and monitor the connection, and close the connection once it's no longer needed. EventTarget RTCPeerConnection.

What is renegotiation WebRTC?

In short, in order to add video or audio to an existing connection, you need to renegotiate the connection every time you make a media change. Basically you register a listener: pc.

Why doesn't WebRTC end the track of the receiving side?

In standard WebRTC ("unified-plan") our transceiver.receiver.track isn't ended when this happens, because it is wired to the other side's transceiver.sender, not the other side's transceiver.sender.track. Instead of ending, our receiving track is muted and removed from its stream (s).

What is rtctrackevent in WebRTC?

The WebRTC API interface RTCTrackEvent represents the track event, which is sent when a new MediaStreamTrack is added to an RTCRtpReceiver which is part of the RTCPeerConnection. The target is the RTCPeerConnection object to which the track is being added.

Does WebRTC work in all browsers?

Here's an example that should work in all browsers. In standard WebRTC ("unified-plan") our transceiver.receiver.track isn't ended when this happens, because it is wired to the other side's transceiver.sender, not the other side's transceiver.sender.track.

When is the track event sent to the rtcpeerconnection?

The track event is sent to the RTCPeerConnection when a new track has been added to the connection. By the time the track event is delivered to the RTCPeerConnection 's ontrack handler, the new media has completed its negotiation for a specific RTCRtpReceiver (which is specified by the event's receiver property).


1 Answers

You use onremovetrack on the receiving stream:

pc.ontrack = ({track, streams: [stream]}) => {
  track.onunmute = () => {
    if (!video.srcObject) video.srcObject = stream;
  };
  stream.onremovetrack = ({track}) => {
    console.log(`${track.kind} track was removed.`);
    if (!stream.getTracks().length) {
      console.log(`stream ${stream.id} emptied (effectively removed).`);
    }
  };
};

The above ontrack will run when e.g. the other side adds a track (and negotiates):

const sender = pc.addTrack(track, stream);

Now, whenever that other side calls either pc.removeTrack(sender) or sets transceiver.direction = "recvonly" (and negotiates), you should see the removetrack event fire.

Here's an example that should work in all browsers.

Things to keep in mind

In standard WebRTC ("unified-plan") our transceiver.receiver.track isn't ended when this happens, because it is wired to the other side's transceiver.sender, not the other side's transceiver.sender.track.

Instead of ending, our receiving track is muted and removed from its stream(s).

This is because pc.removeTrack(sender) only sets the sender.track to null and transceiver.direction to recvonly (requiring negotiation).

A sender may thus resume sending data using sender.replaceTrack(newTrack) and setting transceiver.direction = "sendrecv" again. On this happening, our receiver.track would be unmuted again and reinserted into the stream(s), firing the addtrack events on the stream(s). This also fires the track event again. Explore all the events in this blog's interactive section.

A receiving track is only truly ended by transceiver.stop() (locally or through negotiation), or pc.close().

like image 70
jib Avatar answered Sep 19 '22 22:09

jib