此文章主旨爲了說明在無須修改ffmpeg任何源碼,以及修改編碼參數設置以及服務器、CDN配置,優化播放器便可達到1s延時效果。算法
關於rtmp直播流打開慢和延時大的問題,
不少人共識播放器在公網都在2-3s的延時是正常的,
前天一款播放器拉流rtmp,延時在1s,果斷去分析這個軟件
,發現他就是用了ffmpeg,而後和那款播放器提供者,聊
了下,想套點大概的思路,基本上沒套出啥,沒辦法只能本身動手
而後根據以往的經驗和羣裏幾位大神的建議下,說幹就幹,
花了一天的時間,終於從延時3s優化到了1s的延時,
不敢獨享,拿出來供你們參考。
如下的優化點以重到輕方式描述出來:緩存
一、rtmp直播流打開慢
avformat_find_stream_info(),
這個函數會花去主要的時間,
由於要作流的分析拆分等,
因此優化能夠重點從這個函數入手。
一種是設置probesize,這個設置爲FLAG_NOBUFFER
數據包不入緩衝區,用於分析不顯示,而且還能夠設置max_anlyze_duration2默認值
這塊能夠參考ijkplayer這塊的設置挺好;服務器
另外一種方法比較極端些
本身實現這個函數的功能,以替代avformat_find_stream_info接口,前提就是要知道你的
流的相關信息,通過測試這樣設置以後,僅耗時9ms左右,效果很明顯,具體作法就是
根據metadata信息,手動設置解碼參數,
針對264+aac的rtmp能夠考慮這種優化方案,這個效果比較明顯
具體能夠根據我的項目需求來取捨。網絡
二、第二個關於播放延時的問題,好比ffplay默認的幀率控制沒有追幀的策略,其實說白了
就是同步算法不夠好,在播放網絡流的時候,那麼若是網絡若是發生抖動,延時會累加。
這個就是羣裏一個哥們說這個1s延時效果可以出現多久的緣由,通過半個小時測試依然堅挺着。
優化策略就是調整幀率控制部分。具體作法就是
解碼線程運行的時候獲取機器本地時間,第一幀計算機器時間
與流pts的時間差(本地時間和流時間同步),
流的時間落後本地時間多的狀況下,快放或者考慮丟包
原則就是要在流暢度和實時性之間獲得一個平衡。框架
三、第三個優化的地方,須要優化緩存區,說白了就是通常的播放器都有本身的一個緩衝區,
那麼這個緩衝區存儲數據到獲取第一幀數據不能超過200ms,這個就是你要優化你的緩衝區,
每一個播放器的緩衝區實現方式不同,因此這個也很差具體表述,我這邊就是用的deque作的緩存區,
作的也比較簡單。函數
四、第四個優化的地方,就是視頻渲染這塊,渲染這塊優化,每一個人寫的不同,一樣使用opengl顯示,
每一個人寫的效率不同,這個就看我的功力了,不熟悉能夠看看qtav這塊的代碼,仍是不錯的;測試
五、第五個優化的地方,這個其實就是這個歌播放器的框架,以及數據直接的拷貝傳遞的效率等各類控制
都會影響最終的結果,這個也是說看我的的能力吧。優化
口說無憑,最後上圖證實一切,跑了半個小時,仍是很穩定(播放器觀看手機推流):編碼