原作者:Nick Gauthier(原文链接)
翻译:刘通
WebRTC 1.0使用SDP(会话描述协议)来在对话双方之间进行性能协商。尽管有越来越多的对象来帮助WebRTC挣脱这项协议的限制,但实际情况是,SDP还会伴随我们一段时间。如果你想要进行比如更换编解码器,或者更改带宽限制这些工作的话,你就需要对SDP做一些改变。
在近期一次WebRTC会议上,MeetSpace的Nick Gauthier讲解了他是如何不使用媒体服务器就能够将10个视频通话者塞进同一个聊天会议室中去的。虽然不是所有人都想要做这件事情,但是其中有很多内容可以用来精准的控制你的带宽消耗量,这一点就比较有用了。你可以点击这里来观看他的视频,或者阅读下面将要提到的他是如何更改SDP来调整个人带宽使用量的。
如果不进行人工干涉的话,WebRTC PeerConnection就会为了最好的传输质量,而消耗掉所有可用的带宽资源。当然,如果你只是在进行会议通话的话这是最好的情况,但是如果你要中途切出去发封邮件的时候,或者因为带宽资源突然变少而整个通话变得卡顿的时候,这种情形就不能让人满意了。或者你想要对那些连接环境差的用户提供用户可控质量选择。又或者你想像我们一样运行一个10路的网格通话,这样的话PeerConnection就会彼此竞争带宽资源。
在本文中,我们会讨论如何解析SDP负荷,以及如何在JavaScript通过设定最大带宽容量来对SDP作出调整。
在哪里修改SDP
我们要做的第一件事就是获取SDP负载。当一个PeerConnection对其中一个对等端创建请求时,SDP是第一个产生的。
我们需要做的就是在请求的SDP被发送到远端之前对其进行人工修改。
这里我们调用一个新的函数setMediaBitrates,用来修改SDP负载以及将其返回给我们。(会在下一段对其进行说明)
需要在注意的是,我们不可以在createOffer(或者createAnswer)与setLocalDescription之间对请求进行修改,所以我们一定要在其被发送到远端之前完成这项工作。
当这个请求到达远端的时候,还需要在生成应答的时候再次对SDP进行修改。这是因为请求说“这是我可以处理的带宽”,那么应答也会说“那这个是我可以处理的带宽”,所以如果你想要两边的带宽都被限制,你就必须也对应答的SDP进行修改。只需要进行与刚才十分类似的工作:
现在我们可以开始了!
解析SDP
我强烈推荐大家去读这篇文章Update: Anatomy of a WebRTC SDP (Antón Román),这回让你对SDP有一个清楚全面的认识。
接下来,我就要进到RFC 4566 SDP: Session Description Protocol这个说明里面,这个链接直接指引到第七页,第五段,其中描述了SDP的格式。
TL;DR指的是,SDP是一个UTF-8的语块,被分成了一行一行的,每一行都是<type>=<value>格式。
另一个非常重要的部分在第五段的靠下的位置:排序类型(the ordering of types)。我不会在这里将其全部都重复一遍,但是我们需要的部分是在SDP开头的部分,接在重复媒体描述的后面。媒体描述经常都是m, I, c, b, k, a。
接下来我们需要看的是RFC 3556 Session Description Protocol (SDP) Bandwidth Modifiers for RTP Control Protocol (RTCP) Bandwidth。这段RFC说明描述了如何利用a b行设定带宽。通过b=AS:XXX,其中XXX是我们想要设定的带宽大小。AS的意思是它是“应用指定最大值”(Application Specific Maximum),意味着它限制着总带宽。从这篇RFC说明中,我们还可以看到,带宽值得单位应该是kbps。
这意味着我们的代码需要进行这些工作:
#1 跳过这些行,直到我们找到了m=audio或者m=video(取决于我们在设置什么)。
#2 跳过i和c行。
#3 如果我们在b行,就替换他。
#4 如果我们没有在b行,就添加一个新的b行。
修改SDP来添加一个带宽约束
在WebRTC视频通话中,绝大多数时间都有一个对视频的媒体描述,一个对音频的媒体描述。在我们这个例子中,我们会将视频带宽限制在500kb/s,音频带宽限制在50kb/s。让我们来看一下代码:
这就完成了!说实话当我第一次面对SDP的时候确实有点被它吓到了。有太多复杂的内容让它看起来好像完全不能克服。但是花一天的事件,它们就会变成一行行的内容,并且会明白每一行都有其存在的原因,如果你将它们拆开,SDP就会变得比较好处理了。
我们不需要整齐的表达,因为所有的部分都已经是处在很整齐的情况了。而且在我们的例子中,我们想要完全替换掉b行,所以我们也不需要对复杂行进行分析。
我希望这篇文章可以帮助你限制你WebRTC通话的带宽,并且帮助你在处理SDP以及RFC说明的时候更加从容。