vue2之jessibuca視頻插件使用教程詳細(xì)講解
jessibuca簡(jiǎn)介
Jessibuca是一款開(kāi)源的純H5直播流播放器,通過(guò)Emscripten將音視頻解碼庫(kù)編譯成Js(ams.js/wasm)運(yùn)行于瀏覽器之中。兼容幾乎所有瀏覽器,可以運(yùn)行在PC、手機(jī)、微信中,無(wú)需額外安裝插件。
前期準(zhǔn)備
下載相關(guān)js
從官網(wǎng)下載相關(guān)壓縮包將文件移入自身項(xiàng)目中,并根據(jù)自身vue版本放入Public或者Static文件夾下。
jessibuca官網(wǎng)-源碼下載鏈接 或者 點(diǎn)擊這里下載



vue index.html文件引入
<script type="text/javascript" src="/jessibuca/jessibuca.js"></script>
組件封裝
<template>
<div
ref="container"
@dblclick="fullscreenSwich"
style="width: 100%; height: 100%; background-color: #000000; margin: 0 auto; position: relative"
>
<div
class="buttons-box"
id="buttonsBox"
>
<div class="buttons-box-left">
<i
v-if="!playing"
class="iconfont icon-play jessibuca-btn"
@click="playBtnClick"
></i>
<i
v-if="playing"
class="iconfont icon-pause jessibuca-btn"
@click="pause"
></i>
<i
class="iconfont icon-stop jessibuca-btn"
@click="destroy"
></i>
<i
v-if="isNotMute"
class="iconfont icon-audio-high jessibuca-btn"
@click="mute()"
></i>
<i
v-if="!isNotMute"
class="iconfont icon-audio-mute jessibuca-btn"
@click="cancelMute()"
></i>
</div>
<div class="buttons-box-right">
<span class="jessibuca-btn">{{ kBps }} kb/s</span>
<i
class="iconfont icon-camera1196054easyiconnet jessibuca-btn"
@click="screenshot"
style="font-size: 1rem !important"
></i>
<i
class="iconfont icon-shuaxin11 jessibuca-btn"
@click="playBtnClick"
></i>
<i
v-if="!fullscreen"
class="iconfont icon-weibiaoti10 jessibuca-btn"
@click="fullscreenSwich"
></i>
<i
v-if="fullscreen"
class="iconfont icon-weibiaoti11 jessibuca-btn"
@click="fullscreenSwich"
></i>
<i
style="font-size: 28px"
class="iconfont icon-video-close jessibuca-btn"
@click="closeVideo()"
></i>
</div>
</div>
</div>
</template>
<script>
let jessibucaPlayer = {};
export default {
name: "wkVideoPlayer",
data() {
return {
playing: false,
isNotMute: false,
quieting: false,
fullscreen: false,
loaded: false, // mute
speed: 0,
performance: "", // 工作情況
kBps: 0,
btnDom: null,
};
},
props: ["videoUrl", "error", "hasAudio", "height"],
mounted() {
this.$nextTick(() => {
this.updatePlayerDomSize();
this.btnDom = document.getElementById("buttonsBox");
window.onresize = () => {
this.updatePlayerDomSize();
};
if (this.videoUrl) {
this.play(this.videoUrl);
} else {
return;
}
});
},
watch: {
videoUrl(newData) {
this.play(newData);
},
immediate: true,
},
methods: {
updatePlayerDomSize() {
let dom = this.$refs.container;
let width = dom.parentNode.clientWidth;
let height = dom.parentNode.clientHeight;
const clientHeight = Math.min(
document.body.clientHeight,
document.documentElement.clientHeight
);
if (height > clientHeight) {
height = clientHeight;
width = (16 / 9) * height;
}
dom.style.width = width + "px";
dom.style.height = height + "px";
},
create() {
let options = {};
jessibucaPlayer[this._uid] = new window.Jessibuca(
Object.assign(
{
container: this.$refs.container,
autoWasm: true, // 在使用MSE或者Webcodecs 播放H265的時(shí)候,是否自動(dòng)降級(jí)到wasm模式。
background: "", //背景圖片
controlAutoHide: false, //底部控制臺(tái)是否自動(dòng)隱藏
debug: false, //是否開(kāi)啟控制臺(tái)調(diào)試打印
decoder: "/jessibuca/decoder.js",
hasAudio: typeof this.hasAudio == "undefined" ? true : this.hasAudio, // 是否有音頻,如果設(shè)置false,則不對(duì)音頻數(shù)據(jù)解碼,提升性能。
hasVideo: true, // 是否開(kāi)啟控制臺(tái)調(diào)試打印
heartTimeout: 5, //設(shè)置超時(shí)時(shí)長(zhǎng), 單位秒播放中途,如果超過(guò)設(shè)定時(shí)長(zhǎng)無(wú)數(shù)據(jù)返回,則回調(diào)timeout事件
heartTimeoutReplay: true, //是否開(kāi)啟心跳超時(shí)之后自動(dòng)再播放
heartTimeoutReplayTimes: 3, //重試次數(shù) heartTimeoutReplay 重試失敗之后,不再重新播放視頻地址。如果想無(wú)限次重試,可以設(shè)置為-1
hiddenAutoPause: false, //是否開(kāi)啟當(dāng)頁(yè)面的'visibilityState'變?yōu)?hidden'的時(shí)候,自動(dòng)暫停播放。
hotKey: false, //是否開(kāi)啟鍵盤(pán)快捷鍵 esc -> 退出全屏;arrowUp -> 聲音增加;arrowDown -> 聲音減少;
isFlv: false, //當(dāng)為true的時(shí)候:ws協(xié)議不檢驗(yàn)是否以.flv為依據(jù),進(jìn)行協(xié)議解析。
isFullResize: false, //當(dāng)為true的時(shí)候:視頻畫(huà)面做等比縮放后,完全填充canvas區(qū)域,畫(huà)面不被拉伸,沒(méi)有黑邊,但畫(huà)面顯示不全
isNotMute: this.isNotMute, // 是否開(kāi)啟聲音,默認(rèn)是關(guān)閉聲音播放的。
isResize: false, //當(dāng)為true的時(shí)候:視頻畫(huà)面做等比縮放后,高或?qū)拰?duì)齊canvas區(qū)域,畫(huà)面不被拉伸,但有黑邊。 當(dāng)為false的時(shí)候:視頻畫(huà)面完全填充canvas區(qū)域,畫(huà)面會(huì)被拉伸。
keepScreenOn: false, //開(kāi)啟屏幕常亮,在手機(jī)瀏覽器上, canvas標(biāo)簽渲染視頻并不會(huì)像video標(biāo)簽?zāi)菢颖3制聊怀A?。PC端不會(huì)生效,僅手機(jī)端生效
loadingText: "請(qǐng)稍等, 視頻加載中......", // 視頻加載轉(zhuǎn)圈時(shí)的提示文字
loadingTimeout: 10, //當(dāng)play()的時(shí)候,如果沒(méi)有數(shù)據(jù)返回,則回調(diào)
loadingTimeoutReplay: true, ///是否開(kāi)啟loading超時(shí)之后自動(dòng)再播放
loadingTimeoutReplayTimes: 3, //loadingTimeoutReplay 重試失敗之后,不再重新播放視頻地址。
operateBtns: {
// 配置操作按鈕 其中
fullscreen: false, //全屏按鈕
screenshot: false, //截圖按鈕
play: false, //播放暫停按鈕
audio: false, //聲音按鈕
record: false, //錄制按鈕
},
recordType: "webm", //默認(rèn)錄制的視頻格式
rotate: 0, //設(shè)置旋轉(zhuǎn)角度
showBandwidth: false, // 顯示網(wǎng)速
supportDblclickFullscreen: false, // 是否支持屏幕的雙擊事件,觸發(fā)全屏,取消全屏事件。
timeout: 10, //設(shè)置超時(shí)時(shí)長(zhǎng), 單位秒在連接成功之前(loading)和播放中途(heart),如果超過(guò)設(shè)定時(shí)長(zhǎng)無(wú)數(shù)據(jù)返回,則回調(diào)timeout事件
useMSE: location.hostname !== "localhost" && location.protocol !== "https:", //是否開(kāi)啟MediaSource硬解碼
useWCS: location.hostname === "localhost" || location.protocol === "https", //是否開(kāi)啟Webcodecs硬解碼
useWebFullScreen: false, //是否使用web全屏(旋轉(zhuǎn)90度)(只會(huì)在移動(dòng)端生效)。
videoBuffer: 0, // 設(shè)置最大緩沖時(shí)長(zhǎng),單位秒,播放器會(huì)自動(dòng)消除延遲。
wasmDecodeErrorReplay: true, // 是否開(kāi)啟解碼失敗重新播放
wcsUseVideoRender: true, //webcodecs硬解碼是否通過(guò)video標(biāo)簽渲染
},
options
)
);
let jessibuca = jessibucaPlayer[this._uid];
let _this = this;
// 監(jiān)聽(tīng) jessibuca 初始化事件。
jessibuca.on("load", function () {
// console.log("on load init");
});
// 信息,包含錯(cuò)誤信息
jessibuca.on("log", function (msg) {
// console.log("on log", msg);
});
// 觸發(fā)暫停事件
jessibuca.on("pause", function () {
_this.playing = false;
});
// 觸發(fā)播放事件
jessibuca.on("play", function () {
_this.playing = true;
});
// 當(dāng)前是否全屏
jessibuca.on("fullscreen", function (msg) {
// console.log("on fullscreen", msg);
_this.fullscreen = msg;
});
// 觸發(fā)聲音事件,返回boolean值
jessibuca.on("mute", function (msg) {
// console.log("on mute", msg);
_this.isNotMute = !msg;
});
// 當(dāng)解析出音頻信息時(shí)回調(diào),2個(gè)回調(diào)參數(shù)
// numOfChannels:聲頻通道
// sampleRate 采樣率
// encTypeCode 音頻編碼類型(10:aac,7:ALAW(g711a),8:MULAW(g711u))
// encType 音頻編碼類型(字符串)
jessibuca.on("audioInfo", function (msg) {
// console.log("audioInfo", msg);
});
let _ts = 0;
// 當(dāng)前視頻幀pts,單位毫秒ms
jessibuca.on("timeUpdate", function (ts) {
_ts = ts;
});
// 當(dāng)解析出視頻信息時(shí)回調(diào),2個(gè)回調(diào)參數(shù)
//width:視頻寬
//height:視頻高
//encTypeCode 視頻編碼類型(10:h264,12:h265)
//encType 視頻編碼類型(字符串)
jessibuca.on("videoInfo", function (info) {
// console.log("videoInfo", info);
});
// 錯(cuò)誤信息
// 目前已有的錯(cuò)誤信息:
// jessibuca.ERROR.playError ;播放錯(cuò)誤,url 為空的時(shí)候,調(diào)用play方法
// jessibuca.ERROR.fetchError ;http 請(qǐng)求失敗
// jessibuca.ERROR.websocketError; websocket 請(qǐng)求失敗
// jessibuca.ERROR.webcodecsH265NotSupport; webcodecs 解碼 h265 失敗
// jessibuca.ERROR.mediaSourceH265NotSupport; mediaSource 解碼 h265 失敗
// jessibuca.ERROR.wasmDecodeError ; wasm 解碼失敗
jessibuca.on("error", function (error) {
// console.log("error", error);
});
// 當(dāng)設(shè)定的超時(shí)時(shí)間內(nèi)無(wú)數(shù)據(jù)返回,則回調(diào)
jessibuca.on("timeout", function () {
// console.log("timeout");
});
// 渲染開(kāi)始
jessibuca.on("start", function () {
// console.log("start");
});
// 渲染性能統(tǒng)計(jì),流開(kāi)始播放后回調(diào),每秒1次。
// 0: 表示卡頓
// 1: 表示流暢
// 2: 表示非常流程
jessibuca.on("performance", function (performance) {
let show = "卡頓";
if (performance === 2) {
show = "非常流暢";
} else if (performance === 1) {
show = "流暢";
}
_this.performance = show;
});
// 流狀態(tài)統(tǒng)計(jì),流開(kāi)始播放后回調(diào),每秒1次。
// buf: 當(dāng)前緩沖區(qū)時(shí)長(zhǎng),單位毫秒,
// fps: 當(dāng)前視頻幀率,
// abps: 當(dāng)前音頻碼率,單位byte,
// vbps: 當(dāng)前視頻碼率,單位byte,
// ts:當(dāng)前視頻幀pts,單位毫秒
jessibuca.on("stats", function (stats) {});
// 當(dāng)前網(wǎng)速, 單位KB 每秒1次,
jessibuca.on("kBps", function (kBps) {
_this.kBps = Math.round(kBps);
});
},
playBtnClick: function (event) {
this.play(this.videoUrl);
},
play: function (url) {
console.log(url);
if (jessibucaPlayer[this._uid]) {
this.destroy();
}
this.create();
jessibucaPlayer[this._uid].on("play", () => {
this.playing = true;
this.loaded = true;
this.quieting = jessibuca.quieting;
});
if (jessibucaPlayer[this._uid].hasLoaded()) {
jessibucaPlayer[this._uid].play(url);
} else {
jessibucaPlayer[this._uid].on("load", () => {
console.log("load 播放");
jessibucaPlayer[this._uid].play(url);
});
}
},
pause: function () {
if (jessibucaPlayer[this._uid]) {
jessibucaPlayer[this._uid].pause();
}
this.playing = false;
this.err = "";
this.performance = "";
},
screenshot: function () {
if (jessibucaPlayer[this._uid]) {
jessibucaPlayer[this._uid].screenshot();
}
},
mute: function () {
if (jessibucaPlayer[this._uid]) {
jessibucaPlayer[this._uid].mute();
}
},
cancelMute: function () {
if (jessibucaPlayer[this._uid]) {
jessibucaPlayer[this._uid].cancelMute();
}
},
destroy: function () {
if (jessibucaPlayer[this._uid]) {
jessibucaPlayer[this._uid].destroy();
}
if (document.getElementById("buttonsBox") == null) {
this.$refs.container.appendChild(this.btnDom);
}
jessibucaPlayer[this._uid] = null;
this.playing = false;
this.err = "";
this.performance = "";
},
eventcallbacK: function (type, message) {},
fullscreenSwich: function () {
let isFull = this.isFullscreen();
jessibucaPlayer[this._uid].setFullscreen(!isFull);
this.fullscreen = !isFull;
},
isFullscreen: function () {
return (
document.fullscreenElement ||
document.msFullscreenElement ||
document.mozFullScreenElement ||
document.webkitFullscreenElement ||
false
);
},
closeVideo: function () {
this.destroy();
this.$emit("videoClose");
},
},
};
</script>
<style>
.buttons-box {
width: 100%;
height: 28px;
background-color: rgba(43, 51, 63, 0.7);
position: absolute;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
left: 0;
bottom: 0;
user-select: none;
z-index: 10;
}
.jessibuca-btn {
width: 20px;
color: rgb(255, 255, 255);
line-height: 27px;
margin: 0px 10px;
padding: 0px 2px;
cursor: pointer;
text-align: center;
font-size: 0.8rem !important;
}
.buttons-box-right {
position: absolute;
right: 0;
}
@font-face {
font-family: "iconfont"; /* Project id 1291092 */
src: url("~@/assets/iconfont/iconfont.woff2?t=1673251105600") format("woff2");
}
.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-play:before {
content: "\e603";
}
.icon-pause:before {
content: "\e6c6";
}
.icon-stop:before {
content: "\e6a8";
}
.icon-audio-high:before {
content: "\e793";
}
.icon-audio-mute:before {
content: "\e792";
}
.icon-shuaxin11:before {
content: "\e720";
}
.icon-weibiaoti10:before {
content: "\e78f";
}
.icon-weibiaoti11:before {
content: "\e790";
}
.icon-camera1196054easyiconnet:before {
content: "\e791";
}
</style>
使用
<wk-video-player
class="video"
ref="player"
:videoUrl="videoUrl"
@videoClose="onVideoClose"
/>
---
videoUrl:'直播流url地址'
onVideoClose() {
this.$set(this.videoUrl, "");
},
小知識(shí) 引入iconfont
將iconfont 下載好的圖標(biāo) 放入assets即可,該字體已上傳

總結(jié)
到此這篇關(guān)于vue2之jessibuca視頻插件使用的文章就介紹到這了,更多相關(guān)vue2 jessibuca視頻插件使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue儲(chǔ)存storage時(shí)含有布爾值的解決方案
這篇文章主要介紹了vue儲(chǔ)存storage時(shí)含有布爾值的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06
vue使用keep-alive進(jìn)行組件緩存方法詳解(組件不緩存問(wèn)題解決)
keep-alive包裹動(dòng)態(tài)組件時(shí),會(huì)緩存不活動(dòng)的組件實(shí)例,而不是銷毀它們,下面這篇文章主要給大家介紹了關(guān)于vue使用keep-alive進(jìn)行組件緩存方法(組件不緩存問(wèn)題解決)的相關(guān)資料,需要的朋友可以參考下2022-09-09
VUE PC端可拖動(dòng)懸浮按鈕的實(shí)現(xiàn)代碼
這篇文章主要介紹了VUE PC端可拖動(dòng)懸浮按鈕的實(shí)現(xiàn)代碼,通過(guò)實(shí)例代碼介紹了父頁(yè)面引用的方法,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2024-02-02
Vue中的scoped實(shí)現(xiàn)原理及穿透方法
這篇文章主要介紹了Vue中的scoped實(shí)現(xiàn)原理及穿透方法,本文通過(guò)實(shí)例文字相結(jié)合的形式給大家介紹的非常詳細(xì),需要的朋友可以參考下2018-05-05
vue-echarts如何實(shí)現(xiàn)圖表組件封裝詳解
由于在項(xiàng)目中需要對(duì)數(shù)據(jù)進(jìn)行可視化處理,也就是用圖表展示,所以下面這篇文章主要給大家介紹了關(guān)于vue-echarts如何實(shí)現(xiàn)圖表組件封裝的相關(guān)資料,需要的朋友可以參考下2022-05-05
elementui如何解決el-table重復(fù)寫(xiě)loading問(wèn)題
這篇文章主要介紹了elementui如何解決el-table重復(fù)寫(xiě)loading問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08

