整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          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。

          程序猿的生活:web前端全棧資料粉絲福利(面試題、視頻、資料筆記,進階路線)zhuanlan.zhihu.com/p/136454207

          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 動畫

          了解完直播形式之后,接下來整體了解直播流程。

          相關學習資料推薦,點擊下方鏈接免費報名,先碼住不迷路~】

          音視頻免費學習地址:FFmpeg/WebRTC/RTMP/NDK/Android音視頻流媒體高級開發

          【免費分享】音視頻學習資料包、大廠面試題、技術視頻和學習路線圖,資料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以點擊788280672加群免費領取~

          三、直播整體流程

          直播整體流程大致可分為:

          視頻采集端:可以是電腦上的音視頻輸入設備、或手機端的攝像頭、或麥克風,目前以移動端手機視頻為主。

          直播流視頻服務端:一臺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連接并上推到服務端。


          五、搭建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 實現播放。

          原文 https://zhuanlan.zhihu.com/p/146323842

          享 | 劉博(又拍云多媒體開發工程師)

          又小拍:

          如何實現HTML5直播技術是直播創業團隊一直想要攻克的難題。12月1日20:00,深度參與“又拍直播云”開發的工程師劉博就如何利用WebSocket+MSE實現HTML5直播在微信群里進行了分享。小拍馬不停蹄將劉博的分享內容整理成了文字,并插入一些PPT便于大家了解。全文整理如下:

          下面就是分享內容啦~

          當前為了滿足比較火熱的移動Web端直播需求,一系列的HTML5直播技術迅速的發展起來。

          常見的可用于HTML5的直播技術有HLS、WebSocket與WebRTC。今天我向大家介紹WebSocket與MSE相關的技術要點,并在最后通過一個實例來展示具體用法。

          分享大綱

          ⊙WebSocket協議介紹

          ⊙WebSocket Client/Server API介紹

          ⊙MSE介紹

          ⊙fMP4介紹

          ⊙Demo展示

          WebSocket

          通常的Web應用都是圍繞著HTTP的請求/響應模型構建的。所有的HTTP通信都通過客戶端來控制,由客戶端向服務器發出一個請求,服務器接收和處理完畢后再返回結果給客戶端,客戶端將數據展現出來。由于這種模式不能滿足實時應用需求,于是出現了SSE、Comet等 "服務器推" 的長連接技術。

          WebSocket是基于TCP連接之上的通信協議,可以在單個TCP連接上進行全雙工的通信。WebSocket在2011年被IETF定為標準RFC 6455,并被RFC 7936補充規范,WebSocket API被W3C定為標準。

          WebSocket是獨立地創建在TCP上的協議,HTTP協議中的那些概念都和WebSocket沒有關聯,唯一關聯的是使用HTTP協議的101狀態碼進行協議切換時,使用的TCP端口是80,可以繞過大多數防火墻的限制。

          WebSocket握手

          為了更方便地部署新協議,HTTP/1.1引入了Upgrade機制,使得客戶端和服務端之間可以借助已有的HTTP語法升級到其它協議。這個機制在RFC7230的6.7 Upgrade一節中有詳細描述。

          要發起HTTP/1.1協議升級,客戶端必須在請求頭部中指定這兩個字段 ▽

          Connection: Upgrade

          Upgrade: protocol-name[/protocol-version]

          如果服務端同意升級,那么需要這樣響應 ▽

          HTTP/1.1 101 Switching Protocols

          Connection: upgrade

          Upgrade: protocol-name[/protocol-version]

          [... data defined by new protocol ...]

          可以看到,HTTP Upgrade響應的狀態碼是101,并且響應正文可以使用新協議定義的數據格式。

          WebSocket握手就利用了這種HTTP Upgrade機制。一旦握手完成,后續數據傳輸直接在TCP上完成。

          WebSocket JavaScript API

          目前主流的瀏覽器提供了WebSocket的API接口,可以發送消息(文本或者二進制)給服務器,并且接收事件驅動的響應數據。

          Step1. 檢查瀏覽器是否支持WebSocket

          if(window.WebSocket) {

          // WebSocket代碼

          }

          Step2. 建立連接

          var ws = new WebSocket('ws://localhost:8327');

          Step3. 注冊回調函數以及收發數據

          分別注冊WebSocket對象的onopen、onclose、onerror以及onmessage回調函數。

          通過ws.send()來進行發送數據,這里不僅可以發送字符串,也可以發送Blob或ArrayBuffer類型的數據。

          如果接收的是二進制數據,需要將連接對象的格式設為blob或arraybuffer。

          ws.binaryType = 'arraybuffer';

          WebSocket Golang API

          服務器端WebSocket庫我推薦使用Google自己的golang.org/x/net/websocket,可以非常方便的與net/http一起使用。也可以將WebSocket的handler function通過websocket.Handler轉換成http.Handler,這樣就可以跟net/http庫一起使用了。

          然后通過websocket.Message.Receive來接收數據,通過websocket.Message.Send來發送數據。

          具體代碼可以看下面的Demo部分。

          MSE

          在介紹MSE之前,我們先看看HTML5<audio>和<video>有哪些限制。

          HTML5<audio>和<video>標簽的限制

          • 不支持流

          • 不支持DRM和加密

          • 很難自定義控制, 以及保持跨瀏覽器的一致性

          • 編解碼和封裝在不同瀏覽器支持不同

          MSE是解決HTML5的流問題。

          Media Source Extensions(MSE)是Chrome、Safari、Edge等主流瀏覽器支持的一個新的Web API。MSE是一個W3C標準,允許JavaScript動態構建<video>和<audio>的媒體流。它定義了對象,允許JavaScript傳輸媒體流片段到一個 HTMLMediaElement。

          通過使用MSE,你可以動態地修改媒體流而不需要任何插件。這讓前端JavaScript可以做更多的事情—— 在JavaScript進行轉封裝、處理,甚至轉碼。

          雖然MSE不能讓流直接傳輸到media tags上,但是MSE提供了構建跨瀏覽器播放器的核心技術,讓瀏覽器通過JavaScript API來推音視頻到media tags上。

          Browser Support

          通過caniuse來檢查是否瀏覽器支持情況。

          通過MediaSource.isTypeSupported()可以進一步地檢查codec MIME類型是否支持。

          fMP4

          比較常用的視頻封裝格式有WebM和fMP4。

          WebM和WebP是兩個姊妹項目,都是由Google贊助的。由于WebM是基于Matroska的容器格式,天生是流式的,很適合用在流媒體領域里。

          下面著重介紹一下fMP4格式。

          我們都知道MP4是由一系列的Boxes組成的。普通的MP4的是嵌套結構的,客戶端必須要從頭加載一個MP4文件,才能夠完整播放,不能從中間一段開始播放。

          而fMP4由一系列的片段組成,如果服務器支持byte-range請求,那么,這些片段可以獨立的進行請求到客戶端進行播放,而不需要加載整個文件。

          為了更加形象的說明這一點,下面我介紹幾個常用的分析MP4文件的工具。

          • gpac,原名mp4box,是一個媒體開發框架,在其源碼下有大量的媒體分析工具,可以使用testapps;

          • mp4box.js,是mp4box的Javascript版本;

          • bento4,一個專門用于MP4的分析工具;

          • mp4parser,在線MP4文件分析工具。

          fragment mp4 VS non-fragment mp4

          下面是一個fragment mp4文件通過mp4parser(http://mp4parser.com)分析后的截圖 ▽

          下面是一個non-fragment mp4文件通過mp4parser分析后的截圖 ▽

          我們可以看到non-fragment mp4的最頂層box類型非常少,而fragment mp4是由一段一段的moof+mdat組成的,它們已經包含了足夠的metadata信息與數據, 可以直接seek到這個位置開始播放。也就是說fMP4是一個流式的封裝格式,這樣更適合在網絡中進行流式傳輸,而不需要依賴文件頭的metadata。

          Apple在WWDC 2016大會上宣布會在iOS 10、tvOS、macOS的HLS中支持fMP4,可見fMP4的前景非常的好。

          值得一提的是,fMP4、CMAF、ISOBMFF其實都是類似的東西。

          MSE JavaScript API

          從高層次上看,MSE提供了

          • 一套 JavaScript API 來構建 media streams

          • 一個拼接和緩存模型

          • 識別一些 byte 流類型:

          • WebM

          • ISO Base Media File Format

          • MPEG-2 Transport Streams

          MSE內部結構

          MSE本身的設計是不依賴任務特定的編解碼和容器格式的,但是不同的瀏覽器支持程度是不一樣的。

          可以通過傳遞一個MIME類型的字符串到靜態方法:MediaSource.isTypeSupported來檢查。比如 ▽

          MediaSource.isTypeSupported('audio/mp3'); // false

          MediaSource.isTypeSupported('video/mp4'); // true

          MediaSource.isTypeSupported('video/mp4; codecs="avc1.4D4028, mp4a.40.2"'); // true

          獲取Codec MIME string的方法可以通過在線的mp4info(http://nickdesaulniers.github.io/mp4info),或者使用命令行mp4info test.mp4 | grep Codecs,可以得到類似如下結果 ▽

          mp4info fmp4.mp4| grep Codec

          Codecs String: mp4a.40.2

          Codecs String: avc1.42E01E

          當前,H.264 + AAC的MP4容器在所有的瀏覽器都支持。

          普通的MP4文件是不能和MSE一起使用的, 需要將MP4進行fragment化。

          檢查一個MP4是否已經fragment的方法 ▽

          mp4dump test.mp4 | grep "\[m"

          如果是non-fragment會顯示如下信息 ▽

          mp4dump nfmp4.mp4 | grep "\[m"

          [mdat] size=8+50873

          [moov] size=8+7804

          [mvhd] size=12+96

          [mdia] size=8+3335

          [mdhd] size=12+20

          [minf] size=8+3250

          [mdia] size=8+3975

          [mdhd] size=12+20

          [minf] size=8+3890

          [mp4a] size=8+82

          [meta] size=12+78

          如果已經fragment,會顯示如下的類似信息 ▽

          mp4dump fmp4.mp4 | grep "\[m" | head -n 30

          [moov] size=8+1871

          [mvhd] size=12+96

          [mdia] size=8+312

          [mdhd] size=12+20

          [minf] size=8+219

          [mp4a] size=8+67

          [mdia] size=8+371

          [mdhd] size=12+20

          [minf] size=8+278

          [mdia] size=8+248

          [mdhd] size=12+20

          [minf] size=8+156

          [mdia] size=8+248

          [mdhd] size=12+20

          [minf] size=8+156

          [mvex] size=8+144

          [mehd] size=12+4

          [moof] size=8+600

          [mfhd] size=12+4

          [mdat] size=8+138679

          [moof] size=8+536

          [mfhd] size=12+4

          [mdat] size=8+24490

          [moof] size=8+592

          [mfhd] size=12+4

          [mdat] size=8+14444

          [moof] size=8+312

          [mfhd] size=12+4

          [mdat] size=8+1840

          [moof] size=8+600

          把一個non-fragment MP4轉換成fragment MP4。

          可以使用FFmpeg的 -movflags來轉換。

          對于原始文件為非MP4文件 ▽

          ffmpeg -i trailer_1080p.mov -c:v copy -c:a copy -movflags frag_keyframe+empty_moov bunny_fragmented.mp4

          對于原始文件已經是MP4文件 ▽

          ffmpeg -i non_fragmented.mp4 -movflags frag_keyframe+empty_moov fragmented.mp4

          或者使用mp4fragment ▽

          mp4fragment input.mp4 output.mp4

          DEMO TIME

          劉博在分享的最后階段,展示了兩個demo,分別是MSE Vod Demo、MSE Live Demo

          MSE Vod Demo

          • 展示利用MSE和WebSocket實現一個點播服務

          • 后端讀取一個fMP4文件,通過WebSocket發送給MSE,進行播放

          MSE Live Demo

          • 展示利用MSE和WebSocket實現一個直播服務

          • 后端代理一條HTTP-FLV直播流,通過WebSocket發送給MSE,進行播放

          • 前端MSE部分做了很多工作, 包括將flv實時轉封裝成了fMP4,這里引用了videojs-flow的實現

          Q & A

          Q1:對于沒有公網iIP的客戶如何通過RTMP協議推流?

          A1:用戶客戶端進行RTMP推流,不需要公網IP,推到直播系統分配給你的地址就可以了。

          Q2:MSE客戶端做很多東西,可以轉碼、解碼, 這個會有性能問題嗎? 還有這個技術,目前有公司在大批量用嗎?

          A2:目前該技術在實驗階段,轉封裝的話,對性能要求不高,我們在各自型號的手機上測試都沒有問題。目前除了微信內置瀏覽器對MSE支持不好,大部分瀏覽器對MSE支持都比較好。

          Q3:沒做過相關內容,能簡單介紹一下HTTP-FLV么?

          A3:HTTP-FLV就是將FLV流以HTTP長連接的形式分發出去,目前在各大直播平臺都用的比較多。大家可以關注下又拍云微信公眾賬號,之前專門有一篇文章介紹HTTP-FLV。

          Q4:不大了解HTTP-FLV,既然是長時間的狀態性連接,為什么不用tcp/socket呢?

          A5: FLV不能在<video>標簽直接播放,所以需要通過MSE轉封裝成MP4,再吐到<video>標簽進行播放。

          Q5:嗶哩嗶哩H5播放器是基于WebSocket與MSE技術實現的嘛?

          A5:B站開源的flv.js是一個非常好的項目,是基于 MSE 實現的,實時性做的也比較好,B 站自己已經在網站播放器上使用了。

          Q6:VLC器播放和網頁播放,哪個快啊?

          A6:播放器端延時,一個重要指標是播放器的緩存區大小。VLC的默認緩存區比較大,所以,VLC通常延時會大一些。

          Q7:可以介紹下秒開技術么,以及秒開的原理?

          A7:秒開可以在服務器端多緩存一個GoP來實現,這樣播放器請求的第一幀能保證是I幀,可以立即播放,以此達到秒開的效果.

          Refs

          WebSocket

          • rfc6455

          • HTTP Upgrade

          • WebSocket API

          • MDN WebSocket

          • videojs-flow

          MSE

          • W3C

          • MDN MSE

          • HTML5 Codec MIME

          前,視頻直播(尤其是移動端的視頻直播)已經火到不行了,基本上各大互聯網公司都有了自己的直播產品,所以對于我們而言,了解直播的一些基本知識和主要技術點是有必要的。

          一、移動視頻直播發展

          可以看到,直播從 PC 到一直發展到移動端,越來越多的直播類 App 上線,同時移動直播進入了前所未有的爆發階段,但是對于大多數移動直播來說,還是要以 Native 客戶端實現為主,但是 HTML5 在移動直播端也承載著不可替代的作用,例如 HTML5 有著傳播快,易發布的優勢,同時最為關鍵的時 HTML5 同樣可以播放直播視頻。

          二、直播流程

          完整的直播可以分為以下幾塊:

          1. 視頻錄制端:一般是電腦上的音視頻輸入設備或者手機端的攝像頭或者麥克風,目前以移動端的手機視頻為主。

          2. 視頻播放端:可以是電腦上的播放器,手機端的 Native 播放器,還有就是 HTML5 的 video 標簽等,目前還是已手機端的 Native 播放器為主。

          3. 視頻服務器端:一般是一臺 nginx 服務器,用來接受視頻錄制端提供的視頻源,同時提供給視頻播放端流服務。

          流程如下:

          三、直播協議

          1、HLS

          HLS 全稱是 HTTP Live Streaming。這是 Apple 提出的直播流協議。目前,IOS 和 高版本 Android 都支持 HLS。

          那什么是 HLS 呢?

          HLS 主要的兩塊內容是 .m3u8 文件和 .ts 播放文件。接受服務器會將接受到的視頻流進行緩存,然后緩存到一定程度后,會將這些視頻流進行編碼格式化,同時會生成一份 .m3u8 文件和其它很多的 .ts 文件。

          根據 wiki 闡述,HLS 的基本架構為:

          • 服務器:后臺服務器接受視頻流,然后進行編碼和片段化。

          • 編碼:視頻格式編碼采用 H.264。音頻編碼為 AAC, MP3, AC-3,EC-3。然后使用 MPEG-2 Transport Stream 作為容器格式。

          • 分片:將 TS 文件分成若干個相等大小的 .ts 文件。并且生成一個 .m3u8 作為索引文件(確保包的順序)

          • 分發:由于 HLS 是基于 HTTP 的,所以,作為分發,最常用的就是 CDN 了。

          • 客戶端:使用一個 URL 去下載 m3u8 文件,然后,開始下載 ts 文件,下載完成后,使用 playback software(即時播放器) 進行播放。

          2、RTMP

          RTMP 全稱為:Real-Time Messaging Protocol 。它是專門應對實時交流場景而開發出來的一個協議。它爹是 Macromedia,后來賣身給了 Adobe。RTMP 根據不同的業務場景,有很多變種:

          • 純 RTMP 使用 TCP 連接,默認端口為 1935(有可能被封)。

          • RTMPS: 就是 RTMP + TLS/SSL

          • RTMPE: RTMP + encryption。在 RTMP 原始協議上使用,Adobe 自身的加密方法

          • RTMPT: RTMP + HTTP。使用 HTTP 的方式來包裹 RTMP 流,這樣能直接通過防火墻。

          • RTMFP: RMPT + UDP。該協議常常用于 P2P 的場景中,針對延時有變態的要求。

          3、HLS與RTMP

          四、視頻錄制

          關于音視頻采集錄制,首先明確下面幾個概念:

          • 視頻編碼:所謂視頻編碼就是指通過特定的壓縮技術,將某個視頻格式的文件轉換成另一種視頻格式文件的方式,我們使用的 iPhone 錄制的視頻,必須要經過編碼,上傳,解碼,才能真正的在用戶端的播放器里播放。

          • 編解碼標準:視頻流傳輸中最為重要的編解碼標準有國際電聯的 H.261、H.263、H.264,其中 HLS 協議支持 H.264 格式的編碼。

          • 音頻編碼:同視頻編碼類似,將原始的音頻流按照一定的標準進行編碼,上傳,解碼,同時在播放器里播放,當然音頻也有許多編碼標準,例如 PCM 編碼,WMA 編碼,AAC 編碼等等,這里我們 HLS 協議支持的音頻編碼方式是 AAC 編碼。

          1、HTML5錄制視頻

          對于HTML5視頻錄制,可以使用強大的 webRTC (Web Real-Time Communication)是一個支持網頁瀏覽器進行實時語音對話或視頻對話的技術,缺點是只在 PC 的 Chrome 上支持較好,移動端支持不太理想。

          使用 webRTC 錄制視頻基本流程是:

          1. 調用 window.navigator.webkitGetUserMedia() 獲取用戶的PC攝像頭視頻數據。

          2. 將獲取到視頻流數據轉換成 window.webkitRTCPeerConnection (一種視頻流數據格式)。

          3. 利用 webscoket 將視頻流數據傳輸到服務端

          由于許多方法都要加上瀏覽器前綴,所以很多移動端的瀏覽器還不支持 webRTC,所以真正的視頻錄制還是要靠客戶端(iOS,Android)來實現,效果會好一些。

          2、iOS錄制視頻

          利用 iOS 上的攝像頭,進行音視頻的數據采集,主要分為以下幾個步驟:

          1. 音視頻的采集,iOS 中,利用 AVCaptureSession 和 AVCaptureDevice 可以采集到原始的音視頻數據流。

          2. 對視頻進行 H264 編碼,對音頻進行 AAC 編碼,在 iOS 中分別有已經封裝好的編碼庫來實現對音視頻的編碼。

          3. 對編碼后的音、視頻數據進行組裝封包;

          4. 建立 RTMP 連接并上推到服務端。

          五、推流

          所謂推流,就是將我們已經編碼好的音視頻數據發往視頻流服務器中,在 iOS 代碼里面一般常用的是使用 RTMP 推流,可以使用第三方庫 librtmp-iOS 進行推流,librtmp 封裝了一些核心的 API 供使用者調用。例如推流 API 等等,配置服務器地址,即可將轉碼后的視頻流推往服務器。

          那么如何搭建一個推流服務器呢?

          簡單的推流服務器搭建,由于我們上傳的視頻流都是基于 RTMP 協議的,所以服務器也必須要支持 RTMP 才行,大概需要以下幾個步驟:

          1. 安裝一臺 nginx 服務器。

          2. 安裝 nginx 的 RTMP 擴展,目前使用比較多的是 https://github.com/arut/nginx-rtmp-module

          3. 配置 nginx 的 conf 文件

          4. 重啟 nginx,將 RTMP 的推流地址寫為 rtmp://ip:1935/hls/mystream, 其中 hls_path 表示生成的 .m3u8 和 ts 文件所存放的地址,hls_fragment 表示切片時長,mysteam 表示一個實例,即將來要生成的文件名可以先自己隨便設置一個。

          更多配置可以參考:https://github.com/arut/nginx-rtmp-module/wiki/

          下面是 nginx 的配置文件

          六、播放視頻

          對于視頻播放,可以使用 HLS(HTTP Live Streaming)協議播放直播流,iOS和 Android 都天然支持這種協議,配置簡單,直接使用 video 標簽即可。

          下面是簡單的代碼使用 video 播放直播視頻:


          本文轉載于互聯網,如侵犯你的權益,請及時告知。

          參考地址:http://geek.csdn.net/news/detail/95188、https://aotu.io/notes/2016/10/09/HTML5-SopCast/


          主站蜘蛛池模板: 国产日韩精品一区二区三区| 久久精品一区二区三区资源网| 丰满人妻一区二区三区视频53| 国产成人久久精品区一区二区 | 视频在线一区二区三区| 91精品国产一区二区三区左线| www.亚洲一区| 免费国产在线精品一区| 夜精品a一区二区三区| 亚洲熟妇无码一区二区三区导航| 精品一区二区三区在线观看视频| 中文字幕一区二区三区乱码| 国产美女露脸口爆吞精一区二区 | 亚洲国产欧美日韩精品一区二区三区| 亚洲国产一区二区三区青草影视 | 亚洲AV成人一区二区三区观看| 中文字幕日韩一区二区三区不卡| 性色A码一区二区三区天美传媒| 无码人妻久久一区二区三区免费| 激情综合一区二区三区| 亚洲啪啪综合AV一区| 无人码一区二区三区视频| 人妻免费一区二区三区最新| 视频一区精品自拍| 无码少妇精品一区二区免费动态| 国产成人无码一区二区在线播放 | 久久久精品日本一区二区三区| 久夜色精品国产一区二区三区| 精品一区二区三区四区在线| 自慰无码一区二区三区| 人妻少妇精品视频一区二区三区| 人妻无码久久一区二区三区免费| 极品人妻少妇一区二区三区| 亚洲高清毛片一区二区| 在线观看国产一区二区三区| 国产精品 一区 在线| 无码人妻精品一区二区三区夜夜嗨 | 国产一区二区三区免费看| 精品国产亚洲一区二区在线观看| 果冻传媒董小宛一区二区| 在线播放国产一区二区三区 |