前端在瀏覽器端播放直播流協(xié)議的2種方式講解
直播流協(xié)議2種:.flv后綴是http-flv協(xié)議,.m3u8后綴是hls協(xié)議
一、播放.m3u8
1、hls.js
HLS (HTTP Live Streaming)是Apple公司研發(fā)的流媒體傳輸技術(shù),包括一個m3u8的索引文件、多個ts分片文件和key加密串文件。這項技術(shù)主要應(yīng)用于點(diǎn)播和直播領(lǐng)域。
hls.js是一個JavaScript庫,可實(shí)現(xiàn)HTTP Live Streaming客戶端。 它依靠HTML5視頻和MediaSource擴(kuò)展進(jìn)行播放。
它通過將MPEG-2傳輸流和AAC / MP3流轉(zhuǎn)換為ISO BMFF(MP4)片段來工作。 如果在瀏覽器中可用,可以使用Web Worker異步執(zhí)行此轉(zhuǎn)換。 WWDC2016期間宣布,hls.js還支持HLS + fmp4
hls.js不需要任何播放器,它可以直接在標(biāo)準(zhǔn)HTML 元素上運(yùn)行。
hls.js用ECMAScript6(* .js)和TypeScript(* .ts)(ES6的強(qiáng)類型超集)編寫,并使用TypeScript編譯器在ECMAScript5中進(jìn)行編譯。
特征
- VOD 和現(xiàn)場播放列表
- 實(shí)時播放列表上的 DVR 支持
- 碎片化的 MP4 容器
- MPEG-2 TS 容器
- ITU-T 建議書 H.264 和 ISO/IEC 14496-10 基本流
- ISO/IEC 13818-7 ADTS AAC 基本流
- ISO/IEC 11172-3 / ISO/IEC 13818-3(MPEG-1/2 Audio Layer III)基本流
- 打包元數(shù)據(jù) (ID3v2.3.0) 基本流
- AAC 容器(僅音頻流)
- MPEG 音頻容器(MPEG-1/2 Audio Layer III 僅音頻流)
- HTTP Live Streaming 的定時元數(shù)據(jù)(ID3 格式,MPEG-2 TS 承載)
- AES-128 解密
- SAMPLE-AES 解密(僅當(dāng)使用 MPEG-2 TS 容器時才支持)
- 對 DRM(數(shù)字權(quán)限管理)的加密媒體擴(kuò)展 (EME) 支持
- Widevine CDM(僅在演示頁面上使用shaka-packager test-stream 進(jìn)行測試)
- CEA-608/708 字幕
- WebVTT 字幕
- 用于 VoD 和現(xiàn)場播放列表的備用音軌再現(xiàn)(帶有備用音頻的主播放列表)
- 自適應(yīng)流媒體
- 手動和自動質(zhì)量切換
- 3種質(zhì)量切換模式可用(可通過API方式控制)
- 即時切換(在當(dāng)前視頻位置即時質(zhì)量切換)
- 平滑切換(下一個加載片段的質(zhì)量切換)
- 帶寬保守切換(下一個加載片段的質(zhì)量切換更改,不刷新緩沖區(qū))
- 在自動質(zhì)量模式下,緊急關(guān)閉以防帶寬突然下降以最小化緩沖。
- 3種質(zhì)量切換模式可用(可通過API方式控制)
- VoD & Live 上的準(zhǔn)確搜索(不限于片段或關(guān)鍵幀邊界)
- 無需重新下載段即可在緩沖區(qū)和后臺緩沖區(qū)中查找的能力
- 內(nèi)置分析
- 可以監(jiān)控所有內(nèi)部事件(網(wǎng)絡(luò)事件、視頻事件)
- 播放會話指標(biāo)也公開
- 容錯能力
- 庫中嵌入的重試機(jī)制
- 可以觸發(fā)恢復(fù)操作修復(fù)致命的媒體或網(wǎng)絡(luò)錯誤
2、使用hls.js
1. 安裝hls.js
npm i hls.js
2. 使用hls.js實(shí)現(xiàn)播放m3u8格式流,獲取video節(jié)點(diǎn)
<video id="video" ref="videoRef" autoplay width="800" height="400" controls></video>
import Hls from 'hls.js' // 獲取視頻元素 var video = document.getElementById('video'); if (video.canPlayType('application/vnd.apple.mpegurl')) { video.src = videoSrc; // // If no native HLS support, check if HLS.js is supported // } else if (Hls.isSupported()) { let config = { xhrSetup: function (xhr, url) { xhr.withCredentials = true; // 會攜帶cookie // xhr.setRequestHeader('token',"my-token") }, } // 創(chuàng)建一個新的HLS實(shí)例 var hls = new Hls(config); // 綁定 canplay 事件,當(dāng)能夠播放時開始播放 hls.on(Hls.Events.MANIFEST_PARSED, function() { video.play(); }); // 綁定錯誤事件 hls.on(Hls.Events.ERROR, function(event, data) { var errorType = data.type; var errorDetails = data.details; var errorFatal = data.fatal; if (data.fatal) { switch(data.type) { case Hls.ErrorTypes.NETWORK_ERROR: // 網(wǎng)絡(luò)錯誤處理 break; case Hls.ErrorTypes.MEDIA_ERROR: // 媒體錯誤處理 break; default: // 其他錯誤處理 break; } } }); // 在video元素上附加MSE hls.attachMedia(video); // 開始加載HLS流 hls.loadSource('xxx.m3u8'); }
3. 銷毀
應(yīng)調(diào)用以釋放使用的資源并銷毀 hls 上下文
hls.destroy()
4. 致命錯誤恢復(fù)
hls.js 提供了通過以下 2 種方法“嘗試”恢復(fù)致命網(wǎng)絡(luò)和媒體錯誤的方法:
hls.startLoad()
應(yīng)調(diào)用以恢復(fù)網(wǎng)絡(luò)錯誤。
hls.recoverMediaError()
應(yīng)調(diào)用以恢復(fù)媒體錯誤。
錯誤恢復(fù)示例代碼
hls.on(Hls.Events.ERROR, function (event, data) { if (data.fatal) { switch (data.type) { case Hls.ErrorTypes.NETWORK_ERROR: // try to recover network error console.log('fatal network error encountered, try to recover'); hls.startLoad(); break; case Hls.ErrorTypes.MEDIA_ERROR: console.log('fatal media error encountered, try to recover'); hls.recoverMediaError(); break; default: // cannot recover hls.destroy(); break; } } });
hls.swapAudioCodec()
如果調(diào)用后仍然引發(fā)媒體錯誤hls.recoverMediaError(),調(diào)用此方法可能有助于解決音頻編解碼器不匹配的問題。工作流程應(yīng)該是:
關(guān)于第一媒體錯誤:調(diào)用 hls.recoverMediaError()
如果在第一個媒體錯誤之后“快速”引發(fā)另一個媒體錯誤:首先調(diào)用hls.swapAudioCodec(),然后調(diào)用hls.recoverMediaError()。
5. 切換播放源
首先檢查hls
對象是否已經(jīng)定義,如果已定義,則停止當(dāng)前的播放器實(shí)例。然后創(chuàng)建新的播放器實(shí)例,綁定到video元素,并開始加載新的播放源。加載成功后,播放器會自動開始播放新的視頻內(nèi)容。如果在加載過程中發(fā)生錯誤,會有相應(yīng)的錯誤處理邏輯。
if (typeof hls !== 'undefined') { // 停止當(dāng)前的播放器實(shí)例 hls.destroy(); } // 新的播放源URL var newVideoUrl = 'new_source_url.m3u8'; // 創(chuàng)建新的HLS播放器實(shí)例 var hls = new Hls(); // 綁定到video元素 var video = document.getElementById('video'); hls.attachMedia(video); // 監(jiān)聽加載事件 hls.on(Hls.Events.MANIFEST_PARSED, function () { video.play(); }); // 錯誤處理 hls.on(Hls.Events.ERROR, function (event, data) { if (data.fatal) { switch (data.type) { case Hls.ErrorTypes.NETWORK_ERROR: // 網(wǎng)絡(luò)錯誤處理 break; case Hls.ErrorTypes.MEDIA_ERROR: // 媒體錯誤處理 break; default: // 其他錯誤處理 break; } } }); // 加載新的播放源 hls.loadSource(newVideoUrl);
二、播放.flv
Flv.js 是 HTML5 Flash 視頻(FLV)播放器,純原生 JavaScript 開發(fā),沒有用到 Flash。由 bilibili 網(wǎng)站開源。它的工作原理是將 FLV 文件流轉(zhuǎn)碼復(fù)用成 ISO BMFF(MP4 碎片)片段,然后通過 Media Source Extensions 將 MP4 片段喂進(jìn)瀏覽器。
1、安裝flv.js
npm i flv.js
2、使用flv.js實(shí)現(xiàn)播放flv格式流,獲取video節(jié)點(diǎn)
import flvjs from 'flv.js' let videoElement = document.getElementById('my-player'); if (flvjs.isSupported()) { flvPlayer = flvjs.createPlayer({ type: 'flv', //媒體類型 url: 'XXXX' //flv格式媒體URL isLive: true, //數(shù)據(jù)源是否為直播流 hasAudio: false, //數(shù)據(jù)源是否包含有音頻 hasVideo: true, //數(shù)據(jù)源是否包含有視頻 enableStashBuffer: false //是否啟用緩存區(qū) },{ enableWorker: false, //不啟用分離線程 enableStashBuffer: false, //關(guān)閉IO隱藏緩沖區(qū) autoCleanupSourceBuffer: true //自動清除緩存 }); flvPlayer.attachMediaElement(videoElement); //將播放實(shí)例注冊到節(jié)點(diǎn) flvPlayer.load(); //加載數(shù)據(jù)流 flvPlayer.play(); //播放數(shù)據(jù)流 }
3、關(guān)閉視頻流
flvPlayer.pause(); //暫停播放數(shù)據(jù)流 flvPlayer.unload(); //取消數(shù)據(jù)流加載 flvPlayer.detachMediaElement(); //將播放實(shí)例從節(jié)點(diǎn)中取出 flvPlayer.destroy(); //銷毀播放實(shí)例
4、flv.js常用方法
1:flvjs.isSupported():判斷當(dāng)前瀏覽器是否支持播放 2:flvPlayer = flvjs.createPlayer(mediaDataSource: MediaDataSource, config?: Config):創(chuàng)建一個播放實(shí)例 3:flvPlayer.attachMediaElement(mediaElement: HTMLMediaElement):將播放實(shí)例注冊到video節(jié)點(diǎn) 4:flvPlayer.load():加載數(shù)據(jù)流 5:flvPlayer.play():播放數(shù)據(jù)流 6:flvPlayer.pause():暫停播放數(shù)據(jù)流 7:flvPlayer.unload():取消數(shù)據(jù)流加載 8:flvPlayer.detachMediaElement():將播放實(shí)例從節(jié)點(diǎn)中取出 9:flvPlayer.destroy():銷毀播放實(shí)例
參考文檔
到此這篇關(guān)于前端在瀏覽器端播放直播流協(xié)議的2種方式講解的文章就介紹到這了,更多相關(guān)前端瀏覽器端播放直播流協(xié)議內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript樹的深度優(yōu)先遍歷和廣度優(yōu)先遍歷算法示例
這篇文章主要介紹了JavaScript樹的深度優(yōu)先遍歷和廣度優(yōu)先遍歷算法,結(jié)合實(shí)例形式分析了JavaScript樹的深度優(yōu)先遍歷、廣度優(yōu)先遍歷遞歸與非遞歸相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2018-07-07JS獲取表格內(nèi)指定單元格html內(nèi)容的方法
這篇文章主要介紹了JS獲取表格內(nèi)指定單元格html內(nèi)容的方法,涉及javascript中innerHTML屬性的使用技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-03-03JSON 的正確用法探討:Pyhong、MongoDB、JavaScript與Ajax
這篇文章主要介紹了JSON 的正確用法探討:Pyhong、MongoDB、JavaScript與Ajax的相關(guān)資料,具有參考借鑒價值,需要的朋友一起學(xué)習(xí)吧2016-05-05原生JS實(shí)現(xiàn)的簡單輪播圖功能【適合新手】
這篇文章主要介紹了原生JS實(shí)現(xiàn)的簡單輪播圖功能,結(jié)合實(shí)例形式分析了基于javascript定時器控制頁面元素動態(tài)變換實(shí)現(xiàn)輪播圖的相關(guān)操作技巧,需要的朋友可以參考下2018-08-08javascript 控制input只允許輸入的各種指定內(nèi)容
這篇文章主要介紹了通過javascript控制input只允許輸入的各種指定內(nèi)容,需要的朋友可以參考下2014-06-06