16 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=')) {

    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).

    o=mozilla…THIS_IS_SDPARTA-52.0.1 306592031755684620 0 IN IP4
    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=msid-semantic:WMS *
    m=audio 9 UDP/TLS/RTP/SAVPF 111 126
    c=IN IP4
    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=msid:{0b6ba407-0b05-2a4c-987d-16932f6b46a0} {f9c2bca5-a6e4-f742-b4e2-ce31d8e97315}
    a=rtpmap:111 opus/48000/2
    a=rtpmap:126 telephone-event/8000/1
    a=ssrc:2245107761 cname:{64d3d89b-9c3c-904d-bd59-060fb2c89417}
    m=video 9 UDP/TLS/RTP/SAVPF 96
    c=IN IP4
    a=fmtp:96 max-fs=12288;max-fr=60
    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=rtpmap:96 VP8/90000
    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

  8. Pingback: “Why We Didn’t Use A Framework” (Case Study) - ThemesAffair

  9. Hey guys, I know this post is a bit old, but I don’t know if someone could help me answering some simple questions about this. I am just an enthusiast of webRTC and I am just starting so I apologize if some questions may seem silly or stupid.

    At this moment this is still the only way to control the bandwidth of a webRTC session? I ask this because in the article ORTC is mentioned, what happens with it? there is another ay to manipulate the BW?

    Another question that I would like to do is, what happens if I change the bandwidth limit but I do not change the camera resolution through the getUserMedua() method? for example, what happens if I have a resolution of 320×240 and I am using a good bandwidth to transmit that resolution, and then I inrease the bandwidth limit for the video? It should stay in the old resolution, right? could anybody confirm it?

    I appreciate all the help and thanks in advance for all the possible answers.


      • Hey Chad! Thanks for your Reply, it was very useful to learn a lot of things.

        In that code they do the bandwidth control with both methods SDP and ORTC, but in that code I think they are handling the bandwidth in general and not for each media (Audio and Video), I tried to enable Audio in that demo (because it was disable) and when I modify the bandwidth it has an strange behavior with BW, the AudioBW is the one modified and the VideoBW goes the lowest value possible. I am guessing that it could maybe a confusion between the bandwidth of Video and Audio.
        Do you know where can I read more about how to modify the bandwidth separately with ORTC? Just like here it is made with SDP for Audio and Video Separately?

        By the way, I am testing this code and it seems to have some errors to work properly.

        Thanks in advance for your answer Chad.


  10. Great post, thanks so much for your help.
    I modified the SDP offer before sending it to the remote peer, but I don’t have easy access to that peer so I modify the SDP answer that I receive before calling setRemoteDescription(new RTCSessionDescription(answer)) on my local peer.

    I also stumbled trying to set the kbps to 5 instead of the 50 you used in the article. I wanted to make sure I could tell the difference, but 5 was too low to be negotiated properly. I could hear the difference with 50 just fine.

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.