
當(dāng)你想要找到你 WebRTC 產(chǎn)品中的問題時,webrtc-internals 是一個非常棒的工具,因為你需要用它測試 WebRTC 以及 debug,或者你需要對你的配置進(jìn)行微調(diào)。
如何獲得 webrtc-internals 的數(shù)據(jù)轉(zhuǎn)儲( stats dump )

如果你對這個工具不熟悉的話,那么打開你 Chrome 瀏覽器里的 WebRTC 段,在這段里打開另一個表單并且將其指向這個內(nèi)部( internal )URL:chrome://webrtc-internals/
webrtc-internals 允許將軌道作為大型的 JSON 下載下來,這樣你就可以一層一層地來看它了,但是當(dāng)你這么做的時候,你會看到類似這樣的東西:

查看webrtc-internals數(shù)據(jù)
人們通常問到的第一件事是—這些數(shù)字到底代表什么?我們自己的一位測試人員將這些值放入時序圖表里并且將其輸出出來。這就給了我們要比直接從 webrtc-internals 中取出的300×140的圖片要大的多的圖表。

這些圖表是使用 HighCharts 庫得到的,并且有很多十分方便的特性,比如隱藏線條,放大所需區(qū)域,或者停靠在特定點處并顯示精確值。這比用 JSON 轉(zhuǎn)儲(像上面一樣)要方便的多。
回到基礎(chǔ)的 webrtc-internals 頁中。在此頁頂端,我們可以考到一系列的表單,一個是給getUserMedia調(diào)用的,剩下的兩個分別給每個 RTCPeerConnection。

在 GetUserMedia 請求表單中,我們可以看到每次的 getUserMedia 調(diào)用,以及相關(guān)約束。不幸的是,我們不能看到結(jié)果或者 MediaStreams 中有的 ids。
RTCPeerConnection 數(shù)據(jù)
對于每個peerconnection,我們可以看到這四點:
- RTCPeerConnection 是如何配置的,也就是 STUN 和 TURN 服務(wù)器是如何被使用的,以及如何配置
- PeerConnection API 的軌跡被調(diào)用顯示在左邊。這些 API 軌跡展現(xiàn)了所有的RTCPeerConnection 調(diào)用和他們的參數(shù)(例如createOffer),以及回調(diào)和類似于 onicecandidate 的事件觸發(fā)器
- 從 getStats() API 采集的數(shù)據(jù)在右側(cè)被顯示出來
- 由 getStats() API 產(chǎn)生的圖表在底部顯示
RTCPeerConnection API 軌跡是非常強(qiáng)大的工具,可以幫助你完成很多的事情,比如分析造成 ICE 失敗的原因,或者幫你找到適合部署 TURN 服務(wù)器的地方。我們會在以后的博文中來談這些。
webrtc-internals 所給出的統(tǒng)計數(shù)據(jù)是 Chrome 的內(nèi)部格式。這意味著其與目前的規(guī)范略有不同步,一些名稱和結(jié)構(gòu)體會有改變。在較高層,我們在 webrtc-internals 頁上看到的與我們調(diào)用這個函數(shù)所得到的結(jié)果相近:

下面是 RTCStatsReport 對象的隊列,其中有很多秘鑰和數(shù)值,可以這樣讀取:

要記住的是在這些統(tǒng)計數(shù)據(jù)和規(guī)范之間有一些區(qū)別。這里面有一個經(jīng)驗法則,任意一個名稱以 “Id” 結(jié)尾的秘鑰都包含一個指向不同的報告,其 id 屬性與秘鑰的值對應(yīng)。所以全部這些報告都是彼此相連的。還要注意,這些值都是字符型的,盡管它們看起來像布爾值那樣的數(shù)字。
RTCStatsReport 中最重要的屬性是報告的種類,下面是其中的幾種:
- googTrack
- googLibjingleSession
- googCertificate
- googComponent
- googCandidatePare
- localCandidate
- remoteCandidate
- ssrc
- VideoBWE
讓我們來深入探討一下這些報告型
googTrack 與 googLibjingleSession 報告- googTrack 和 googLibjingleSession 沒包含什么信息,所以我們跳過它不做分析。
- googCertificate 報告
- googCertificate 報告包括了一些有關(guān)近端和對等端所使用的 DTLS 證書的信息,以及指紋和哈希算法。這些都在 RTCCertificateStats 字典中有詳細(xì)說明。
googComponent 報告的作用就像是認(rèn)證數(shù)據(jù)與連接之間的膠水。它包含了一個紙箱當(dāng)前活躍的候選項對的指針,以及有關(guān)用語 DTLS 和 SRTP 加密的加密套接字。
googCandidatePair 報告
googCandidatePair 對一對 ICE 候選做了描述,也就是低層次的連接。從這個報告中,你可以得到這些信息:
- 發(fā)送和接收的數(shù)據(jù)包以及字節(jié)數(shù)總數(shù)( bytesSent,bytesReceived,packetsSent;因為不明原因丟失的 packetsReceived )。這是一個包含 RTP 報頭的 UDP 或者 TCP字節(jié)。
- 如何判斷這是否是一個活躍的連接,googActiveConnection 的值是真則為活躍,否則為假。大多數(shù)時間你都會只對活躍的候選對感興趣。對等的規(guī)范可以在這里找到。
- 被發(fā)送和接收的 STUN 請求和應(yīng)答數(shù)量是計算在 ICE 進(jìn)程中輸入和輸出的 STUN 請求數(shù)量。
- googRtt 是最新的 STUN 請求的往返時間。這與 ssrc 報告上的 googRtt 是不一樣的,我們稍后會說。
- localCandidateId 和 remoteCandidateId 指向 localCandidate 型和 remoteCandidate型。localCandidate 和 remoteCandidate 描述了本地和遠(yuǎn)端的ICE候選項。你可以在googLocalAddress 型上面找到絕大多數(shù)信息。
- googTr 以及 googLocalCandidateType 的值。
- googTransportType 規(guī)定了傳輸?shù)念愋汀W⒁膺@些數(shù)據(jù)的值通常是 “udp” 的,即便是在 TCP 上的 TURN 被用于連接 TURN 服務(wù)器的情況下。只有當(dāng) ICE-TCP 被使用時,此值才會是 “tcp” 的。
從下面這張圖上可以比較直觀地看到一些數(shù)據(jù),如發(fā)送和接收的字節(jié)數(shù)等等:

- localCandidate 和 remoteCandidate 與規(guī)范中所描述的是一模一樣的,告訴我們 ip 地址,端口號,以及候選項的類型。對于 TURN 候選來說,其會告訴我們候選被分配在哪個端口上了。
Ssrc 報告
ssrc 報告是這里面最重要的報告之一。每一個音頻或者視頻軌道發(fā)送或接收都有一個 ssrc 報告。在舊版本的規(guī)范中,這些叫做 MediaStreamTrackStats 和 RTPStreamStats 。其內(nèi)容決定于這是音頻還是視頻軌道,以及這是發(fā)送還是接收。讓我們先來描述下一些其中基本的元素:
- mediaType 表示我們在觀察的是音頻數(shù)據(jù)還是視頻數(shù)據(jù)
- ssrc 屬性指定了媒體是發(fā)送ssrc還是接收
- googTrackId 會識別這些數(shù)據(jù)描述的軌跡。這個 id 可以在 SDP 中,以及本地或遠(yuǎn)端媒體流軌道中被找到。事實上,這違背了以 “ Id ” 為后綴的命名法則,通常以 “ Id ” 結(jié)束的都是一個指向其他報告的指針。Google 把 goog stats 給搞錯了。
- googRtt 表示的是往返時間。與之前說過的往返時間不同,這個往返時間是從 RTCP 測量的時間。
- transportId,是指向被用于傳送 RTP 流的部分。通常用于音頻和視頻流的 transportId 是一樣的。
- googCodecName 規(guī)定了編譯碼器的名稱。典型的音頻編解碼器是 opus,對于視頻來說,使用的是 VP8,VP9 或者使用 H264。你還可以看到在 codecImplementationName 統(tǒng)計數(shù)據(jù)中使用的實施方案的有關(guān)信息。
- bytesSent,bytesReceived,packetsSent 以及 packetsReceived 的值可以讓你計算出總的字節(jié)數(shù)。這些數(shù)字是累加的,所以你需要在你最后一次詢問 getStats 之后要將其按時間分開。規(guī)定中的示例代碼寫的還不錯,單是要注意 Chrome 有事會將這些計數(shù)器重置,所以你有可能得到一個負(fù)數(shù)的速率。
- packetsLost 讓你知道有多少包在傳輸過程中丟失了。對于發(fā)送端來說,丟包來自 RTCP,對于接收端來說,丟包是在本地測量的。當(dāng)你在檢查一個質(zhì)量不好的通話時,這個參數(shù)可能是你想要查看的最直接的數(shù)據(jù)。
音頻特性
對于音軌來說,我們有 audioInputLevel 和 audioOutputLevel(在規(guī)范中叫做 audioLevel )可以告訴我們音頻信號是來與麥克風(fēng),還是通過揚聲器播出的。這個特性可以用來探測 Chrome 里不受歡迎的音頻 bug。我們還可以通過 googJitterReceived 和 googJitterBufferReceived 得知有多少抖動被接收,以及 jitter buffer 的狀態(tài)。
視頻特性
對于視頻軌道來說,我們有兩大信息需要關(guān)注。第一個是被送入 googNacksSent,googPLIsSent 和 googFirsSent 中,NACK,PLI 和 FIR 數(shù)據(jù)包的數(shù)量差別。這可以讓我們知道丟包會如何影響視頻質(zhì)量。
更重要的是,我們得知了框架大小和速率是作為輸入( googFrameWidthInput,googFrameHeightInput,googFrameRateInput )并且實時上是發(fā)送到網(wǎng)絡(luò)之上( googFrameWidthSent,googFrameHeightSent,googFrameRateSent )。
相似的數(shù)據(jù)可以在接收端被收集到存在 googFrameWidthReceived,googFrameHeightReceived 中。對于框架速率來說我們甚至可以將其從 googFrameRateReceived,googFrameRateDecoded 和 GOOGFrameRateOutput 中分開來。
在編碼端我們可以看到這些值之間的差別,還能知道為什么圖片會被縮小。通常這些事情發(fā)生不是因為沒有足夠大的 CPU,就是沒有足夠大的帶寬來傳送完整的圖片。另外,想要降低框架速率( 其可以從對比 googFrameRateInput 和 googFrameRateSent 之間的差距得到),我們需要得到額外的信息:分辨率是否因為 CPU 的問題而得到適應(yīng),以及是否是因為帶寬不夠使得 googBandwidthLimitedResolution 的值是真。無論是上述哪個情況發(fā)生了改變,googAdaptionChanges 計數(shù)器都會增加。
我們可以從這張圖表上看到這些變化:

這里的丟包是人為產(chǎn)生的。作為反應(yīng),Chrome 在 t=184 時第一次嘗試降低分辨率,這是綠線代表的 googFrameWidthSent 開始偏離黑線代表的 googFrameWidthInput。接下來在 t=186 時,框架開始下降,輸入框架速率(淺藍(lán)色線條所示)大約是 30fps,與發(fā)出的框架速率(藍(lán)色線條所示)產(chǎn)生區(qū)別,后者幾乎是 0.
另外,Chrome 在 ssrc 報告中公開了大量關(guān)于音頻和視頻堆棧的表現(xiàn)的數(shù)據(jù)。我們會在未來的博文中進(jìn)行討論。
VideoBWE 報告
最后,但并不是不重要,我們來分析一下 VideoBWE 報告。就像它名字所表達(dá)的,它包括有關(guān)帶寬估計的信息。但是還有一些其他的有用信息包含在這個報告里:
- googAvailableReceiveBandwidth — 對于接收視頻數(shù)據(jù)可用的帶寬。
- googAvailableSendBandwidth — 對于發(fā)送視頻數(shù)據(jù)可用的帶寬。
- googTargetEncBitrate — 視頻編碼器的目標(biāo)比特率。這項指標(biāo)會嘗試填滿可用的帶寬。
- googActualEncBitrate — 視頻編碼器輸出的比特率。通常這與目標(biāo)比特率是匹配的。
- googTansmitBitrate — 這個比特率是實際傳輸?shù)谋忍芈省H绻藬?shù)值與實際編碼比特率有較大的差別,那么可能是因為前向錯誤糾正造成的。
- googRetransmitBitrate — 如果RTX被使用的話,這項允許測量重傳的比特率。此數(shù)據(jù)通常代表丟包率。
- googBucketDelay — 是Google為了處理大框架速率的策略表示。通常是很小的數(shù)值。
正如你看到的,這個報告會給你視頻質(zhì)量最重要的信息—可用帶寬。查看發(fā)送和接收的可用帶寬通常都是在深入分析 ssrc 報告之前做的最重要的事。因為有時你可能會發(fā)現(xiàn)這樣的情況,這解釋了用戶所抱怨的 “質(zhì)量差”:

在這種情況下,“ 在所有時間里,帶寬估計都在下降 ” 是對質(zhì)量問題的一個比較好的解釋。
原文鏈接:http://testrtc.com/webrtc-internals-parameters/
原文鏈接:http://testrtc.com/webrtc-internals-parameters/