乾貨 | 蘇寧影片雲跨平臺播放器開發方案詳解

蘇寧影片雲發表於2019-01-16

乾貨 | 蘇寧影片雲跨平臺播放器開發方案詳解

作者:施靈凱。蘇寧雲音影片開發高階工程師;8年以上音影片開發經驗,目前專注於蘇寧雲影片播放器核心、SDK等領域的開發。SDK及核心產品應用於PP體育、PP影片等數百家行業客戶,累計覆蓋使用者超千萬。

從傳統的點播,到這幾年興起的直播和短影片,在客戶端層面都要用到播放器,那麼如何去打造一款播放器來滿足點播,直播,短影片三種場景的需求呢?

首先可能來講講技術選型,目前筆者所瞭解到的播放器開源方案有如下幾種:vlc,xbmc,ijkplayer,exoplayer,ffplay等,那麼哪種開源方案能夠滿足我們這邊的需求或者適合我們做二次開發呢?

答案是都不滿足。

因為隨著蘇寧影片雲業務的擴充套件,不同的客戶有越來越多合理但很特殊的需求出現,會導致基於現成的開源方案做的播放器功能擴充套件越來越難,維護的時間成本越來越大。作為雲服務商,要能及時響應並能最短時間完成客戶的各種合理需求,那就必須要打造一款完全自研的跨平臺播放器,也就是播放器的各種技術點都要Full Control。

下面先看一下播放器的框架圖:

乾貨 | 蘇寧影片雲跨平臺播放器開發方案詳解

如上圖一般所有的播放器的方案,都會有解封裝,資料包佇列,解碼,幀佇列,渲染等幾大模組,然後組成一套播放邏輯,大多數的播放器的功能實現也都大同小異。

寫到這裡,可能會有人認為既然都是大同小異,那寫這篇技術分享的文章,有啥價值?雖然播放器的邏輯是一樣的,但是不同業務、不同方案的具體做法還是有很大差異。

一、多樣化的解封裝模組

就比如說解封裝技術,一般的做法是直接採用ffmpeg解封裝,幾乎支援所有的主流媒體解封裝協議,雖然ffmpeg是足夠厲害,但是有兩種情況,是很難做支援的;

一種是基於點播HLS協議,本地硬碟快取ts資料(不是記憶體快取),另一種是基於P2P協議,從P2P核心拿媒體資料包。

基於點播HLS協議,本地硬碟快取ts資料:蘇寧影片雲實現了PrivateHLSDemuxer模組,就是從伺服器請求到的ts檔案資料首先下載到本地硬碟,然後從本地硬碟讀取ts檔案做解封裝。

為什麼要這樣做?

節省記憶體佔用,透過硬碟空間預快取更多的媒體資料,提高流暢率。

有些片源使用者回拖,replay的頻率較高,這種方案正好可以省去回拖,replay的時候,頻繁重複向伺服器發起ts檔案的資料請求,好處是可以降低伺服器頻寬消耗,同時減少客戶端的流量消耗。

基於P2P協議,從P2P核心拿媒體資料包:我們實現了ExternalDemuxer模組,這是一個開放式的模組,可以接入第三方私有的解封裝模組,例如基於第三方私有協議的或者基於P2P協議的,在資料來源層面增加了播放器的擴充套件性。

二、自研的跨平臺的渲染引擎

這兩年短影片開始火起來,各種眼花繚亂的特效濾鏡,很吸引人;所以在影片渲染模組,蘇寧影片雲自研了一套渲染引擎GPUImage。

首先宣告一下,這不是github開源的基於OC實現的iOS平臺的GPUImage;也是不是基於java實現的android平臺的GPUImage;這是完全基於C++實現的一套跨平臺的GPUImage渲染引擎,目前支援android和iOS。

優勢是用C++寫一套濾鏡,同時支援多平臺,省時省力,目前你能夠想到的各種濾鏡,蘇寧影片雲都有做支援,並且還支援全景VR;具體如何實現?篇幅有限,後續會再寫一篇博文細講。

三、不同的直播低延遲追幀策略

這幾年火得一塌糊塗的直播,一提直播就會想到低延遲,那麼就講講在播放器層面,蘇寧影片雲是怎麼去最佳化延遲的?

於rtmp的直播,只要網路有抖動或者卡頓,播放器端的累積延遲會逐步加大,所以網上有一堆技術分享的博文講直播最佳化延遲的,例如最直接的:清快取資料佇列。

這個方法確實可以短時間內降低延遲,但是強行跳幀,直播內容強行被跳過,嚴重影響體驗;而且,丟Gop裡面的B幀,非參考幀或者序列裡面最後幾個P幀等;或者丟部分音訊資料包,影片幀時間戳同步音訊來達到資料的加速消耗等;但是實際測下來,控制延遲的效果甚微;

那麼蘇寧影片雲的方案是什麼呢?

不丟任何資料,加速消耗音影片資料,其實就是傳統的倍數播放,只是這種配速播放策略是實時受控制的;播放端的延遲一般根據資料佇列的時長來統計,一般佇列時長0-4s,保持1.0倍速播放,4-8s,1.2倍倍速播放,8-16s,1.3倍倍速播放,>16s,1.5倍倍數播放;

透過實際測試,一般因網路抖動帶來的累積延遲最多在30s內收斂到4s內,並且微量的倍速播放,使用者其實無感知;難點是要控制好音畫同步,這樣做法的目的是時間戳不變,音訊pcm資料透過atempo filter做速率壓縮。

四、單路影片流多解析度碼流切換

那麼,如何實現無感知的觀看體驗?

為了提高使用者觀看的流暢度,蘇寧影片雲提出了要有單路流多解析度的需求場景,實現播放器層面做到無縫播放。

例如:

當使用者的網路狀態變差後,如果還是保持原來的碼流位元速率,快取消耗乾淨後,馬上就會卡頓,所以為了保證流暢,要向伺服器請求當前流的低位元速率低解析度的資料,因為大多數使用者,對卡頓的敏感度遠遠大於畫質。

那麼從播放邏輯上來講,蘇寧影片雲是怎麼處理的呢?

首先解封裝模組。檢測到資料包裡面有更新stream info的標誌,更新stream info資訊放到list裡面,在list裡面每個streaminfo,打上id標誌;並且向音訊和影片資料佇列裡面分別新增一個帶有reset decoder標誌的資料包。

資料包裡面攜帶streaminfo的id,解碼器讀到reset decoder資料包,根據攜帶的id,向解封裝模組的streaminfo list裡面拿到對應的stream info,然後reset decoder;同時音訊要reset resample模組,整個過程在播放觀看層面完全是無縫播放的體驗,是不是很簡單?

以上,是蘇寧影片雲播放器方案相比於開源方案做的一些針對需求場景和功能上的差異點。目前該套方案已成熟執行,並經過行業超過千萬級使用者量的大規模使用和最佳化。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31559352/viewspace-2563025/,如需轉載,請註明出處,否則將追究法律責任。

相關文章