web flash rtmp_基于RTMP和WebRTC开发大规模低延迟(1000毫秒内)直播系统
問題
隨著移動設備大規模的普及以及流量的資費越來越便宜, 超低延遲的場景越來越多. 從去年到今年火過的場景就有在線娃娃機, 直播答題, 在線K歌等. 但要做到音視頻的超低延遲確是很不容易, 編碼延遲, 網絡丟包, 網絡抖動, 多節點relay,視頻分段傳輸,播放端緩存等等都會帶來延遲.
WebRTC興起提供的方案以及遇到的問題
WebRTC技術的興起為低延遲音視頻傳輸帶來了解決方案, 但WebRTC是為端到端設計的, 適合的場景是小規模內的實時互動, 例如視頻會議, 連麥場景. 即使加入了SFU Media server作為轉發服務器, 也很難做到大規模的分發. 另外一個需要考量的是流量成本, WebRTC的實時流量是通過UDP傳輸的(某些情況下可以用TCP), 無法復用在傳統CDN的架構之上, 實時的流量價格更是CDN流量的3倍以上, 部署一個超低延遲的直播網絡成本非常高.
RTMP系統推流播放延遲分析
一個經過優化的RTMP-CDN網絡端到端的延遲大概在2-3秒, 延遲大一些要在5秒甚至10秒以上. 從推流到播放, 會引入延遲的環節有編碼延遲, 網絡丟包和網絡抖動, 視頻的分段傳輸, 多媒體節點的relay, 播放器的緩存等等. 實際上除了網絡丟包和網絡抖動不太可控之外, 其他的各各環節都有一定的優化方案, 比如使用x264的-preset ultrafast和zerolatency, 可以降低編碼的延遲,
分段傳輸部分可以把GOP減少到1秒之內, 在播放器端可以適當減小buffer, 并設置一定的追幀策略, 防止過大的buffer引起的時延.
低成本的低延遲的實現
在RTMP直播系統中從推流端到網絡傳輸到播放器都做深度定制確實可以做到比較低的延遲, 但成本也是比較高的, 需要完備的高水平的團隊(服務端和客戶端), 以及大量的帶寬服務器資源. 如果想做到超低延遲(1000毫秒以內)更是難上加難, 而且這么低的延遲也會帶來一些負面的效果, 網絡出現少許抖動的時候就會出現卡頓等等. 有沒有更低成本的實現方案呢? 以及如何復用現有的CDN的基礎設施來做到低延遲? 其實我們可以在現有的RTMP-CDN系統上做一些優化調整, 在邊緣節點把RTMP流轉化為WebRTC可以播放的流來達到低延遲和CDN系統的復用, 同時還可以利用WebRTC抗丟包來優化最后一公里的觀看體驗. WebRTC在各個平臺上都有相應的SDK, 尤其是在瀏覽器內嵌, 可以極大的減少整個系統的開發, 升級, 維護成本, 達到打開瀏覽器就可以觀看的效果.
需要注意的問題
當然事情不可能那么完美, 讓RTMP和WebRTC可以很好的互通也需要做一些額外的工作:
1, RTMP推流端低延遲以及GOP大小
如果想做到低延遲, 我們需要在推流端盡可能的快, 同時RTMP-CDN一般都會有GOP cache, 會緩存最近的一個GOP, GOP太大是沒法做到低延遲的, 可以考慮把GOP設置在1秒. 這樣的好處還有一個就是在WebRTC播放端, 如果出現丟關鍵幀的情況可以快速回復. 在我們這個場景下WebRTC服務端會拒絕WebRTR的FIR信息, 通過下一個關鍵幀來解決關鍵幀丟失的問題.
2, RTMP源站以及邊緣站盡可能的不做任何緩存
在一個幀率為25FPS的直播流中, 緩存一幀就會增加40ms的延遲. 在我們這個場景下RTMP的源站和邊緣站除了做一些GOP cache外, 其他緩存要盡可能的小.3, 編碼器參數設置
WebRTC對H264的支持還沒有那么完美, 比如在chrome支持H264的baseline, main profile 以及high profile, firefox和safari目前支持baseline.
B幀的存在雖然可以降低一些帶寬占用確會引入更多的延遲, 不推薦使用. 經過測試H264的編碼參數選擇可以選擇為baseline level3.
4, PPS和SPS
在RTMP場景中通常我們只會在推流開始的時候加入PPS和SPS, 但WebRTC要求在每個關鍵幀前面都有PPS和SPS, 這個問題我們可以在推流的時候解決, 也可以在把RTMP轉成RTP的時候加入. 萬能的ffmpeg已經支持這個bitstream filter -- dump_extra, 謝謝ffmpeg讓音視頻開發者節省了那么多的時間.
5, 音頻轉碼
RTMP的協議規范中音頻支持pcma和pcmu, WebRTC也支持pcma和pcmu, 如果RTMP推流端推送的音視是pcma或者pcmu格式, 我們就不用轉碼了. 當然現實比較殘酷, 在RTMP體系中大多數廠商和開源項目只支持AAC, 這個時候我們需要對音頻做轉碼. 這樣的工作對于萬能的ffmpeg來說也只有一二十行代碼的事情, 再一次謝謝ffmpeg讓音視頻開發者節省了那么多的時間.(如果想學ffmpeg 可以購買大師兄的書<<FFmpeg從入門到精通>>)
6, 視頻轉封裝
視頻部分我們上邊提到盡可能的用H264 baseline, 這樣的話WebRTC支持也會比較好. 我們只需要把RTMP流轉封裝為RTP的流, 喂給相應的WebRTC mediaserver.
這部分可以借助FFmpeg或者gstreamer來完成.
如何落地
目前身邊完全沒有完全匹配的需求, 這個方案目前并沒有落地, 設想中的落地方式是, RTMP部分還是用現有的CDN, 自己部署WebRTC的邊緣節點, 根據訪問請求向CDN拉流.
需要開發的地方只有邊緣節點WebRTC media server部分, 這部分我們可以借助一些開源的media server然后再做一些業務上的開發. 支持rtp輸入的開源WebRTC mediaserver 有janus-gateway, medooze mediaserver.
Talk is cheap, show me the code. 我實現了一個RTMP推流WebRTC播放的原型實現, 在阿里云上測試延遲在1000ms以內, 經過一些優化可以把延遲降低到500ms以內.
完整的代碼在這里
我部署了一個測試版本網址在這里:https://rtmp-to-webrtc.dot.cc
總結
以上是生活随笔為你收集整理的web flash rtmp_基于RTMP和WebRTC开发大规模低延迟(1000毫秒内)直播系统的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 佛教术语:苦空无常无我
- 下一篇: java信息管理系统总结_java实现科