WebRTC Internals

1. 概览介绍

打开 Chrome 浏览器,在地址栏输入chrome://webrtc-internals 即可打开调试工具,进入后可以看到类似的页面

image.png

1.1 Create Dump 保存日志

数据包含所有 PeerConnection 涉及到的信息,可供后续问题复盘。

1.2 读取状态日志

WebRTC 读取状态日志的2种标准,两种标准之间存在较大的差异。

  • Standardized:符合W3C的新标准,其代码调用是基于 Promise
  • Legacy Non-Standard:废弃的 google 定义的旧标准,基代码调用是基于 callback
// Standardized 
pc.getStats().then(stats => console.log(stats)) 
// Legacy Non-Standard 
pc.getStats(stats => console.log(stats))

1.3 GetUserMedia

是浏览器获取摄像头和麦克风媒体流的接口,GetUserMedia Request 的 Tab 中可以看到近期调用该API的记录,以及调用参数,有关 getUserMedia 的基本使用。每条记录都会包括:调用的域名、调用时间、音频约束、视频约束,如图:

image.png

navigator.mediaDevices 接口提供访问连接媒体输入的设备,如照相机和麦克风,以及屏幕共享等

  • mediaDevices 上提供了4个方法和一个监听事件

  • enumerateDevices: 获取系统可用的媒体输入和输出设备

  • getSupportedConstraints: 返回一个输入设备可支持的约束属性

  • getDisplayMedia: 开启屏幕共享

  • getUserMedia: 开启媒体输入设备

2. RTCPeerConnection 监控信息详解

可以看到除了GetUserMedia Requests,还有其他的Tab,这些每一个Tab都对应了一个 PeerConnection对象,打开后又可以分为4部分:

image.png

2.1 构造 PeerConnection 的参数

这一部分可以看到我们在构造 PeerConnection的 参数,这个参数是传入参数与默认参数的合并后的结果,PeerConnection 的构造函数详情可以参考 MDN

2.2 PeerConnection 的操作与事件

这里按照时间顺序记录了对 PeerConnection 的一些操作和回调事件

操作

  • createOffer、createAnswer:生成 offer 和 answer,点击展开后可以看到调用参数(参数同样是合并后的值)
  • setLocalDescription、setRemoteDescription: 设置的 local sdp 和 remote sdp,展开后可以看到详情
  • addIceCandidate:将对端的 candidate 添加到 PeerConnection 中

回调事件

  • createOfferOnSuccess、createAnswerOnSuccess:由于 createOffer 和 createAnswer 是异步的,所以这里显示了调用成功之后的结果
  • setLocalDescriptionOnSuccess、setRemoteDescriptionOnSuccess:同样 setLocalDescription 和setRemoteDescription 也是异步的,这里表明是正确调用(也会有调用Failed的情况)
  • signalingstatechange:信令状态的回调,信令状态是调用 setLocalDescription、setRemoteDescription 等API的结果,具体变化情况可以参考下图(信令状态同样重要,比如在'stable'的状态是不能直接设置remote sdp)
image.png

信令状态变化这里可能有点绕,但是如果像下图这样,设置时序或者任何SDP设置的问题可以很明显地看到

image.png
  • icecandidate:收集本地的 candidate,收集动作一般是 setLocalDescription 后由 WebRTC 内部自动完成,然后由回调抛到 JS 层
  • iceconnectionstatechange:ICE 的连接状态发生变化,具体可以参考MDN
  • connectionstatechange:PeerConnection的连接状态发生变化,具体可以参考MDN

2.3 流数据(数值格式 & 图表格式)

这里可以真正的可以看到上行、下行的流数据,其中可以重点观注以下4行(上下连接部分分别的数值和图表格式,其含义和数据源是一致的):

  • inbound-rtp:下行数据,可以分为音频和视频
  • outbound-rtp:上行数据,可以分为音频和视频


    image.png

2.3.1 audio outbound-rtp/remote-inbound-rtp

image.png
  • Kind: audio
  • SSRC: 2840249774 和sdp的mline相对应
  • bytesSent_in_bits/s:上行码率,音频一般在30k左右(静音后会减半),该值并不直接体现在getStats的返回值中,而是需要两次stats计算得出:码率 = (delta bytesSent) / (delta timestamp)
  • packetsSent/s: 每秒发送的数据包 同理是由计算得出
  • retransmittedPacketsSent: 重传包
  • packetsLost:丢包,除以发送的总包数可以得到丢包率
image.png
image.png
  • packetsLost:丢包,除以发送的总包数可以得到丢包率
const deltaLost = currentLost - prevLost; 
const deltaSent = (currentPacketsSent + currentLost) - (prevPacketsSent + prevLost); 
const lostRate = deltaLost / deltaSent; 
  • roundTripTime: 单位是秒

2.3.2 video outbound-rtp/remote-inbound-rtp

视频上行和音频类似,可以重点关注以下几个字段:

image.png

ssrc、codec、packetsSent、bytesSent_in_bit/s这些和音频统计一致

  • frameWidth: 上行视频宽度
  • frameHeight: 上行视频高度

同样可以对应的remote-inbound-rtp里看到远端接收的情况来计算丢包率和roundTripTime

image.png

2.3.3 audio inbound-rtp、video inbound-rtp

这里代表下行数据,大体和outbound-rtp类似,只是这里会包含丢包、audioLevel等数据

3. 实战问题分析

3.1 收到画面模糊

一般发生成通话刚建立时,下图是一个码率比较大的视频上行数据,可以看到刚开始有个明显爬坡的过程,这是因为WebRTC刚建立连接时并不知道网络状况如何,会一点点放开上行的码率,以确保视频的流畅,所以对端刚开始接收的是比较模糊的画面,这个属于正常现象。

image.png

如果在通话中画面模糊一直未恢复,可能是发送端网络比较差,或者采集码率极大,但是限制了 RTC 的上行码率,限制码率可以查看sdp 中是否有b=AS:行,或者如果是通过sender来限制可以通过 transceiverModified 事件来确定是否有maxBitrate的限制

3.2 拉流画面黑屏

需要查看 video 的 inbound-rtp 的下行码率是否有值,如果有值可以排查渲染的问题,如果无值的话,可以查看下发流方的码率,排除发流方发送异常。如果也正常的话需要服务器排查问题。

3.3 拉流无声

需要查看 audio 的 inbound-rtp 接收的 audioLevel 和 totalAudioEnergy,audioLevel 由 totalAudioEnergy 计算得出,值在 [0, 1] 之间,正常说话应该在 0.1 以上

image.png

在实际应用中可能会遇到各种各样的问题,比如打开通话Demo页面开始通话,查看audioLevel是正常有值的,但是如果在开始通话前在控制台输入:

Array(50).fill(0).forEach(() => new AudioContext()); 
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 225,565评论 6 525
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 96,696评论 3 406
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 172,935评论 0 370
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 61,327评论 1 303
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 70,338评论 6 401
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 53,760评论 1 316
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 42,085评论 3 431
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 41,091评论 0 280
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 47,656评论 1 327
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 39,657评论 3 348
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 41,767评论 1 355
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 37,360评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 43,088评论 3 341
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 33,493评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 34,654评论 1 278
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 50,374评论 3 383
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 46,841评论 2 367