1. 程式人生 > >WebRTC內建debug工具,詳細引數解讀 chrome://webrtc-internals/

WebRTC內建debug工具,詳細引數解讀 chrome://webrtc-internals/

為了確保這篇文章所寫內容儘可能的準確,我決定請來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/