vue2之jessibuca视频插件使用教程

跳跳的小古风 2024-09-06 13:33:01 阅读 73

vue2之jessibuca视频插件使用教程

jessibuca简介前期准备下载相关jsvue index.html文件引入

组件封装使用小知识 引入iconfont

jessibuca简介

Jessibuca是一款开源的纯H5直播流播放器,通过Emscripten将音视频解码库编译成Js(ams.js/wasm)运行于浏览器之中。兼容几乎所有浏览器,可以运行在PC、手机、微信中,无需额外安装插件。

前期准备

下载相关js

从官网下载相关压缩包将文件移入自身项目中,并根据自身vue版本放入Public或者Static文件夹下。

jessibuca官网-源码下载链接

在这里插入图片描述

解压后的文件

在这里插入图片描述

vue index.html文件引入

<code><script type="text/javascript" src="/jessibuca/jessibuca.js"></script>code>

组件封装

<template>

<div

ref="container"code>

@dblclick="fullscreenSwich"code>

style="width: 100%; height: 100%; background-color: #000000; margin: 0 auto; position: relative"code>

>

<div

class="buttons-box"code>

id="buttonsBox"code>

>

<div class="buttons-box-left">code>

<i

v-if="!playing"code>

class="iconfont icon-play jessibuca-btn"code>

@click="playBtnClick"code>

></i>

<i

v-if="playing"code>

class="iconfont icon-pause jessibuca-btn"code>

@click="pause"code>

></i>

<i

class="iconfont icon-stop jessibuca-btn"code>

@click="destroy"code>

></i>

<i

v-if="isNotMute"code>

class="iconfont icon-audio-high jessibuca-btn"code>

@click="mute()"code>

></i>

<i

v-if="!isNotMute"code>

class="iconfont icon-audio-mute jessibuca-btn"code>

@click="cancelMute()"code>

></i>

</div>

<div class="buttons-box-right">code>

<span class="jessibuca-btn">{ -- -->{ kBps }} kb/s</span>code>

<i

class="iconfont icon-camera1196054easyiconnet jessibuca-btn"code>

@click="screenshot"code>

style="font-size: 1rem !important"code>

></i>

<i

class="iconfont icon-shuaxin11 jessibuca-btn"code>

@click="playBtnClick"code>

></i>

<i

v-if="!fullscreen"code>

class="iconfont icon-weibiaoti10 jessibuca-btn"code>

@click="fullscreenSwich"code>

></i>

<i

v-if="fullscreen"code>

class="iconfont icon-weibiaoti11 jessibuca-btn"code>

@click="fullscreenSwich"code>

></i>

<i

style="font-size: 28px"code>

class="iconfont icon-video-close jessibuca-btn"code>

@click="closeVideo()"code>

></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的时候,是否自动降级到wasm模式。

background: "", //背景图片

controlAutoHide: false, //底部控制台是否自动隐藏

debug: false, //是否开启控制台调试打印

decoder: "/jessibuca/decoder.js",

hasAudio: typeof this.hasAudio == "undefined" ? true : this.hasAudio, // 是否有音频,如果设置false,则不对音频数据解码,提升性能。

hasVideo: true, // 是否开启控制台调试打印

heartTimeout: 5, //设置超时时长, 单位秒播放中途,如果超过设定时长无数据返回,则回调timeout事件

heartTimeoutReplay: true, //是否开启心跳超时之后自动再播放

heartTimeoutReplayTimes: 3, //重试次数 heartTimeoutReplay 重试失败之后,不再重新播放视频地址。如果想无限次重试,可以设置为-1

hiddenAutoPause: false, //是否开启当页面的'visibilityState'变为'hidden'的时候,自动暂停播放。

hotKey: false, //是否开启键盘快捷键 esc -> 退出全屏;arrowUp -> 声音增加;arrowDown -> 声音减少;

isFlv: false, //当为true的时候:ws协议不检验是否以.flv为依据,进行协议解析。

isFullResize: false, //当为true的时候:视频画面做等比缩放后,完全填充canvas区域,画面不被拉伸,没有黑边,但画面显示不全

isNotMute: this.isNotMute, // 是否开启声音,默认是关闭声音播放的。

isResize: false, //当为true的时候:视频画面做等比缩放后,高或宽对齐canvas区域,画面不被拉伸,但有黑边。 当为false的时候:视频画面完全填充canvas区域,画面会被拉伸。

keepScreenOn: false, //开启屏幕常亮,在手机浏览器上, canvas标签渲染视频并不会像video标签那样保持屏幕常亮。PC端不会生效,仅手机端生效

loadingText: "请稍等, 视频加载中......", // 视频加载转圈时的提示文字

loadingTimeout: 10, //当play()的时候,如果没有数据返回,则回调

loadingTimeoutReplay: true, ///是否开启loading超时之后自动再播放

loadingTimeoutReplayTimes: 3, //loadingTimeoutReplay 重试失败之后,不再重新播放视频地址。

operateBtns: {

// 配置操作按钮 其中

fullscreen: false, //全屏按钮

screenshot: false, //截图按钮

play: false, //播放暂停按钮

audio: false, //声音按钮

record: false, //录制按钮

},

recordType: "webm", //默认录制的视频格式

rotate: 0, //设置旋转角度

showBandwidth: false, // 显示网速

supportDblclickFullscreen: false, // 是否支持屏幕的双击事件,触发全屏,取消全屏事件。

timeout: 10, //设置超时时长, 单位秒在连接成功之前(loading)和播放中途(heart),如果超过设定时长无数据返回,则回调timeout事件

useMSE: location.hostname !== "localhost" && location.protocol !== "https:", //是否开启MediaSource硬解码

useWCS: location.hostname === "localhost" || location.protocol === "https", //是否开启Webcodecs硬解码

useWebFullScreen: false, //是否使用web全屏(旋转90度)(只会在移动端生效)。

videoBuffer: 0, // 设置最大缓冲时长,单位秒,播放器会自动消除延迟。

wasmDecodeErrorReplay: true, // 是否开启解码失败重新播放

wcsUseVideoRender: true, //webcodecs硬解码是否通过video标签渲染

},

options

)

);

let jessibuca = jessibucaPlayer[this._uid];

let _this = this;

// 监听 jessibuca 初始化事件。

jessibuca.on("load", function () {

// console.log("on load init");

});

// 信息,包含错误信息

jessibuca.on("log", function (msg) {

// console.log("on log", msg);

});

// 触发暂停事件

jessibuca.on("pause", function () {

_this.playing = false;

});

// 触发播放事件

jessibuca.on("play", function () {

_this.playing = true;

});

// 当前是否全屏

jessibuca.on("fullscreen", function (msg) {

// console.log("on fullscreen", msg);

_this.fullscreen = msg;

});

// 触发声音事件,返回boolean值

jessibuca.on("mute", function (msg) {

// console.log("on mute", msg);

_this.isNotMute = !msg;

});

// 当解析出音频信息时回调,2个回调参数

// numOfChannels:声频通道

// sampleRate 采样率

// encTypeCode 音频编码类型(10:aac,7:ALAW(g711a),8:MULAW(g711u))

// encType 音频编码类型(字符串)

jessibuca.on("audioInfo", function (msg) {

// console.log("audioInfo", msg);

});

let _ts = 0;

// 当前视频帧pts,单位毫秒ms

jessibuca.on("timeUpdate", function (ts) {

_ts = ts;

});

// 当解析出视频信息时回调,2个回调参数

//width:视频宽

//height:视频高

//encTypeCode 视频编码类型(10:h264,12:h265)

//encType 视频编码类型(字符串)

jessibuca.on("videoInfo", function (info) {

// console.log("videoInfo", info);

});

// 错误信息

// 目前已有的错误信息:

// jessibuca.ERROR.playError ;播放错误,url 为空的时候,调用play方法

// jessibuca.ERROR.fetchError ;http 请求失败

// jessibuca.ERROR.websocketError; websocket 请求失败

// jessibuca.ERROR.webcodecsH265NotSupport; webcodecs 解码 h265 失败

// jessibuca.ERROR.mediaSourceH265NotSupport; mediaSource 解码 h265 失败

// jessibuca.ERROR.wasmDecodeError ; wasm 解码失败

jessibuca.on("error", function (error) {

// console.log("error", error);

});

// 当设定的超时时间内无数据返回,则回调

jessibuca.on("timeout", function () {

// console.log("timeout");

});

// 渲染开始

jessibuca.on("start", function () {

// console.log("start");

});

// 渲染性能统计,流开始播放后回调,每秒1次。

// 0: 表示卡顿

// 1: 表示流畅

// 2: 表示非常流程

jessibuca.on("performance", function (performance) {

let show = "卡顿";

if (performance === 2) {

show = "非常流畅";

} else if (performance === 1) {

show = "流畅";

}

_this.performance = show;

});

// 流状态统计,流开始播放后回调,每秒1次。

// buf: 当前缓冲区时长,单位毫秒,

// fps: 当前视频帧率,

// abps: 当前音频码率,单位byte,

// vbps: 当前视频码率,单位byte,

// ts:当前视频帧pts,单位毫秒

jessibuca.on("stats", function (stats) { });

// 当前网速, 单位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"code>

ref="player"code>

:videoUrl="videoUrl"code>

@videoClose="onVideoClose"code>

/>

---

videoUrl:'直播流url地址'

onVideoClose() {

this.$set(this.videoUrl, "");

},

小知识 引入iconfont

将iconfont 下载好的图标 放入assets即可,该字体已上传

在这里插入图片描述



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。