vue+flvjs實現自定義控制條的流媒體播放器
flvjs與FLV有什么區別和聯系?
flv.js
是 HTML5 Flash 視頻(FLV)播放器,純原生 JavaScript 開發,沒有用到 Flash。由 bilibili 網站開源(Github)。
概覽:
一個實現了在 HTML5 視頻中播放 FLV 格式視頻的 JavaScript 庫。它的工作原理是將 FLV 文件流轉碼復用成 ISO BMFF(MP4 碎片)片段,然后通過 Media Source Extensions 將 MP4 片段喂進瀏覽器。
flv.js 是使用 ECMAScript 6 編寫的,然后通過 Babel Compiler 編譯成 ECMAScript 5,使用 Browserify 打包。
功能:
- FLV 容器,具有 H.264 + AAC 編解碼器播放功能
- 多部分分段視頻播放
- HTTP FLV 低延遲實時流播放
- FLV 通過 WebSocket 實時流播放
- 兼容 Chrome, FireFox, Safari 10, IE11 和 Edge
- 十分低開銷,並且通過你的瀏覽器進行硬件加速
FLV
HTTP FLV則是將RTMP封裝在HTTP協議之上的,可以更好的穿透防火牆等。rtmp和http-flv的視頻格式都是flv格式的,只是傳輸協議而不同。rtmp是tcp的傳輸協議,而http-flv是http長鏈接的傳輸協議。
總結
flvjs是一個H5播放器。FLV是一種協議。flvjs可以用於播放FLV格式的視頻。
幾種視頻流比較。
協議 | http-flv | rtmp | hls |
---|---|---|---|
傳輸方式 | http流 | tcp流 | http流 |
視頻封裝格式 | flv | flv | Ts文件 |
延遲 | 低 | 低 | 高 |
數據分段 | 連續流 | 連續流 | 切片文件 |
h5播放 | flv.js | video.js | hls.js |
vue中使用flvjs。
1.使用npm安裝flv.js
npm install --save flv.js
2.新建FlvLive.vue文件,在文件中引入
import flvjs from 'flv.js'
3.在template標簽中添加代碼
<figure
ref="videoContainer"
data-fullscreen="false"
>
<video
ref="video"
autoplay
>
Your browser is too old which doesn't support HTML5 video.
</video>
</figure>
4.在created中加入以下代碼
this.$nextTick(() => {
if (flvjs.isSupported()) {
const flvPlayer = flvjs.createPlayer({
type: 'flv',
isLive: true,
url: this.src,
});
flvPlayer.attachMediaElement(this.$refs.video);
flvPlayer.load();
flvPlayer.play();
this.flvPlayer = flvPlayer;
}
});
flvjs.isSupported()
判斷當前瀏覽器是否支持flv。
flvPlayer.attachMediaElement(this.$refs.video)
掛載video標簽。
也可以使用如下方式:
<video
id="videoEdlement"
autoplay
>
Your browser is too old which doesn't support HTML5 video.
</video>
js
const id = document.getElementById('videoEdlement')
flvPlayer.attachMediaElement(id)
使用這種方式會導致組件無法復用。除非給video傳入不同的id的值。
5.傳入src,一個簡單的播放器就完成了。也可以在video標簽中加入controls
屬性以利用H5播放器自帶的控制條。
自定義控制條。
效果圖,畫面是ffmpeg推的一個mp4的流。紅框部分為控制條。
使用全屏API
這里使用webkitRequestFullScreen()
API實現全屏功能。
webkitRequestFullScreen()
方法用於發出異步請求使元素進入全屏模式。來自MDN教程的解釋。
使用全屏API時需要注意,如果全屏的元素是video,自定義的控制條會被全屏后的video元素覆蓋住,更改z-index也不能解決。所以要放大video的父級元素。
this.$refs.videoContainer.webkitRequestFullScreen();
CSS部分
設置全屏時的背景,隱藏全屏時video標簽中的控制條。
/* fullscreen */
html:-ms-fullscreen {
width: 100%;
}
:-webkit-full-screen {
background: #666;
}
figure[data-fullscreen='true'] {
max-width: 100%;
width: 100%;
margin: 0;
padding: 0;
/* hide controls on fullscreen with WebKit */
video::-webkit-media-controls {
display: none !important;
}
}
figure[data-fullscreen='true'] {...}
在點擊全屏按鈕時會改變這個屬性。體現在如下代碼中。
setFullscreenData(state) {
this.$refs.videoContainer.setAttribute(
'data-fullscreen',
Boolean(state),
);
},
判斷當前頁面是否處於全屏狀態
對應不同的瀏覽器內核做兼容處理。
isFullScreen() {
return Boolean(
document.fullScreen ||
document.webkitIsFullScreen ||
document.mozFullScreen ||
document.msFullscreenElement ||
document.fullscreenElement,
);
},
開發中遇到的報錯
Uncaught (in promise) DOMException:The play() request was interrupted by a new load request
報錯信息表示:視頻還沒有准備好,就已經開始播放了。這種情況會出現在,視頻地址錯誤的情況下。常常是地址為空,或者格式錯誤。
Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause().
調用play()的時候,音頻文件還沒有加載完成導致的問題。建議給video標簽加上autoplay。不然老是出現這個問題。到底是什么原因導致的還不知道。
同一頁面中引入4個畫面時,其他三個畫面會報錯。video標簽的id一致導致的。
總結
本文通過實現一個自定義控制條的H5播放器,來學習相關的內容,包括:flvjs在vue中的使用。js的全屏API。以及一個document的一些內置對象的使用。
完整代碼:gitee