ionorg / ion-sfu

Pure Go WebRTC SFU
MIT License
983 stars 238 forks source link

Dead Track in Relay #586

Open mumuan opened 3 years ago

mumuan commented 3 years ago

Your environment.

What did you do?

  1. Alice publish video track(H264,no simulcast) and audio track(opus) to sfu1
  2. Bob receive video and audio track successfully from sfu2
  3. Alice share screen, (VP8, no simulcast)
  4. Bob receive screen video track successfully
  5. Alice stop share screen.
  6. Bob quit and rejoin.
  7. Bob receive video and audio track successfully from sfu2, but also recieve a dead track .

Possible Reason:

If sfu1 relay sfu2 , it use ORTC API. When share screen stopped, it will cause rtpsender(sfu1) stop, but rtpreceiver(sfu2) do not kown that rtpsender(sfu1) has been stopped. So rtpreceiver(sfu2) will keep the dead track.

OrlandoCo commented 3 years ago

Hello @mumuan when you say you are stopping the Share screen, are you stopping the transceiver and causing a renegotiation?

mumuan commented 3 years ago

Hello @mumuan when you say you are stopping the Share screen, are you stopping the transceiver and causing a renegotiation?

Hey @OrlandoCo I am stopping the Share screen from client.

Client SDK Version: ion-sdk-js 1.7.2

 //_unpublish in my client 
 _unpublish = async stream => {

  if (stream) {

   await this._stopMediaStream(stream);

   await stream.unpublish();

   // console.log('unpublish localstream or shareStream',stream);

  }

 };

  //  unpublish in ion-sdk-js , /lib/stream.js
  unpublish() {

​    if (this.pc) {

​      const tracks = this.getTracks();

​      this.pc.getSenders().forEach((s) => {

​        if (s.track && tracks.includes(s.track)) {

​          this.pc.removeTrack(s);

​        }

​      });

​    }

  }
mumuan commented 3 years ago

Hey @OrlandoCo I have sloved this issue. There are two reasons for this issue:

  1. When Alice stop share screen,the associated downtrack in sfu1 will be closed,but publisher did not delete the associated PublisherTrack. Then if anyone join conference from a new sfu node firstly, the dead PublisherTrack will be relayed .
  2. When Alice stop share screen,the associated downtrack in sfu1 will be closed, and the rtpsender will be closed to. But the remote rtpreceiver do not kown that the rtpsender has been closed. So if some peers still in remote sfu node, the session.relayPeers will still exists, and the relayPeer.receiver for the dead track will exists too.

How to fix ?

  1. delete PublisherTrack in downTrack.OnCloseHandler
  2. When rtpsender is closed, emit a signal to remote sfu node by datachannel. Then remote sfu close the receiver of relayPeer.(Because no trackID in rtpreceiver, so we could not found the associated rtpreceiver to close, and only close the associated receiver of relayPeer directly. )