为了确保这篇文章所写内容尽可能的准确,我决定请来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,我们可以在这里看到这四点:

  1. RTCPeerConnection是如何配置的,也就是STUN和TURN服务器是如何被使用的,以及如何配置
  2. PeerConnection API的轨迹被调用显示在左边。这些API轨迹展现了所有的RTCPeerConnection调用和他们的参数(例如createOffer),以及回调和类似于onicecandidate的事件触发器
  3. 从getStats() API采集的数据在右侧被显示出来
  4. 由getStats() API产生的图表在底部显示

RTCPeerConnection API轨迹是非常强大的工具,可以帮助你完成很多的事情,比如分析造成ICE失败的原因,或者帮你找到适合部署TURN服务器的地方。我们会在以后的博文中来谈这些。

webrtc-internals所给出的统计数据是Chrome的内部格式。这意味着其与目前的规范略有不同步,一些名称和结构体会有改变。在较高层,我们在webrtc-internals页上看到的与我们调用这个函数所得到的结果相近:

下面是RTCStatsReport对象的队列,其中有很多秘钥和数值,可以这样读取:

要记住的是在这些统计数据和规范之间有一些区别。这里面有一个经验法则,任意一个名称以“Id”结尾的秘钥都包含一个指向不同的报告,其id属性与秘钥的值对应。所以全部这些报告都是彼此相连的。还要注意,这些值都是字符型的,尽管它们看起来像布尔值那样的数字。

RTCStatsReport中最重要的属性是报告的种类,下面是其中的几种:

  • googTrack
  • googLibjingleSession
  • googCertificate
  • googComponent
  • googCandidatePare
  • localCandidate
  • remoteCandidate
  • ssrc
  • VideoBWE

让我们来深入探讨一下这些报告型

googTrack与googLibjingleSession报告

googTrack和googLibjingleSession没包含什么信息,所以我们跳过它不做分析。

googCertificate报告

googCertificate报告包括了一些有关近端和对等端所使用的DTLS证书的信息,以及指纹和哈希算法。这些都在RTCCertificateStats字典中有详细说明。

googComponent报告

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”的。

从下面这张图上可以比较直观地看到一些数据,如发送和接收的字节数等等:

localCandidate和remoteCandidate报告

感谢上天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计数器都会增加。

我们可以从这张图表上看到这些变化:

这里的丢包是人为产生的。作为反应,Chrome在t=184时第一次尝试降低分辨率,这是绿线代表的googFrameWidthSent开始偏离黑线代表的googFrameWidthInput。接下来在t=186时,框架开始下降,输入框架速率(浅蓝色线条所示)大约是30fps,与发出的框架速率(蓝色线条所示)产生区别,后者几乎是0.

另外,Chrome在ssrc报告中公开了大量关于音频和视频堆栈的表现的数据。我们会在未来的博文中进行讨论。

  • VideoBWE报告

最后,但并不是不重要,我们来分析一下VideoBWE报告。就像它名字所表达的,它包括有关带宽估计的信息。但是还有一些其他的有用信息包含在这个报告里:

  • googAvailableReceiveBandwidth—对于接收视频数据可用的带宽。
  • googAvailableSendBandwidth—对于发送视频数据可用的带宽。
  • googTargetEncBitrate—视频编码器的目标比特率。这项指标会尝试填满可用的带宽。
  • googActualEncBitrate—视频编码器输出的比特率。通常这与目标比特率是匹配的。
  • googTansmitBitrate—这个比特率是实际传输的比特率。如果此数值与实际编码比特率有较大的差别,那么可能是因为前向错误纠正造成的。
  • googRetransmitBitrate—如果RTX被使用的话,这项允许测量重传的比特率。此数据通常代表丢包率。
  • googBucketDelay—是Google为了处理大框架速率的策略表示。通常是很小的数值。

正如你看到的,这个报告会给你视频质量最重要的信息—可用带宽。查看发送和接收的可用带宽通常都是在深入分析ssrc报告之前做的最重要的事。因为有时你可能会发现这样的情况,这解释了用户所抱怨的“质量差”:

在这种情况下,“在所有时间里,带宽估计都在下降”是对质量问题的一个比较好的解释。

原作者:Levent-Levi

翻译:刘通

原文链接:http://testrtc.com/webrtc-internals-parameters/

WebRTC内置debug工具,详细参数解读 chrome://webrtc-internals/的更多相关文章

  1. spring hystrix和内置tomcat组件的参数调优解析

    1. springboot内置tomcat容器的参数配置 server: port: 12021 # server端的socket超时间(毫秒),使用值-1表示没有(即无限)超时,默认值为60000( ...

  2. sql server 内置ETL工具学习(一) BCP篇

    sql server 内置ETL工具学习 常用的导入方式:bcp, BULK INSERT,OPENROWSET和 SSIS. BCP BCP全称BULK COPY PROGRAM 有以下特点: 命令 ...

  3. 几个可以提高工作效率的Python内置小工具

    在这篇文章里,我们将会介绍4个Python解释器自身提供的小工具.这些小工具在笔者的日常工作中经常用到,减少了各种时间的浪费,然而,却很容易被大家忽略.每当有新来的同事看到我这么使用时,都忍不住感叹, ...

  4. python面向对象的基础语法(dir内置函数、self参数、初始化方法、内置方法和属性)

    面相对象基础语法 目标 dir 内置函数 定义简单的类(只包含方法) 方法中的 self 参数 初始化方法 内置方法和属性 01. dir 内置函数(知道) 在 Python 中 对象几乎是无所不在的 ...

  5. python 内置2to3工具将python2代码转换为python3代码

    python2与python3代码不兼容,如果需要python2代码在python3环境下运行,需要将代码进行转换,本文介绍使用python3内置工具2to3.py对代码进行转换 一:2to3.py在 ...

  6. Jdk内置性能测试工具的介绍

    (一) JConsole JConsole使用JVM的可扩展性Java管理扩展(JMX)工具来提供关于运行于Java平台的应用程序的性能和资源消耗的信息. 在J2SE 5.0软件中,你需要启动使用-D ...

  7. Python 内置logging 使用详细讲

    logging 的主要作用 提供日志记录的接口和众多处理模块,供用户存储各种格式的日志,帮助调试程序或者记录程序运行过程中的输出信息. logging 日志等级 logging 日志等级分为五个等级, ...

  8. Node.js内置的工具和第三方模块来进行单步调试

    1.命令行调试: Node.js调试命令: run 执行脚本,在第一行暂停 restart 重新执行脚本 cont,c 继续执行,知道遇到下一个断点 next,n 单步执行 step,s 单步执行,并 ...

  9. Mysql内置优化工具show profiles

    一.概述: Mysql的explain工具目前还没有Oracle的explain plan工具那么强大,但是结合show profiles工具可以实现相似的效果.show profiles语句用于在当 ...

随机推荐

  1. 部署tomcat到Linux

    1. alt+p   放文件 2.解压到自定义 apps文件夹中 tar -zxvf apache-tomcat-7.0.68.tar.gz -C apps 3.进入文件启动tomcat/bin ./ ...

  2. MySQL Transaction--RC和RR区别

    在MySQL中,事务隔离级别RC(read commit)和RR(repeatable read)两种事务隔离级别基于多版本并发控制MVCC(multi-version concurrency con ...

  3. MySQL--限制用户使用资源

    在MySQL 5.7及后续版本中,可以按照账号来限制每个账号实际具有的资源限制. 语法: GRANT WITH option, 如: GRANT SELECT ON test.* TO user1@l ...

  4. day20 python sys os time json pickl 正则

    字符组 : [字符组] 在同一个位置可能出现的各种字符组成了一个字符组,在正则表达式中用[]表示 字符分为很多类,比如数字.字母.标点等等. 假如你现在要求一个位置....9这10个数之一. 量词 几 ...

  5. JS 网页键盘钩子

    使用write技术把脚本和代码写入文件,即使查看原文及也无法看到原代码,下面是具体的代码,直接保存就可以运行============================================== ...

  6. python安装途中遇到的问题和解决方法

    一.setuptools安装错误:RuntimeError: Compression requires the (missing) zlib module 1. 描述 搞了个腾讯云的服务器,闲在手上没 ...

  7. 【转】每天一个linux命令(24):Linux文件类型与扩展名

    原文网址:http://www.cnblogs.com/peida/archive/2012/11/22/2781912.html Linux文件类型和Linux文件的文件名所代表的意义是两个不同的概 ...

  8. js 逻辑的短路运算

    && 与运算 同时为true,才为true: 表达式1为false,不用看表达式2: || 或运算 有一个为true,就为true: 表达式1为true,不用看表达式2: && ...

  9. golang panic的捕获

    panic发生时, 会导致进程挂掉.为了处理panic, 可以使用recover捕获,然后处理. 下面以下标引用越界问题为例进行说明. 正常情况下,代码中如果出现下标越界,会直接触发panic, 导致 ...

  10. Linux Home目录硬盘空间缩减

    Linux Home目录硬盘空间缩减 操作   基于centos6.5 x86_64, runlevel 3,命令行模式,测试成功. 1.首先查看磁盘使用情况 [root@localhost ~]# ...