Alberto Fecchi
Alberto Fecchi

Reputation: 3406

WebRTC - multi-track streams issue on Firefox <> Chrome

I created a video-call + multiple screen sharing app that works well in every case except one.

The main flow is:

The webcam flow always works well, while the screen sharing breaks in a specific case:

Failed to execute 'setLocalDescription' on 'RTCPeerConnection': Failed to parse SessionDescription. a=rtpmap:127 H264/90000 Duplicate  payload type with conflicting codec name or clock rate

Looking at the offer's SDP, i see that the payload for the line a=rtpmap:127 is duplicated:

a=rtpmap:127 H264/90000
...
a=rtpmap:127 rtx/90000

This error happens ONLY in the specified flow (Chrome sends an offer first, Firefox answers (and camera works well), Firefox share a screen and i get the SDP error). If the first offer is sent by a Firefox user, everything works well. If the first offer is sent by a Chrome, everything works well if the first screen sharing is started by a Chrome user.

If the first offer is sent by a Chrome user and then a Firefox user shares a screen, it breaks. Only in this case.

So, the problem is that the offer created by the Firefox user during the first screen sharing contains that payload conflict.

Why does it happen (only in that case) and how can i prevent this error?

Upvotes: 1

Views: 374

Answers (1)

giacomoto
giacomoto

Reputation: 504

I also run into this bug and i didn't found a solution other than modifying the SDP description by myself. Although this is a rough workaround, it fix the codec collision bug.

  1. You want to remove the duplicate codec number form the video track (127 here):

    m=video 9 UDP/TLS/RTP/SAVPF 100 101 127 127 ...

  2. then remove the payload of the RTX codec.

    a=rtpmap:127 RTX/90000

    ...

Keep in mind that RTX is used to resend corrupted packages

RTX stands for retransmission. RTX

RTP retransmission is an effective packet loss recovery technique for real-time applications with relaxed delay bounds rfc4588

So removing it from payload may void this capability.

Here my JS (typescript) function

removeDuplicateCodecs(sdp: string): string {
    // split sdp for each video track
    const lines = sdp.split(/^(?=m=video)/gm);

    for (let i = 0, videosLength = lines.length; i < videosLength; i++) {
        if (lines[i].startsWith("m=video")) {
    
            // split each line
            let rows = lines[i].split(/\r\n/gm);
            const codecDuplicated: string[]= [];

            if (rows.length) {
                // take first row and get all codecs
                const duplicates = rows[0].match(/(\b\d+\b)(?=.*\b\1\b)/g);

                if (duplicates?.length) {
                    duplicates.forEach(duplicate => {
    
                        // remove duplicates from row
                        rows[0] = rows[0].replace(` ${duplicate}`, '')
                        codecDuplicated.push(duplicate);
                    });
                }
            }

            // join back all rows
            lines[i] = rows.join('\r\n');

            // split by rtpmap
            rows = lines[i].split(/^(?=a=rtpmap:)/gm);
            if (rows) {
                codecDuplicated.forEach(duplicate => {
                        
                    // remove duplicate codec definitions rows
                    rows = rows.filter(row => !row.startsWith(`a=rtpmap:${duplicate} rtx`));
                });
                lines[i] = rows.join('');
            }
        }
    }
    return lines.join('');
}

Upvotes: 0

Related Questions