![\](http://www.ctiforum.com/uploadfile/2017/0122/20170122093642478.jpg)
当你想要找到你 WebRTC 产品中的问题时,webrtc-internals 是一个非常棒的工具,因为你需要用它测试 WebRTC 以及 debug,或者你需要对你的配置进行微调。
如何获得 webrtc-internals 的数据转储( stats dump )
![\](http://www.ctiforum.com/uploadfile/2017/0122/20170122093731471.jpg)
如果你对这个工具不熟悉的话,那么打开你 Chrome 浏览器里的 WebRTC 段,在这段里打开另一个表单并且将其指向这个内部( internal )URL:chrome://webrtc-internals/
webrtc-internals 允许将轨道作为大型的 JSON 下载下来,这样你就可以一层一层地来看它了,但是当你这么做的时候,你会看到类似这样的东西:
![\](http://www.ctiforum.com/uploadfile/2017/0122/20170122093953187.jpg)
查看webrtc-internals数据
人们通常问到的第一件事是—这些数字到底代表什么?我们自己的一位测试人员将这些值放入时序图表里并且将其输出出来。这就给了我们要比直接从 webrtc-internals 中取出的300×140的图片要大的多的图表。
![\](http://www.ctiforum.com/uploadfile/2017/0122/20170122094133210.jpg)
这些图表是使用 HighCharts 库得到的,并且有很多十分方便的特性,比如隐藏线条,放大所需区域,或者停靠在特定点处并显示精确值。这比用 JSON 转储(像上面一样)要方便的多。
回到基础的 webrtc-internals 页中。在此页顶端,我们可以考到一系列的表单,一个是给getUserMedia调用的,剩下的两个分别给每个 RTCPeerConnection。
![\](http://www.ctiforum.com/uploadfile/2017/0122/20170122094332295.jpg)
在 GetUserMedia 请求表单中,我们可以看到每次的 getUserMedia 调用,以及相关约束。不幸的是,我们不能看到结果或者 MediaStreams 中有的 ids。
RTCPeerConnection 数据
对于每个peerconnection,我们可以看到这四点:
- RTCPeerConnection 是如何配置的,也就是 STUN 和 TURN 服务器是如何被使用的,以及如何配置
- PeerConnection API 的轨迹被调用显示在左边。这些 API 轨迹展现了所有的RTCPeerConnection 调用和他们的参数(例如createOffer),以及回调和类似于 onicecandidate 的事件触发器
- 从 getStats() API 采集的数据在右侧被显示出来
- 由 getStats() API 产生的图表在底部显示
RTCPeerConnection API 轨迹是非常强大的工具,可以帮助你完成很多的事情,比如分析造成 ICE 失败的原因,或者帮你找到适合部署 TURN 服务器的地方。我们会在以后的博文中来谈这些。
webrtc-internals 所给出的统计数据是 Chrome 的内部格式。这意味着其与目前的规范略有不同步,一些名称和结构体会有改变。在较高层,我们在 webrtc-internals 页上看到的与我们调用这个函数所得到的结果相近:
![\](http://www.ctiforum.com/uploadfile/2017/0122/20170122094929520.jpg)
下面是 RTCStatsReport 对象的队列,其中有很多秘钥和数值,可以这样读取:
![\](http://www.ctiforum.com/uploadfile/2017/0122/20170122095149748.jpg)
要记住的是在这些统计数据和规范之间有一些区别。这里面有一个经验法则,任意一个名称以 “Id” 结尾的秘钥都包含一个指向不同的报告,其 id 属性与秘钥的值对应。所以全部这些报告都是彼此相连的。还要注意,这些值都是字符型的,尽管它们看起来像布尔值那样的数字。
RTCStatsReport 中最重要的属性是报告的种类,下面是其中的几种:
- googTrack
- googLibjingleSession
- googCertificate
- googComponent
- googCandidatePare
- localCandidate
- remoteCandidate
- ssrc
- VideoBWE
让我们来深入探讨一下这些报告型
googTrack 与 googLibjingleSession 报告- googTrack 和 googLibjingleSession 没包含什么信息,所以我们跳过它不做分析。
- googCertificate 报告
- googCertificate 报告包括了一些有关近端和对等端所使用的 DTLS 证书的信息,以及指纹和哈希算法。这些都在 RTCCertificateStats 字典中有详细说明。
googComponent 报告的作用就像是认证数据与连接之间的胶水。它包含了一个纸箱当前活跃的候选项对的指针,以及有关用语 DTLS 和 SRTP 加密的加密套接字。
googCandidatePair 报告
googCandidatePair 对一对 ICE 候选做了描述,也就是低层次的连接。从这个报告中,你可以得到这些信息:
- 发送和接收的数据包以及字节数总数( bytesSent,bytesReceived,packetsSent;因为不明原因丢失的 packetsReceived )。这是一个包含 RTP 报头的 UDP 或者 TCP字节。
- 如何判断这是否是一个活跃的连接,googActiveConnection 的值是真则为活跃,否则为假。大多数时间你都会只对活跃的候选对感兴趣。对等的规范可以在这里找到。
- 被发送和接收的 STUN 请求和应答数量是计算在 ICE 进程中输入和输出的 STUN 请求数量。
- googRtt 是最新的 STUN 请求的往返时间。这与 ssrc 报告上的 googRtt 是不一样的,我们稍后会说。
- localCandidateId 和 remoteCandidateId 指向 localCandidate 型和 remoteCandidate型。localCandidate 和 remoteCandidate 描述了本地和远端的ICE候选项。你可以在googLocalAddress 型上面找到绝大多数信息。
- googTr 以及 googLocalCandidateType 的值。
- googTransportType 规定了传输的类型。注意这些数据的值通常是 “udp” 的,即便是在 TCP 上的 TURN 被用于连接 TURN 服务器的情况下。只有当 ICE-TCP 被使用时,此值才会是 “tcp” 的。
从下面这张图上可以比较直观地看到一些数据,如发送和接收的字节数等等:
![\](http://www.ctiforum.com/uploadfile/2017/0122/20170122095238231.jpg)
- localCandidate 和 remoteCandidate 与规范中所描述的是一模一样的,告诉我们 ip 地址,端口号,以及候选项的类型。对于 TURN 候选来说,其会告诉我们候选被分配在哪个端口上了。
Ssrc 报告
ssrc 报告是这里面最重要的报告之一。每一个音频或者视频轨道发送或接收都有一个 ssrc 报告。在旧版本的规范中,这些叫做 MediaStreamTrackStats 和 RTPStreamStats 。其内容决定于这是音频还是视频轨道,以及这是发送还是接收。让我们先来描述下一些其中基本的元素:
- mediaType 表示我们在观察的是音频数据还是视频数据
- ssrc 属性指定了媒体是发送ssrc还是接收
- googTrackId 会识别这些数据描述的轨迹。这个 id 可以在 SDP 中,以及本地或远端媒体流轨道中被找到。事实上,这违背了以 “ Id ” 为后缀的命名法则,通常以 “ Id ” 结束的都是一个指向其他报告的指针。Google 把 goog stats 给搞错了。
- googRtt 表示的是往返时间。与之前说过的往返时间不同,这个往返时间是从 RTCP 测量的时间。
- transportId,是指向被用于传送 RTP 流的部分。通常用于音频和视频流的 transportId 是一样的。
- googCodecName 规定了编译码器的名称。典型的音频编解码器是 opus,对于视频来说,使用的是 VP8,VP9 或者使用 H264。你还可以看到在 codecImplementationName 统计数据中使用的实施方案的有关信息。
- bytesSent,bytesReceived,packetsSent 以及 packetsReceived 的值可以让你计算出总的字节数。这些数字是累加的,所以你需要在你最后一次询问 getStats 之后要将其按时间分开。规定中的示例代码写的还不错,单是要注意 Chrome 有事会将这些计数器重置,所以你有可能得到一个负数的速率。
- packetsLost 让你知道有多少包在传输过程中丢失了。对于发送端来说,丢包来自 RTCP,对于接收端来说,丢包是在本地测量的。当你在检查一个质量不好的通话时,这个参数可能是你想要查看的最直接的数据。
音频特性
对于音轨来说,我们有 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 计数器都会增加。
我们可以从这张图表上看到这些变化:
![\](http://www.ctiforum.com/uploadfile/2017/0122/20170122095347833.jpg)
这里的丢包是人为产生的。作为反应,Chrome 在 t=184 时第一次尝试降低分辨率,这是绿线代表的 googFrameWidthSent 开始偏离黑线代表的 googFrameWidthInput。接下来在 t=186 时,框架开始下降,输入框架速率(浅蓝色线条所示)大约是 30fps,与发出的框架速率(蓝色线条所示)产生区别,后者几乎是 0.
另外,Chrome 在 ssrc 报告中公开了大量关于音频和视频堆栈的表现的数据。我们会在未来的博文中进行讨论。
VideoBWE 报告
最后,但并不是不重要,我们来分析一下 VideoBWE 报告。就像它名字所表达的,它包括有关带宽估计的信息。但是还有一些其他的有用信息包含在这个报告里:
- googAvailableReceiveBandwidth — 对于接收视频数据可用的带宽。
- googAvailableSendBandwidth — 对于发送视频数据可用的带宽。
- googTargetEncBitrate — 视频编码器的目标比特率。这项指标会尝试填满可用的带宽。
- googActualEncBitrate — 视频编码器输出的比特率。通常这与目标比特率是匹配的。
- googTansmitBitrate — 这个比特率是实际传输的比特率。如果此数值与实际编码比特率有较大的差别,那么可能是因为前向错误纠正造成的。
- googRetransmitBitrate — 如果RTX被使用的话,这项允许测量重传的比特率。此数据通常代表丢包率。
- googBucketDelay — 是Google为了处理大框架速率的策略表示。通常是很小的数值。
正如你看到的,这个报告会给你视频质量最重要的信息—可用带宽。查看发送和接收的可用带宽通常都是在深入分析 ssrc 报告之前做的最重要的事。因为有时你可能会发现这样的情况,这解释了用户所抱怨的 “质量差”:
![\](http://www.ctiforum.com/uploadfile/2017/0122/20170122095437460.jpg)
在这种情况下,“ 在所有时间里,带宽估计都在下降 ” 是对质量问题的一个比较好的解释。
原文链接:http://testrtc.com/webrtc-internals-parameters/
原文链接:http://testrtc.com/webrtc-internals-parameters/