亚洲最大看欧美片,亚洲图揄拍自拍另类图片,欧美精品v国产精品v呦,日本在线精品视频免费

  • 站長資訊網
    最全最豐富的資訊網站

    WebSocket+MSE——HTML5 直播技術解析

    作者 | 劉博(又拍云多媒體開發(fā)工程師)

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

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

    文章大綱

    • WebSocket 協(xié)議介紹

    • WebSocket Client/Server API介紹

    • MSE 介紹

    • fMP4 介紹

    • Demo 展示

    WebSocket

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

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

    WebSocket 是獨立地創(chuàng)建在 TCP 上的協(xié)議,HTTP 協(xié)議中的那些概念都和 WebSocket 沒有關聯(lián),唯一關聯(lián)的是使用 HTTP 協(xié)議的 101 狀態(tài)碼進行協(xié)議切換時,使用的 TCP 端口是 80,可以繞過大多數(shù)防火墻的限制。

    WebSocket+MSE——HTML5 直播技術解析

    WebSocket 握手

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

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

    > 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 響應的狀態(tài)碼是 101,并且響應正文可以使用新協(xié)議定義的數(shù)據(jù)格式。

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

    WebSocket JavaScript API

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

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

    > if(window.WebSocket) {      // WebSocket代碼  }

    Step2. 建立連接

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

    Step3. 注冊回調函數(shù)以及收發(fā)數(shù)據(jù)

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

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

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

    ws.binaryType = 'arraybuffer';

    WebSocket Golang API

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

    然后通過 websocket.Message.Receive 來接收數(shù)據(jù),通過 websocket.Message.Send 來發(fā)送數(shù)據(jù)。

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

    MSE

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

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

    • 不支持流

    • 不支持 DRM 和加密

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

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

    MSE 是解決 HTML5 的流問題。

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

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

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

    Browser Support

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

    WebSocket+MSE——HTML5 直播技術解析

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

    fMP4

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

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

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

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

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

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

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

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

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

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

    fragment mp4 VS non-fragment mp4

    下面是一個 fragment mp4 文件通過 mp4parser(Online MPEG4 Parser )分析后的截圖 ▽

    WebSocket+MSE——HTML5 直播技術解析

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

    WebSocket+MSE——HTML5 直播技術解析

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

    Apple在WWDC 2016 大會上宣布會在 iOS 10、tvOS、macO S的 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 內部結構

    WebSocket+MSE——HTML5 直播技術解析

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

    可以通過傳遞一個 MIME 類型的字符串到靜態(tài)方法:

    > 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 實現(xiàn)一個點播服務

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

    WebSocket+MSE——HTML5 直播技術解析

    展示利用 MSE 和 WebSocket 實現(xiàn)一個直播服務

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

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

    Refs

    WebSocket

    • rfc6455

    • HTTP Upgrade

    • WebSocket API

    • MDN WebSocket

    • videojs-flow

    MSE

    • W3C

    • MDN MSE

    • HTML5 Codec MIME

    又拍直播云是基于又拍云內容分發(fā)網絡為直播應用提供超低延遲、高碼率、高并發(fā)的整套從推流端到播放端的一站式解決方案。包括實時轉碼,實時錄制,分發(fā)加速,水印,截圖,秒級禁播,延時直播等功能。直播源站支持自主源站或又拍云源,為支持用戶在不同終端播放,支持 RTMP、HLS、HTTP-flv 播放輸出。

    詳情了解:https://www.upyun.com/products/live

    推薦閱讀:

    無連麥,不直播,都在說的直播利器連麥互動到底是啥?
    技術干貨|移動直播六大關鍵技術詳解
    又拍直播云SDK,自帶美顏、濾鏡、消噪、人聲增益等功能
    又拍直播云功能處理篇:轉碼、錄制、視頻水印、視頻截圖
    又拍直播云功能基礎篇:推流和拉流、多協(xié)議輸出、多訪問方式、回源端口自定義
    又拍直播云功能高級篇:防盜鏈、秒級禁播、自動鑒黃、API接口

    贊(0)
    分享到: 更多 (0)
    網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號