11 comments on “How to limit WebRTC bandwidth by modifying the SDP

  1. Got this from Nils (Firefox team): The blog post should mention that b=AS only works with Chrome. For Firefox you need to look for b=TIAS to accomplish the same.

    • Hey @Victor,

      Are you sure about that point?

      I currently seems to “work” for me on Firefox 51 & 52 ;
      At least it doesn’t trigger any error when setting the updated RTCSessionDescription as remote description.
      Maybe it doesn’t have any effect on bandwidth, though? How to mesure it?

      And I am wondering, as “b=AS” is following the RFC 3556, what would be the point for Firefox not to follow it?

  2. Hey,

    Thanks for this tip,
    If you’re interested, here is an ES6 rewrite of the same method 🙂
    Feel free to use it if you wish.

    setMediaBitrate(sdp, mediaType, bitrate) {
    let sdpLines = sdp.split(‘\n’),
    mediaLineIndex = -1,
    mediaLine = ‘m=’ + mediaType,
    bitrateLineIndex = -1,
    bitrateLine = ‘b=AS:’ + bitrate,
    mediaLineIndex = sdpLines.findIndex(line => line.startsWith(mediaLine));

    // If we find a line matching “m={mediaType}”
    if (mediaLineIndex && mediaLineIndex < sdpLines.length) {
    // Skip the media line
    bitrateLineIndex = mediaLineIndex + 1;

    // Skip both i=* and c=* lines (bandwidths limiters have to come afterwards)
    while (sdpLines[bitrateLineIndex].startsWith('i=') || sdpLines[bitrateLineIndex].startsWith('c=')) {
    bitrateLineIndex++;
    }

    if (sdpLines[bitrateLineIndex].startsWith('b=')) {
    // If the next line is a b=* line, replace it with our new bandwidth
    sdpLines[bitrateLineIndex] = bitrateLine;
    } else {
    // Otherwise insert a new bitrate line.
    sdpLines.splice(bitrateLineIndex, 0, bitrateLine);
    }
    }

    // Then return the updated sdp content as a string
    return sdpLines.join('\n');
    }

  3. With this we limit download bandwidth or upload bandwidth or both? If answer is both. Is there a way to control each one of them individually?

  4. I did this and although I set the lines correctly (according to the sdp output I do afterward) the following happens:

    As soon as the AUDIO bandwidth is changed, the VIDEO bandwidth goes to the same bandwidth (according to the CHROME graphical analsys at chrome:webrtc-internals).

    I can repeat this behavior anytime Chrome 57 (PC) connected to Chrome 57 (Mac). If I connect from Chrome 57 (Mac) to Vivaldi, the outcome is as expected and correct.

    Anybody suggestions?

  5. PS: I am changing the bandwidth on the fly: When the connections first is established, audio and video bandwidth are set correctlys. When I change audio BW during a connections, BOTH audio and video bandwidth change to the value set for Audio BW, although correct value for video is given and inserted.

    • Hey Armin,

      Sorry but I haven’t tried the on-the-fly adjustments yet. I’m waiting for applyConstraints to drop for chrome so I can adjust frame rate and size at the same time. I dunno how much it’s worth to only adjust bandwidth without adjusting frame size and height (although I tend to be more concerned about cpu usage).

  6. Here is the remoteDescription (chrome connecting to firefox, but it is the same with Chrome to Chrome).

    v=0
    o=mozilla…THIS_IS_SDPARTA-52.0.1 306592031755684620 0 IN IP4 0.0.0.0
    s=-
    t=0 0
    a=fingerprint:sha-256 8C:E4:68:9A:0C:DA:15:DC:FC:18:92:02:D2:93:9A:81:D0:BE:BF:86:99:EC:5E:CD:C8:5F:99:78:9F:DA:AA:32
    a=group:BUNDLE audio video
    a=ice-options:trickle
    a=msid-semantic:WMS *
    m=audio 9 UDP/TLS/RTP/SAVPF 111 126
    c=IN IP4 0.0.0.0
    b=AS:160
    a=sendrecv
    a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
    a=fmtp:111 vbr=1; minptime=10; ptime=20; useinbandfec=1; usedtx=0; sprop-maxcapturerate=48000; maxplaybackrate=48000; maxaveragebitrate=320000
    a=fmtp:126 0-15
    a=ice-pwd:aeb7995cdaf18ceaae9ca2225bf8ba67
    a=ice-ufrag:680cb6e6
    a=mid:audio
    a=msid:{0b6ba407-0b05-2a4c-987d-16932f6b46a0} {f9c2bca5-a6e4-f742-b4e2-ce31d8e97315}
    a=rtcp-mux
    a=rtpmap:111 opus/48000/2
    a=rtpmap:126 telephone-event/8000/1
    a=setup:active
    a=ssrc:2245107761 cname:{64d3d89b-9c3c-904d-bd59-060fb2c89417}
    m=video 9 UDP/TLS/RTP/SAVPF 96
    c=IN IP4 0.0.0.0
    b=AS:250
    a=sendrecv
    a=fmtp:96 max-fs=12288;max-fr=60
    a=ice-pwd:aeb7995cdaf18ceaae9ca2225bf8ba67
    a=ice-ufrag:680cb6e6
    a=mid:video
    a=msid:{0b6ba407-0b05-2a4c-987d-16932f6b46a0} {c4854cab-8bc6-3a4a-abc3-c700cafa228c}
    a=rtcp-fb:96 nack
    a=rtcp-fb:96 nack pli
    a=rtcp-fb:96 ccm fir
    a=rtcp-fb:96 goog-remb
    a=rtcp-mux
    a=rtpmap:96 VP8/90000
    a=setup:active
    a=ssrc:1569125431 cname:{64d3d89b-9c3c-904d-bd59-060fb2c89417}

    As you can see, video should be (stay) at 250 but it will drop to 160 (same as Audio BW) as soon as remoteDescription is set.

    I get the EXACT same remoteDescription on connecting but there it works.

    Any idea? Highly appreciated!

  7. Pingback: “Why We Didn’t Use A Framework” (Case Study) – Smashing Magazine

Leave a Reply

Your email address will not be published. Required fields are marked *