最近視訊直播比較火,發現目前WEB 上主流的視訊直播方案有HLS 和RTMP,行動WEB 端目前以HLS 為主,PC端則以RTMP 為主實時性較好,接下來將圍繞這兩種視訊串流協定來展開H5直播主題分享,以下透過本文給大家分享HTML5視訊直播思維詳解,一起看看吧
前言
前不久抽空對目前比較火的視訊直播,做了下研究與探索,了解其整體實現流程,以及探討行動端HTML5直播可行性方案。
發現目前WEB 上主流的視訊直播方案有HLS 和RTMP,行動WEB 端目前以HLS 為主(HLS有延遲性問題,也可以藉助video.js 採用RTMP),PC端則以RTMP為主即時性較好,接下來將圍繞這兩種視訊串流協定展開H5直播主題分享。
一、視訊串流協定HLS與RTMP
#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 的伺服器需要做兩件事:
編碼:以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=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 中的索引數,延遲確實會減少,但會帶來更頻繁的緩衝,對服務端的請求壓力也會倍增。所以只能根據實際情況找到一個折中的點。
對於支援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 Protocol
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 動畫
了解完直播形式之後,接下來整體了解直播流程。
三、直播整體流程
#直播整體流程大致可分為:
視訊擷取端:可以是電腦上的影音輸入裝置、或手機端的相機、或麥克風,目前以行動裝置手機影片為主。
直播串流視訊服務端:一台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 Rtmp直播串流服務
安裝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 的設定
3. 重启nginx服务
重启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常用推流命令
七、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 实现播放。
以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!
相关推荐:
HTML5
video播放器全屏(fullScreen)实现的方法
以上是HTML5如何實現視訊直播功能的詳細內容。更多資訊請關注PHP中文網其他相關文章!