1. 程式人生 > >直播技術總結(五)如何快速起播直播流

直播技術總結(五)如何快速起播直播流

經常會看到,很多公司都在頻寬和卡頓中抉擇,想把H.265編碼格式做為視訊編碼格式普及開來,用於客戶端播放,無論在TV上,還是手機上,由於很多裝置不支援這種編碼格式,所以往往要做適配。有人問,為什麼大家都在說切H.265?

H.265是ITU-T VCEG 繼H.264之後所制定的新的視訊編碼標準。H.265標準圍繞著現有的視訊編碼標準H.264,保留原來的某些技術,同時對一些相關的技術加以改進。新技術使用先進的技術用以改善碼流、編碼質量、延時和演算法複雜度之間的關係,達到最優化設定。具體的研究內容包括:提高壓縮效率、提高魯棒性和錯誤恢復能力、減少實時的時延、減少通道獲取時間和隨機接入時延、降低複雜度等。H264由於演算法優化,可以低於1Mbps的速度實現標清數字影象傳送;H265則可以實現利用1~2Mbps的傳輸速度傳送720P(解析度1280*720)普通高清音視訊傳送。

回到商業目的本質上來,就是省頻寬。在有限頻寬下傳輸更高質量的網路視訊。這就是相比於H.264最突出的。當然還有有些在演算法優化上,更高效。最終都是省頻寬。打個比方理解,原來10M頻寬,可以傳輸1T的網路視訊,現在用H.265編碼格式,可以傳輸2T的同等清晰度的網路視訊。要用H.265來做編碼格式,其代價就是裝置計算能力:H.265編碼的視訊需要更多的計算能力來解碼。所以,經常看到手機發燙,電視盒子發燒,手機更加耗電。因為會把CPU一下飆起來。前面都是閒話,今天總結下如何快速起播直播流。直播行業流傳一句話,現在的直播應用,沒有混到秒開,都不意思,說自己搞直播的。這句話不是沒有道理的。

對於直播來講,它是一個流,它不像點播,大家都從0秒開始,任何一個視訊檔案,0秒第一個幀肯定都是關鍵幀。那麼對於直播來講,是一個隨機的時間點接到這個視訊流進行播放,那麼我接入的這個時間點的幀有可能拿到的第一個幀的資料是I幀,也有可能是B幀,也有可能是P幀。這是一個隨機的。在這種情況下,我們大概率會出現一個黑屏的狀態。因為我拿到的是個P幀,對於P幀來講,解碼器面那個Buffer是空的,它不知道這個P幀如何進行解碼,所以它只能丟棄這個幀。

先來看一個花屏,解釋參考幀丟失,I幀是關鍵幀,一個完整畫面,可以獨立解碼,P幀,是前向預測編碼幀,可以理解為運動補償幀,根據關鍵幀+運動補償預測下一個關鍵幀。B幀,是雙向預測編碼幀,也是用來預測修補下一個I幀,所以B幀,P幀統稱為參考幀。如 I P P B I 如下

這裡寫圖片描述

視訊流是1080*1920解析度的。用1080*720的,沒有任何問題。猜測如下原因:

  • 同一種視訊封裝格式,解析度越小,花屏現象越少。
  • 解析度越小,服務端傳送給客戶端的資料越小,其花屏現象越少,說明花屏現象與服務端傳送的資料量有關。
  • 可能的原因是服務端傳送的資料量較大時,客戶端緩衝區不足,導致資料丟失的問題,從而引起花屏現象。

對於直播來講,我一秒鐘的幀數是固定的,只能等到我下一個關鍵幀到來的時候,我才能開始去播放。當然正好趕巧了的話,接入那瞬間得到的資料正好是個I幀。就可以達到秒開的效果。

服務端優化,CDN 預快取 GOP,以高倍速推送,縮短I幀等待時間:

  • 在直播伺服器中,支援設定一個cache,用於存放GOP(就是I/P/B組起來的),客戶端播放。
    直播伺服器快取了當前的GOP序列,當播放端請求資料的時候,CDN會從I幀返回給客戶端,從而保證客戶端可以快速獲取I 幀進行顯示;當然,由於快取的是之前的視訊資訊,當音訊資料到達播放端後,為了音視訊同步,播放器會進行視訊的快進處理(也就是趕上,據說百度視訊雲,在~“趕上”~這塊,還專門寫了專利),但這種影響很小;相比於能夠達到“秒開”的效果,這個代價是值得的;

播放端優化:

  • DNS解析加快,通常,DNS解析,意味著要把一個域名為xxx.com解析成ip過程,平時請求網頁,網路差,就會開啟網頁半天。
  • 修改播放器邏輯,基於FFmpeg二次開發,FFmpeg起播視訊,都是拿到視訊完整資訊,才起播。能不不能只拿到部分資訊,就起播。就要修改程式碼了。通常FFmpeg起播時,finder_decoder, avformat_find_stream_info較耗時,前者去找解碼器,相對後者,又不那麼耗時,凡事都有相對。在avformat.h宣告。在libavformat\utils.c中實現如下:

    finder_decoder:


    這裡寫圖片描述

    avformat_find_stream_info:

    這裡寫圖片描述

    這裡優化後者,主要修改兩個引數,一個是 probesize,一個是 analyzeduration,分別用來控制其讀取的資料量大小和時長。減少 probesize 和 analyzeduration 可以降低avformat_find_stream_info 的函式耗時,達到起播快。

如果是基於ijkplayer二次開發的,不用修改c層,直接在ijkVideoView.java中,也可以作相應修改。


這裡寫圖片描述

注意:修改任何引數,都是有代價的,要視具體情況。這個值修改,大小,可能播不起來,這種情況就坑了,如果是先有畫面,在有聲音,音畫不同步。

還有一些方法如,播放端識別首個關鍵幀即啟動播放,或者通過減小GOP間隔來提高載入速度;也是可以達到的。

優化是一個漸進的過程,從表面顯而易見的開始,逐步拆解流程,找到可能的優化點,對這些點逐個分析,找到效能瓶頸,然後想辦法解決。當然優化有時也需要權衡代價和效果,重點先解決價效比比較高的優化點。

第一時間獲得部落格更新提醒,以及更多android乾貨,原始碼分析,歡迎關注我的微信公眾號,掃一掃下方二維碼或者長按識別二維碼,即可關注。

這裡寫圖片描述
如果你覺得好,隨手點贊,也是對筆者的肯定,也可以分享此公眾號給你更多的人,原創不易