前不久抽空對目前比較火的視訊直播,做了下研究與探索,了解其整體實現流程,以及探討行動端HTML5直播可行性方案。
發現目前WEB 上主流的視訊直播方案有HLS 和RTMP,行動WEB 端目前以HLS 為主(HLS有延遲性問題,也可以藉助video.js 採用RTMP),PC端則以RTMP 為主即時性較好,接下來將圍繞這兩種視訊串流協定來展開H5直播主題分享。
一、視訊串流協定HLS與RTMP 1. HTTP Live StreamingHTTP Live Streaming(簡稱HLS)是一個基於HTTP 的視訊串流協議,由Apple 公司實現,Mac OS 上的QuickTime、Safari 以及iOS 上的Safari 都能很好的支援HLS,高版本Android 也增加了對HLS 的支持。一些常見的客戶端如:MPlayerX、VLC 也都支援HLS 協定。
HLS 協定是基於HTTP,而提供HLS 的伺服器需要做兩件事:
編碼:以H.263 格式對影像進行編碼,以MP3 或HE-AAC 對聲音進行編碼,最終打包到MPEG-2 TS(Transport Stream)容器之中;分割:把編碼好的TS 檔案等長切分成後綴為ts 的小文件,並產生一個.m3u8 的純文字索引文件;瀏覽器使用的是m3u8 文件。 m3u8 跟音訊清單格式m3u 很像,可以簡單的認為m3u8 就是包含多個ts 檔案的播放清單。播放器依序逐一播放,全部放完再請求一下m3u8 文件,取得包含最新ts 文件的播放清單繼續播,周而復始。整個直播過程就是依靠一個不斷更新的m3u8 和一堆小的ts 檔案組成,m3u8 必須動態更新,ts 可以走CDN。一個典型的m3u8 檔案格式如下:
#EXTM3U#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=200000gear1/prog_index.m3u8#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=311111gear2/prog_index.m3u8#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=484444gear3/prog_index.m3u8#EXT-X-STREAM-INF:PROGRAM-IDP. m3u8
可以看到HLS 協定本質還是一個個的HTTP 請求/ 回應,所以適應性很好,不會受到防火牆影響。但它也有一個致命的弱點:延遲現象非常明顯。如果每個ts 依照5 秒來切分,一個m3u8 放6 個ts 索引,那麼至少就會帶來30 秒的延遲。如果減少每個ts 的長度,減少m3u8 中的索引數,延遲確實會減少,但會帶來更頻繁的緩衝,對服務端的請求壓力也會倍增。所以只能根據實際情況找到一個折中的點。
對於支援HLS 的瀏覽器來說,直接這樣寫就能播放了:
<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。
2. Real Time Messaging ProtocolReal 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 動畫
了解完直播形式之後,接下來整體了解直播流程。
三、直播整體流程直播整體流程大致可分為:
視訊擷取端:可以是電腦上的音訊和視訊輸入裝置、或手機端的攝影機、或麥克風,目前以行動裝置手機視訊為主。
直播串流視訊服務端:一台Nginx伺服器,擷取視訊錄製端傳輸的視訊串流(H264/ACC編碼),由伺服器端進行解析編碼,推送RTMP/HLS格式視訊串流至視訊播放端。
影片播放端:可以是電腦上的播放器(QuickTime Player、VLC),手機端的native播放器,還有就是H5 的video標籤等,目前還是以手機端的native播放器為主。
(web前端學習交流群:328058344 禁止閒聊,非喜勿進!)
四、H5 錄製視頻對於H5視訊錄製,可以使用強大的webRTC (Web Real-Time Communication)是一個支援網頁瀏覽器進行即時語音對話或視訊對話的技術,缺點是只在PC 的Chrome 上支援較好,行動裝置支援不太理想。
使用webRTC 錄製影片基本流程
① 呼叫window.navigator.webkitGetUserMedia()
取得用戶的PC攝影機視訊資料。
② 將取得到視訊串流資料轉換成window.webkitRTCPeerConnection
(一種視訊串流資料格式)。
③ 利用WebScoket
將視訊串流資料傳輸到服務端。
注意:
雖然Google一直在推WebRTC,目前已有不少成型的產品出現,但是大部分行動端的瀏覽器還不支援webRTC(最新iOS 10.0也不支援),所以真正的錄影還是要靠客戶端(iOS, Android)來實現,效果會好一些。
WebRTC支援度
WebRTC支援度
iOS原生應用程式呼叫相機錄影流程
① 音視頻的採集,利用AVCaptureSession和AVCaptureDevice可以收集到原始的音視頻資料流。
② 對視訊進行H264編碼,對音訊進行AAC編碼,在iOS中分別有已經封裝好的編碼庫(x264編碼、faac編碼、ffmpeg編碼)來實現對音視訊的編碼。
③ 將編碼後的音、視訊資料進行組裝封包。
④ 建立RTMP連線並上推至服務端。
五、搭建Ng
安裝nginx、nginx-rtmp-module
① 先clone nginx專案到本地:
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 協定流ffeg -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:1.101 1935/hls/testffmpeg -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 'lay=main_ww-lay_ -10′ -acodec libmp3lame -ar 44100 -ac 1 -f flv rtmp://192.168.1.101:1935/hls/test
更多指令,請參考:
FFmpeg處理RTMP串流媒體的命令大全
FFmpeg常用推流指令
七、H5 直播影片播放行動端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 實現播放。
總結以上所述是小編給大家介紹的HTML5實現視訊直播功能思路詳解,希望對大家有幫助,如果大家有任何疑問請給我留言,小編會及時回覆大家的。在此也非常感謝大家對VeVb武林網站的支持!