前不久抽空對目前比較火的視頻直播,作了下研究與探索,瞭解其總體實現流程,以及探討移動端HTML5直播可行性方案。css
發現目前 WEB 上主流的視頻直播方案有 HLS 和 RTMP,移動 WEB 端目前以 HLS 爲主(HLS存在延遲性問題,也能夠藉助 video.js 採用RTMP),PC端則以 RTMP 爲主實時性較好,接下來將圍繞這兩種視頻流協議來展開H5直播主題分享。html
1. HTTP Live Streaming前端
HTTP Live Streaming(簡稱 HLS)是一個基於 HTTP 的視頻流協議,由 Apple 公司實現,Mac OS 上的 QuickTime、Safari 以及 iOS 上的 Safari 都能很好的支持 HLS,高版本 Android 也增長了對 HLS 的支持。一些常見的客戶端如:MPlayerX、VLC 也都支持 HLS 協議。
HLS 協議基於 HTTP,而一個提供 HLS 的服務器須要作兩件事:ios
瀏覽器使用的是 m3u8 文件。m3u8 跟音頻列表格式 m3u 很像,能夠簡單的認爲 m3u8 就是包含多個 ts 文件的播放列表。播放器按順序逐個播放,所有放完再請求一下 m3u8 文件,得到包含最新 ts 文件的播放列表繼續播,周而復始。整個直播過程就是依靠一個不斷更新的 m3u8 和一堆小的 ts 文件組成,m3u8 必須動態更新,ts 能夠走 CDN。一個典型的 m3u8 文件格式以下:nginx
#EXTM3U #EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=200000 gear1/prog_index.m3u8 #EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=311111 gear2/prog_index.m3u8 #EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=484444 gear3/prog_index.m3u8 #EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=737777 gear4/prog_index.m3u8
能夠看到 HLS 協議本質仍是一個個的 HTTP 請求 / 響應,因此適應性很好,不會受到防火牆影響。但它也有一個致命的弱點:延遲現象很是明顯。若是每一個 ts 按照 5 秒來切分,一個 m3u8 放 6 個 ts 索引,那麼至少就會帶來 30 秒的延遲。若是減小每一個 ts 的長度,減小 m3u8 中的索引數,延時確實會減小,但會帶來更頻繁的緩衝,對服務端的請求壓力也會成倍增長。因此只能根據實際狀況找到一個折中的點。git
對於支持 HLS 的瀏覽器來講,直接這樣寫就能播放了:github
<video src=」./bipbopall.m3u8″ height=」300″ width=」400″ preload=」auto」 autoplay=」autoplay」 loop=」loop」 webkit-playsinline=」true」></video>
注意:HLS 在 PC 端僅支持safari瀏覽器,相似chrome瀏覽器使用HTML5 video
標籤沒法播放 m3u8 格式,可直接採用網上一些比較成熟的方案,如:sewise-player、MediaElement、videojs-contrib-hls、jwplayer。web
2. Real Time Messaging Protocolchrome
Real Time Messaging Protocol(簡稱 RTMP)是 Macromedia 開發的一套視頻直播協議,如今屬於 Adobe。這套方案須要搭建專門的 RTMP 流媒體服務如 Adobe Media Server,而且在瀏覽器中只能使用 Flash 實現播放器。它的實時性很是好,延遲很小,但沒法支持移動端 WEB 播放是它的硬傷。
雖然沒法在iOS的H5頁面播放,可是對於iOS原生應用是能夠本身寫解碼去解析的, RTMP 延遲低、實時性較好。
瀏覽器端,HTML5 video
標籤沒法播放 RTMP 協議的視頻,能夠經過 video.js 來實現。瀏覽器
<link href=「http://vjs.zencdn.net/5.8.8/video-js.css」 rel=「stylesheet」> <video id=「example_video_1″ class=「video-js vjs-default-skin」 controls preload=「auto」 width=「640」 height=「264」 loop=「loop」 webkit-playsinline> <source src=「rtmp://10.14.221.17:1935/rtmplive/home」 type=‘rtmp/flv’> </video> <script src=「http://vjs.zencdn.net/5.8.8/video.js」></script> <script> videojs.options.flash.swf = ‘video.swf’; videojs(‘example_video_1′).ready(function() { this.play(); }); </script>
3. 視頻流協議HLS與RTMP對比
目前直播展現形式,一般以YY直播、映客直播這種頁面居多,能夠看到其結構能夠分紅三層:
① 背景視頻層
② 關注、評論模塊
③ 點贊動畫
而現行H5相似直播頁面,實現技術難點不大,其能夠經過實現方式分爲:
① 底部視頻背景使用video視頻標籤實現播放
② 關注、評論模塊利用 WebScoket 來實時發送和接收新的消息經過DOM 和 CSS3 實現
③ 點贊利用 CSS3 動畫
瞭解完直播形式以後,接下來總體瞭解直播流程。
3、直播總體流程
直播總體流程大體可分爲:
(web前端學習交流羣:328058344 禁止閒聊,非喜勿進!)
對於H5視頻錄製,可使用強大的 webRTC (Web Real-Time Communication)是一個支持網頁瀏覽器進行實時語音對話或視頻對話的技術,缺點是隻在 PC 的 Chrome 上支持較好,移動端支持不太理想。
注意:
雖然Google一直在推WebRTC,目前已有很多成型的產品出現,可是大部分移動端的瀏覽器還不支持 webRTC(最新iOS 10.0也不支持),因此真正的視頻錄製仍是要靠客戶端(iOS,Android)來實現,效果會好一些。
brew tap homebrew/nginx
② 執行安裝nginx-rtmp-module
brew install nginx-full –with-rtmp-module
2. nginx.conf配置文件,配置RTMP、HLS
查找到nginx.conf配置文件(路徑/usr/local/etc/nginx/nginx.conf),配置RTMP、HLS。
① 在http節點以前添加 rtmp 的配置內容:
② 在http中添加 hls 的配置
重啓nginx服務,瀏覽器中輸入 http://localhost:8080,是否出現歡迎界面肯定nginx重啓成功。
nginx -s reload
當服務器端接收到採集視頻錄製端傳輸過來的視頻流時,須要對其進行解析編碼,推送RTMP/HLS格式視頻流至視頻播放端。一般使用的常見編碼庫方案,如x264編碼、faac編碼、ffmpeg編碼等。
鑑於 FFmpeg 工具集合了多種音頻、視頻格式編碼,咱們能夠優先選用FFmpeg進行轉換格式、編碼推流。
1.安裝 FFmpeg 工具
brew install ffmpeg
2.推流MP4文件
視頻文件地址:/Users/gao/Desktop/video/test.mp4
推流拉流地址:rtmp://localhost:1935/rtmplive/home,rtmp://localhost:1935/rtmplive/home
//RTMP 協議流 ffmpeg -re -i /Users/gao/Desktop/video/test.mp4 -vcodec libx264 -acodec aac -f flv rtmp://10.14.221.17:1935/rtmplive/home //HLS 協議流 ffmpeg -re -i /Users/gao/Desktop/video/test.mp4 -vcodec libx264 -vprofile baseline -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -q 10 rtmp://10.14.221.17:1935/hls/test
注意:
當咱們進行推流以後,能夠安裝VLC、ffplay(支持rtmp協議的視頻播放器)本地拉流進行演示
3.FFmpeg推流命令
① 視頻文件進行直播
ffmpeg -re -i /Users/gao/Desktop/video/test.mp4 -vcodec libx264 -vprofile baseline -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -q 10 rtmp://192.168.1.101:1935/hls/test ffmpeg -re -i /Users/gao/Desktop/video/test.mp4 -vcodec libx264 -vprofile baseline -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -q 10 rtmp://10.14.221.17:1935/hls/test
② 推流攝像頭+桌面+麥克風錄製進行直播
ffmpeg -f avfoundation -framerate 30 -i 「1:0″ \-f avfoundation -framerate 30 -video_size 640x480 -i 「0」 \-c:v libx264 -preset ultrafast \-filter_complex ‘overlay=main_w-overlay_w-10:main_h-overlay_h-10′ -acodec libmp3lame -ar 44100 -ac 1 -f flv rtmp://192.168.1.101:1935/hls/test
更多命令,請參考:
FFmpeg處理RTMP流媒體的命令大全
FFmpeg經常使用推流命令
移動端iOS和 Android 都自然支持HLS協議,作好視頻採集端、視頻流推流服務以後,即可以直接在H5頁面配置 video 標籤播放直播視頻。
<video controls preload=「auto」 autoplay=「autoplay」 loop=「loop」 webkit-playsinline> <source src=「http://10.14.221.8/hls/test.m3u8″ type=「application/vnd.apple.mpegurl」 /> <p class=「warning」>Your browser does not support HTML5 video.</p> </video>
本文從視頻採集上傳,服務器處理視頻推流,以及H5頁面播放直播視頻一整套流程,具體闡述了直播實現原理,實現過程當中會遇到不少性能優化問題。
① H5 HLS 限制必須是H264+AAC編碼。② H5 HLS 播放卡頓問題,server 端能夠作好分片策略,將 ts 文件放在 CDN 上,前端可儘可能作到 DNS 緩存等。③ H5 直播爲了達到更好的實時互動,也能夠採用RTMP協議,經過video.js實現播放。