前端視頻直播技術總結及videojs在h5頁面中的應用
目前有一個需求是在移動端上內嵌h5實現點位的視頻直播,直播項目采用Vue編寫,后端主要輸出 RTMP 和 HLS 協議的直播流,本文主要總結一下整體開發的技術選型以及開發過程中的思考與學習總結。
流媒體是指采用流式傳輸方式在 Internet 上播放的媒體格式,例如音頻、視頻等多媒體文件。
流式傳輸方式是將多媒體文件經過特殊壓縮后分成一個個壓縮包,再由服務器向客戶端連續、實時傳送。用戶不必像非流式傳輸那樣等待整個文件全部下載完畢后才能播放,而是只需要經過幾秒鐘或幾十秒的啟動延時即可對壓縮的音視頻文件進行播放,剩余的部分將繼續下載,直至播放完畢。
HTTP漸進式下載:僅能傳輸完整的音視頻文件,在給定時刻,用戶只能觀看已下載的那部分,而不能跳到還未下載的部分。HTTP邊下載邊播放,嚴格意義上講,不是直播協議。他的原理是先下載文件的基本信息,音頻視頻的時間戳,再下載音視頻數據,以播放mp4為例,先下載文件頭,根據文件頭指引下載文件尾,然后再下載文件的音視頻數據。
實時流媒體協議:可用于實況直播,也可傳輸完整的音視頻文件。例如RTSP/RTP、RTMP、HLS、HTTP-FLV。
既可以基于UDP傳輸也可以基于TCP傳輸,是純粹的傳輸控制協議,它本身與它負載的媒體數據不相關,RTSP協議需要自定義客戶端向服務器發送RTSP命令。其視頻數據由RTP傳輸,視頻質量由RTCP控制,視頻控制(如播放、暫停等)由RTSP提供。
協議比較全能,既可以用來推送,又可以用來直播。其核心理念是將大塊的視頻幀和音頻幀“剁碎”,然后以小數據包的形式在互聯網上進行傳輸,且支持加密,因此隱私性相對比較理想,但拆包組包的過程比較復雜,所以在海量并發時容易出現一些不可預期的穩定性問題。
蘋果推出的解決方案,將視頻分成 5-10 秒的視頻小分片,然后用 M3U8 索引表進行管理。由于客戶端下載到的視頻都是 5-10 秒的完整數據,故視頻的流暢性很好,但也同樣引入了很大的延遲(HLS 的一般延遲在 10-30s 左右)。相比于 FLV,HLS 在iPhone 和大部分 Android 手機瀏覽器上的支持非常給力,所以常用于 QQ 和微信朋友圈的 URL 分享。
由 Adobe 公司主推,格式極其簡單,只是在大塊的視頻幀和音視頻頭部加入一些標記頭信息,由于這種極致的簡潔,在延遲表現和大規模并發方面都很成熟。唯一的不足就是在手機瀏覽器上的支持非常有限,但是用作手機端 APP 直播協議卻異常合適。
如果用一句話描述整體過程,其實就是直播時,主播端將直播流推向服務器,用戶端發起請求從服務器拉視頻流過來解碼播放,流程如下圖所示:
為了增強額外效果,對音頻進行混音、降噪等處理,可為視頻打上時間戳、添加Logo水印或增加濾鏡;
隨后對音頻、視頻進行編碼,通過編碼壓縮滿足其在互聯網上實時傳輸的需求;
編碼后就可以把各種多媒體內容(視頻、音頻、字幕等)盛放在同一個容器里,也就是所謂的封裝,使得不同多媒體內容可同步播放,與此同時還提供了索引;
第二部分就是流媒體服務器:負責把從第一部分接收到的流進行處理并分發給用戶。
流媒體服務器的主要功能是對流媒體內容進行采集(接收推流)、緩存、調度和傳輸播放(以流式協議實現用戶分發)。
這一部分其實就是我們前端需要實現的,如何在移動端的內嵌h5頁面中實現直播流的播放。所以我們只需要關注后端是通過什么協議給我們返回直播流以及我們如何有效的播放就可以了~
我的困惑:除了采用h5原生的video/video標簽,我們還能用什么插件實現視頻直播,不同插件之間有什么區別?
經過我暴風式搜索后找到三款常用并且支持實時流媒體播放的客戶端插件(hls.js、video.js、vue-video-player),下面我們一個個道來。
優點:包比較小,很純凈,UI可以根據自己的業務自行擴展,功能可以根據需求進行封裝,比較靈活,而且專業直播HLS協議流。
缺點:對于常規的通用性播放器沒有封裝好的UI,功能上也需要自己調API實現,協議單一,只支持HLS。
video.js是一個基于h5的網絡視頻播放器,支持h5視頻、現代流媒體格式(MP4、WebM、HLS、DASH等)以及YouTube、Vimeo,甚至連flash也支持(通過插件實現,后面會詳細說明),可在桌面端或移動端實現視頻播放。
優點:支持多種格式的流媒體播放,瀏覽器不支持時可實現優雅降級;專門有一套針對直播流的UI;插件機制強大,目前社區已有數百個皮膚和插件供下載;兼容性好,幾乎支持所有桌面及移動端的瀏覽器。
缺點:包比較大,實現hls直播的時候其實是內嵌了hls.js的代碼,由于封裝好UI和功能,使其不夠靈活,修改UI時需要通過插件實現。
傳輸協議——由于后端支持同時返回HLS協議和RTMP協議的直播流,結合考慮HLS協議的高延時問題和RTMP協議的兼容性問題,本項目決定采用向下兼容的方式實現,默認使用RTMP協議直播,當瀏覽器不支持時降級使用HLS協議播放。
直播插件——本項目基于Vue實現,并且業務邏輯為常規直播操作,無特殊需求,從開發效率、穩定性及兼容性出發,決定采用vue-video-player插件實現。
3、video.js插件擴展:當已有插件(video.js插件集合:)無法滿足需求時可對已有插件進行擴展或自行開發video.js插件
本文首先闡述了流媒體、流媒體傳輸方式、流媒體傳輸協議以及RTSP協議的概念;接著基于項目直播需求引出三種常用直播流協議RTMP、HLS、HTTP-FLV,并對三種協議進行了對比分析,為后續技術選型提供參考;然后根據通用直播原理描述了整個直播流數據傳輸的過程,從采集、處理、編碼、封裝到推流、分發與播放,表明前端的重點工作在最后一步即流媒體播放;隨后對常用的三款客戶端直播插件hls.js、video.js、vue-video-player進行說明,并分析了各自的優缺點;最后詳細總結了移動端內嵌h5實現視頻直播的編碼過程,包括技術選型、插件的安裝與引入、插件擴展、視頻直播關鍵代碼及最終的效果展示。
本項目中視頻直播方式的實現大大提高了前端的開發效率,并且保證了桌面端與移動端的兼容性,同時增強了用戶體驗,比傳統只使用一種協議的播放源更靈活,為通用直播需求提供解決方案。