您當(dāng)前的位置是:  首頁 > 新聞 > 國內(nèi) >
 首頁 > 新聞 > 國內(nèi) >

WebRTC內(nèi)置debug 工具詳細(xì)參數(shù)解讀

2017-01-22 09:30:51   作者:Levent-Levi 翻譯:劉通   來源:CTI論壇   評論:0  點(diǎn)擊:


\  
  為了確保這篇文章所寫內(nèi)容盡可能的準(zhǔn)確,我決定請來Philipp Hancke 來作為此篇文章的共同作者。
  當(dāng)你想要找到你 WebRTC 產(chǎn)品中的問題時(shí),webrtc-internals 是一個(gè)非常棒的工具,因?yàn)槟阈枰盟鼫y試 WebRTC 以及 debug,或者你需要對你的配置進(jìn)行微調(diào)。
  如何獲得 webrtc-internals 的數(shù)據(jù)轉(zhuǎn)儲(chǔ)( stats dump ) 
\
  如果你對這個(gè)工具不熟悉的話,那么打開你 Chrome 瀏覽器里的 WebRTC 段,在這段里打開另一個(gè)表單并且將其指向這個(gè)內(nèi)部( internal )URL:chrome://webrtc-internals/
  webrtc-internals 允許將軌道作為大型的 JSON 下載下來,這樣你就可以一層一層地來看它了,但是當(dāng)你這么做的時(shí)候,你會(huì)看到類似這樣的東西:
\
  查看webrtc-internals數(shù)據(jù) 
  人們通常問到的第一件事是—這些數(shù)字到底代表什么?我們自己的一位測試人員將這些值放入時(shí)序圖表里并且將其輸出出來。這就給了我們要比直接從 webrtc-internals 中取出的300×140的圖片要大的多的圖表。
\
  這些圖表是使用 HighCharts 庫得到的,并且有很多十分方便的特性,比如隱藏線條,放大所需區(qū)域,或者?吭谔囟c(diǎn)處并顯示精確值。這比用 JSON 轉(zhuǎn)儲(chǔ)(像上面一樣)要方便的多。
  回到基礎(chǔ)的 webrtc-internals 頁中。在此頁頂端,我們可以考到一系列的表單,一個(gè)是給getUserMedia調(diào)用的,剩下的兩個(gè)分別給每個(gè) RTCPeerConnection。
\
  在 GetUserMedia 請求表單中,我們可以看到每次的 getUserMedia 調(diào)用,以及相關(guān)約束。不幸的是,我們不能看到結(jié)果或者 MediaStreams 中有的 ids。
  RTCPeerConnection 數(shù)據(jù) 
  對于每個(gè)peerconnection,我們可以看到這四點(diǎn):
  • 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ù)器的地方。我們會(huì)在以后的博文中來談這些。
  webrtc-internals 所給出的統(tǒng)計(jì)數(shù)據(jù)是 Chrome 的內(nèi)部格式。這意味著其與目前的規(guī)范略有不同步,一些名稱和結(jié)構(gòu)體會(huì)有改變。在較高層,我們在 webrtc-internals 頁上看到的與我們調(diào)用這個(gè)函數(shù)所得到的結(jié)果相近:
\
  下面是 RTCStatsReport 對象的隊(duì)列,其中有很多秘鑰和數(shù)值,可以這樣讀。
\
  要記住的是在這些統(tǒng)計(jì)數(shù)據(jù)和規(guī)范之間有一些區(qū)別。這里面有一個(gè)經(jīng)驗(yàn)法則,任意一個(gè)名稱以 “Id” 結(jié)尾的秘鑰都包含一個(gè)指向不同的報(bào)告,其 id 屬性與秘鑰的值對應(yīng)。所以全部這些報(bào)告都是彼此相連的。還要注意,這些值都是字符型的,盡管它們看起來像布爾值那樣的數(shù)字。
  RTCStatsReport 中最重要的屬性是報(bào)告的種類,下面是其中的幾種:
  • googTrack
  • googLibjingleSession
  • googCertificate
  • googComponent
  • googCandidatePare
  • localCandidate
  • remoteCandidate
  • ssrc
  • VideoBWE
  讓我們來深入探討一下這些報(bào)告型 
  googTrack 與 googLibjingleSession 報(bào)告
  • googTrack 和 googLibjingleSession 沒包含什么信息,所以我們跳過它不做分析。
  • googCertificate 報(bào)告
  • googCertificate 報(bào)告包括了一些有關(guān)近端和對等端所使用的 DTLS 證書的信息,以及指紋和哈希算法。這些都在 RTCCertificateStats 字典中有詳細(xì)說明。
  googComponent 報(bào)告
  googComponent 報(bào)告的作用就像是認(rèn)證數(shù)據(jù)與連接之間的膠水。它包含了一個(gè)紙箱當(dāng)前活躍的候選項(xiàng)對的指針,以及有關(guān)用語 DTLS 和 SRTP 加密的加密套接字。
  googCandidatePair 報(bào)告
  googCandidatePair 對一對 ICE 候選做了描述,也就是低層次的連接。從這個(gè)報(bào)告中,你可以得到這些信息:
  • 發(fā)送和接收的數(shù)據(jù)包以及字節(jié)數(shù)總數(shù)( bytesSent,bytesReceived,packetsSent;因?yàn)椴幻髟騺G失的 packetsReceived )。這是一個(gè)包含 RTP 報(bào)頭的 UDP 或者 TCP字節(jié)。
  • 如何判斷這是否是一個(gè)活躍的連接,googActiveConnection 的值是真則為活躍,否則為假。大多數(shù)時(shí)間你都會(huì)只對活躍的候選對感興趣。對等的規(guī)范可以在這里找到。
  • 被發(fā)送和接收的 STUN 請求和應(yīng)答數(shù)量是計(jì)算在 ICE 進(jìn)程中輸入和輸出的 STUN 請求數(shù)量。
  • googRtt 是最新的 STUN 請求的往返時(shí)間。這與 ssrc 報(bào)告上的 googRtt 是不一樣的,我們稍后會(huì)說。
  • localCandidateId 和 remoteCandidateId 指向 localCandidate 型和 remoteCandidate型。localCandidate 和 remoteCandidate 描述了本地和遠(yuǎn)端的ICE候選項(xiàng)。你可以在googLocalAddress 型上面找到絕大多數(shù)信息。
  • googTr 以及 googLocalCandidateType 的值。
  • googTransportType 規(guī)定了傳輸?shù)念愋。注意這些數(shù)據(jù)的值通常是 “udp” 的,即便是在 TCP 上的 TURN 被用于連接 TURN 服務(wù)器的情況下。只有當(dāng) ICE-TCP 被使用時(shí),此值才會(huì)是 “tcp” 的。
  從下面這張圖上可以比較直觀地看到一些數(shù)據(jù),如發(fā)送和接收的字節(jié)數(shù)等等:
\
  localCandidate 和 remoteCandidate 報(bào)告
  • localCandidate 和 remoteCandidate 與規(guī)范中所描述的是一模一樣的,告訴我們 ip 地址,端口號,以及候選項(xiàng)的類型。對于 TURN 候選來說,其會(huì)告訴我們候選被分配在哪個(gè)端口上了。
  Ssrc 報(bào)告
  ssrc 報(bào)告是這里面最重要的報(bào)告之一。每一個(gè)音頻或者視頻軌道發(fā)送或接收都有一個(gè) ssrc 報(bào)告。在舊版本的規(guī)范中,這些叫做 MediaStreamTrackStats 和 RTPStreamStats 。其內(nèi)容決定于這是音頻還是視頻軌道,以及這是發(fā)送還是接收。讓我們先來描述下一些其中基本的元素:
  • mediaType 表示我們在觀察的是音頻數(shù)據(jù)還是視頻數(shù)據(jù)
  • ssrc 屬性指定了媒體是發(fā)送ssrc還是接收
  • googTrackId 會(huì)識(shí)別這些數(shù)據(jù)描述的軌跡。這個(gè) id 可以在 SDP 中,以及本地或遠(yuǎn)端媒體流軌道中被找到。事實(shí)上,這違背了以 “ Id ” 為后綴的命名法則,通常以 “ Id ” 結(jié)束的都是一個(gè)指向其他報(bào)告的指針。Google 把 goog stats 給搞錯(cuò)了。
  • googRtt 表示的是往返時(shí)間。與之前說過的往返時(shí)間不同,這個(gè)往返時(shí)間是從 RTCP 測量的時(shí)間。
  • transportId,是指向被用于傳送 RTP 流的部分。通常用于音頻和視頻流的 transportId 是一樣的。
  • googCodecName 規(guī)定了編譯碼器的名稱。典型的音頻編解碼器是 opus,對于視頻來說,使用的是 VP8,VP9 或者使用 H264。你還可以看到在 codecImplementationName 統(tǒng)計(jì)數(shù)據(jù)中使用的實(shí)施方案的有關(guān)信息。
  • bytesSent,bytesReceived,packetsSent 以及 packetsReceived 的值可以讓你計(jì)算出總的字節(jié)數(shù)。這些數(shù)字是累加的,所以你需要在你最后一次詢問 getStats 之后要將其按時(shí)間分開。規(guī)定中的示例代碼寫的還不錯(cuò),單是要注意 Chrome 有事會(huì)將這些計(jì)數(shù)器重置,所以你有可能得到一個(gè)負(fù)數(shù)的速率。
  • packetsLost 讓你知道有多少包在傳輸過程中丟失了。對于發(fā)送端來說,丟包來自 RTCP,對于接收端來說,丟包是在本地測量的。當(dāng)你在檢查一個(gè)質(zhì)量不好的通話時(shí),這個(gè)參數(shù)可能是你想要查看的最直接的數(shù)據(jù)。
  音頻特性
  對于音軌來說,我們有 audioInputLevel 和 audioOutputLevel(在規(guī)范中叫做 audioLevel )可以告訴我們音頻信號是來與麥克風(fēng),還是通過揚(yáng)聲器播出的。這個(gè)特性可以用來探測 Chrome 里不受歡迎的音頻 bug。我們還可以通過 googJitterReceived 和 googJitterBufferReceived 得知有多少抖動(dòng)被接收,以及 jitter buffer 的狀態(tài)。
  視頻特性
  對于視頻軌道來說,我們有兩大信息需要關(guān)注。第一個(gè)是被送入 googNacksSent,googPLIsSent 和 googFirsSent 中,NACK,PLI 和 FIR 數(shù)據(jù)包的數(shù)量差別。這可以讓我們知道丟包會(huì)如何影響視頻質(zhì)量。
  更重要的是,我們得知了框架大小和速率是作為輸入( googFrameWidthInput,googFrameHeightInput,googFrameRateInput )并且實(shí)時(shí)上是發(fā)送到網(wǎng)絡(luò)之上( googFrameWidthSent,googFrameHeightSent,googFrameRateSent )。
  相似的數(shù)據(jù)可以在接收端被收集到存在 googFrameWidthReceived,googFrameHeightReceived 中。對于框架速率來說我們甚至可以將其從 googFrameRateReceived,googFrameRateDecoded 和 GOOGFrameRateOutput 中分開來。
  在編碼端我們可以看到這些值之間的差別,還能知道為什么圖片會(huì)被縮小。通常這些事情發(fā)生不是因?yàn)闆]有足夠大的 CPU,就是沒有足夠大的帶寬來傳送完整的圖片。另外,想要降低框架速率( 其可以從對比 googFrameRateInput 和 googFrameRateSent 之間的差距得到),我們需要得到額外的信息:分辨率是否因?yàn)?CPU 的問題而得到適應(yīng),以及是否是因?yàn)閹挷粔蚴沟?googBandwidthLimitedResolution 的值是真。無論是上述哪個(gè)情況發(fā)生了改變,googAdaptionChanges 計(jì)數(shù)器都會(huì)增加。
  我們可以從這張圖表上看到這些變化:
\
  這里的丟包是人為產(chǎn)生的。作為反應(yīng),Chrome 在 t=184 時(shí)第一次嘗試降低分辨率,這是綠線代表的 googFrameWidthSent 開始偏離黑線代表的 googFrameWidthInput。接下來在 t=186 時(shí),框架開始下降,輸入框架速率(淺藍(lán)色線條所示)大約是 30fps,與發(fā)出的框架速率(藍(lán)色線條所示)產(chǎn)生區(qū)別,后者幾乎是 0.
  另外,Chrome 在 ssrc 報(bào)告中公開了大量關(guān)于音頻和視頻堆棧的表現(xiàn)的數(shù)據(jù)。我們會(huì)在未來的博文中進(jìn)行討論。
  VideoBWE 報(bào)告
  最后,但并不是不重要,我們來分析一下 VideoBWE 報(bào)告。就像它名字所表達(dá)的,它包括有關(guān)帶寬估計(jì)的信息。但是還有一些其他的有用信息包含在這個(gè)報(bào)告里:
  • googAvailableReceiveBandwidth — 對于接收視頻數(shù)據(jù)可用的帶寬。
  • googAvailableSendBandwidth — 對于發(fā)送視頻數(shù)據(jù)可用的帶寬。
  • googTargetEncBitrate — 視頻編碼器的目標(biāo)比特率。這項(xiàng)指標(biāo)會(huì)嘗試填滿可用的帶寬。
  • googActualEncBitrate — 視頻編碼器輸出的比特率。通常這與目標(biāo)比特率是匹配的。
  • googTansmitBitrate — 這個(gè)比特率是實(shí)際傳輸?shù)谋忍芈。如果此?shù)值與實(shí)際編碼比特率有較大的差別,那么可能是因?yàn)榍跋蝈e(cuò)誤糾正造成的。
  • googRetransmitBitrate — 如果RTX被使用的話,這項(xiàng)允許測量重傳的比特率。此數(shù)據(jù)通常代表丟包率。
  • googBucketDelay — 是Google為了處理大框架速率的策略表示。通常是很小的數(shù)值。
  正如你看到的,這個(gè)報(bào)告會(huì)給你視頻質(zhì)量最重要的信息—可用帶寬。查看發(fā)送和接收的可用帶寬通常都是在深入分析 ssrc 報(bào)告之前做的最重要的事。因?yàn)橛袝r(shí)你可能會(huì)發(fā)現(xiàn)這樣的情況,這解釋了用戶所抱怨的 “質(zhì)量差”:
\
  在這種情況下,“ 在所有時(shí)間里,帶寬估計(jì)都在下降 ” 是對質(zhì)量問題的一個(gè)比較好的解釋。
  原文鏈接:http://testrtc.com/webrtc-internals-parameters/

專題