为了确保这篇文章所写内容尽可能的准确,我决定请来 Philipp Hancke 来作为此篇文章的共同作者。 当你想要找到你 WebRTC 产品中的问题时, webrtc-internals 是一个非常棒的工具,因为你需要用它测试 WebRTC 以及 debug ,或者你需要对你的配置进行微调。
如何获得 webrtc-internals 的数据转储( statsdump )? ▼
如果你对这个工具不熟悉的话,那么打开你 Chrome 浏览器里的 WebRTC 段,在这段里打开另一个表单并且将其指向这个内部( internal ) URL :chrome://webrtc-internals/
webrtc-internals 允许将轨道作为大型的 JSON 下载下来,这样你就可以一层一层地来看它了,但是当你这么做的时候,你会看到类似这样的东西:
查看 webrtc-internals 数据
人们通常问到的第一件事是 — 这些数字到底代表什么?一位我们自己的测试人员将这些值放入时序图表里并且将其输出出来。这就给了我们要比直接从 webrtc-internals 中取出的 300×140的图片要大的多的图表。
这些图表是使用 HighCharts 库得到的,并且有很多十分方便的特性,比如隐藏线条,放大所需区域,或者停靠在特定点处并显示精确值。这比用 JSON 转储(像上面一样)要方便的多。 回到基础的 webrtc-internals 页中。在此页顶端,我们可以考到一系列的表单,一个是给 getUserMedia 调用的,剩下的两个分别给每个 RTCPeerConnection 。
在 GetUserMedia 请求表单中,我们可以看到每次的 getUserMedia 调用,以及相关约束。不幸的是,我们不能看到结果或者 MediaStreams 中有的 ids 。
RTCPeerConnection 数据
对于每个 peerconnection,我们可以在这里看到这四点:
RTCPeerConnection API 轨迹是非常强大的工具,可以帮助你完成很多的事情,比如分析造成 ICE 失败的原因,或者帮你找到适合部署 TURN 服务器的地方。我们会在以后的博文中来谈这些。 webrtc-internals 所给出的统计数据是 Chrome 的内部格式。这意味着其与目前的规范略有不同步,一些名称和结构体会有改变。在较高层,我们在 webrtc-internals 页上看到的与我们调用这个函数所得到的结果相近:
下面是 RTCStatsReport 对象的队列,其中有很多秘钥和数值,可以这样读取:
要记住的是在这些统计数据和规范之间有一些区别。这里面有一个经验法则,任意一个名称以 “Id” 结尾的秘钥都包含一个指向不同的报告,其 id 属性与秘钥的值对应。所以全部这些报告都是彼此相连的。还要注意,这些值都是字符型的,尽管它们看起来像布尔值那样的数字。 RTCStatsReport 中最重要的属性是报告的种类,下面是其中的几种:
让我们来深入探讨一下这些报告型
googTrack与googLibjingleSession报告 googTrack 和 googLibjingleSession 没包含什么信息,所以我们跳过它不做分析。 googCertificate报告
googCertificate
报告包括了一些有关近端和对等端所使用的 DTLS 证书的信息,以及指纹和哈希算法。这些都在 RTCCertificateStats 字典中有详细说明。googComponent报告
googComponent 报告的作用就像是认证数据与连接之间的胶水。它包含了一个纸箱当前活跃的候选项对的指针,以及有关用语 DTLS 和 SRTP 加密的加密套接字。
googCandidatePair报告
候选做了描述,也就是低层次的连接。从这个报告中,你可以得到这些信息:
从下面这张图上可以比较直观地看到一些数据,如发送和接收的字节数等等:
localCandidate和remoteCandidate报告 感谢上天 localCandidate 和 remoteCandidate 与规范中所描述的是一模一样的,告诉我们 ip 地址,端口号,以及候选项的类型。对于 TURN 候选来说,其会告诉我们候选被分配在哪个端口上了。 Ssrc报告 ssrc 报告是这里面最重要的报告之一。每一个音频或者视频轨道发送或接收都有一个 ssrc 报告。在旧版本的规范中,这些叫做 MediaStreamTrackStats 和 RTPStreamStats 。其内容决定于这是音频还是视频轨道,以及这是发送还是接收。让我们先来描述下一些其中基本的元素:
音频特性
对于音轨来说,我们有 audioInputLevel 和 audioOutputLevel (在规范中叫做 audioLevel )可以告诉我们音频信号是来与麦克风,还是通过扬声器播出的。这个特性可以用来探测 Chrome 里不受欢迎的音频 bug 。我们还可以通过 googJitterReceived 和 googJitterBufferReceived 得知有多少抖动被接收,以及 jitter buffer 的状态。
视频特性
对于视频轨道来说,我们有两大信息需要关注。第一个是被送入 googNacksSent , googPLIsSent 和 googFirsSent 中, NACK , PLI 和 FIR 数据包的数量差别。这可以让我们知道丢包会如何影响视频质量。
更重要的是,我们得知了框架大小和速率是作为输入( googFrameWidthInput , googFrameHeightInput , googFrameRateInput )并且实时上是发送到网络之上( googFrameWidthSent , googFrameHeightSent , googFrameRateSent )。 相似的数据可以在接收端被收集到存在 googFrameWidthReceived , googFrameHeightReceived 中。对于框架速率来说我们甚至可以将其从 googFrameRateReceived , googFrameRateDecoded 和 GOOGFrameRateOutput 中分开来。 在编码端我们可以看到这些值之间的差别,还能知道为什么图片会被缩小。通常这些事情发生不是因为没有足够大的 CPU ,就是没有足够大的带宽来传送完整的图片。另外,想要降低框架速率(其可以从对比 googFrameRateInput 和 googFrameRateSent 之间的差距得到),我们需要得到额外的信息:分辨率是否因为 CPU 的问题而得到适应,以及是否是因为带宽不够使得 googBandwidthLimitedResolution 的值是真。无论是上述哪个情况发生了改变, googAdaptionChanges 计数器都会增加。 我们可以从这张图表上看到这些变化:
这里的丢包是人为产生的。作为反应, Chrome 在 t=184 时第一次尝试降低分辨率,这是绿线代表的 googFrameWidthSent 开始偏离黑线代表的 googFrameWidthInput 。接下来在 t=186 时,框架开始下降,输入框架速率(浅蓝色线条所示)大约是 30fps ,与发出的框架速率(蓝色线条所示)产生区别,后者几乎是 0.
另外, Chrome 在 ssrc 报告中公开了大量关于音频和视频堆栈的表现的数据。我们会在未来的博文中进行讨论。
最后,但并不是不重要,我们来分析一下 VideoBWE 报告。就像它名字所表达的,它包括有关带宽估计的信息。但是还有一些其他的有用信息包含在这个报告里:
正如你看到的,这个报告会给你视频质量最重要的信息 — 可用带宽。查看发送和接收的可用带宽通常都是在深入分析 ssrc 报告之前做的最重要的事。因为有时你可能会发现这样的情况,这解释了用户所抱怨的 “ 质量差 ” :
在这种情况下, “ 在所有时间里,带宽估计都在下降 ” 是对质量问题的一个比较好的解释。
原作者: Levent-Levi
翻译:刘通
原文链接: http://testrtc.com/webrtc-internals-parameters/