天天看點

丢棄RTMP協定的FLASH視訊直播方案所踩過的坑

很久沒有寫部落格了,最近一直在忙FLASH直播相關的事情,終于完成了階段性工作。先描述下我們的FLASH方案。我們主要用FLASH在浏覽器展示實時遊戲直播視訊,視訊可以除了可以再WEB上觀看,也可以在語音用戶端觀看和手機觀看。開始我們采用基本的FLASH FMS/RTMP方式。測試下來有以下幾個問題:

1、上傳和觀看必須用FLASH,RTMP和FLASH本身很多細節無法掌控。

2、帶寬問題,FLASH編碼的視訊帶寬過大,視訊品質相同的情況下640P的分辨率(70 ~ 90KB/S)與用X264應用程式編碼(35 ~ 55KB/S)的同分辨率相比帶寬大30KB/S,這是不能接受的。

3、傳輸RTMP承載過于呆闆和複雜,無法根據實時直播進行優化。

4、其他一些FLASH FMS上的問題。例如:嚴格時間戳問題、語音丢包問題、延遲問題等。

測試下來,無法跟我們現有的語音視訊應用軟體做很好的相容。經過讨論後,我們采用私有協定傳輸,前端用FLASH做展示。利用FLASH的TCP和FLV做一個仿應用程式的WEB用戶端。總體方案描述如下:

1.實時上傳視訊通過語音用戶端進行,用戶端用X264和HEAAC進行進行媒體編碼,通過私有的網絡協定上傳到媒體伺服器上。

2.媒體伺服器實作語音和視訊分離傳輸,為什麼要分離傳輸呢?語音為了防止延遲,采用的是UDP方式傳輸,允許丢包,也可以采用語音特有的QOS算法進行控制;視訊采用RUDP方式傳輸,不允許丢包,盡量減少延遲。分離傳輸還有一個好處就是可以根據語音和視訊帶寬特性調配具體的機房帶寬。

3、設計一個falsh gate服務來耦合WEB FLASH的接入。在這個網關上實作語音和視訊的合并、協定轉譯、FLASH的接入協定實作、FLASH的私有協定QOS保證、減少播放緩沖等待等。

4、實作一個WEB FLASH播放器。主要實作私有協定的接入、FLV緩沖播放、多路媒體管理、視訊JITTER BUFFER/語音JITTER BUFFER、核心C的子產品嵌入(SWC方式)、語音視訊同步、QOS評估和路線選擇、斷線重連等。

下圖是整個流資料的走向圖:

丢棄RTMP協定的FLASH視訊直播方案所踩過的坑

整個方案大概用了1個月實作,期間遇到了很多坑。如下:

1、在初期的實作的版本中,視訊在FLASH端感覺很卡,沒有丢包,在模拟用戶端中是完全正常的。我們檢視FLV播放的幀,發現隻有5幀被播放。後來我檢視編碼器中的參數,發現在640P分辨率下用了H264的B幀編碼,從測試模拟程式來看,FLASH好像不支援B幀。把B幀去掉,進行測試,正常了。

2、視訊分包問題,在我們的用戶端傳輸網絡中,為了相容P2P,我們将一幀視訊資料以4K大小進行分包。因為資料包是直接透傳到FLASH PLAYER上,必須在FLASH SWC中做組包。開始一直因為組包方式不對,FLV播放無圖像或者出現馬賽克。後來嚴格調整時間戳群組包算法,正常了。時間戳一定要嚴格對齊,至少在FLV播放前是這樣的。

3、語音疊幀問題,我們采用HEAAC進行編碼,1秒鐘會産生22 ~ 23幀資料,在用戶端為了減少UDP封包的數量,采用了3幀疊成一個語音封包,這樣時間戳在封包中是最後一幀資料的時間戳,在FLASH播放端處理的時候,開始以最後時間戳進行播放,聲音很鈍。後來進行測試和問題查找,發現在時間戳上,進行時間戳完全校驗,收到一個語音包後進行拆幀,第一幀的時間戳是TS - 2*44,第二幀的時間戳是TS - 44,第三幀是TS。進行測試,完全正常了。

4、語音采樣率的坑,我們在用戶端都是采用48KHZ的雙聲道采樣編碼,在FLASH PLAYER FLV完全無法聽到聲音。後來查找FLASH支援的采用,才發現隻支援11KHZ,22KHZ,44.1KHZ采樣。但是我們的HEAAC中好像沒有支援44.1KHZ的采樣編碼。回過頭進行HEAAC的改造,把44.1KHZ的采用率編碼加上。進行測試,正常通過。

5、FLASH PLAYER播放器記憶體洩露問題。在長時間運作過程中,浏覽器的記憶體越來越大,開始毫無頭緒。後來經過仔細查找,發現是SWC(flash 嵌入C子產品)有記憶體洩露。用工具經常排查,修改對應FLASH 嵌入C中的記憶體洩露問題,進行測試,記憶體正常。

繼續閱讀