npm i flv.js --save
<template>
<div class="container">
<!-- 正常播放 -->
<video class="player" muted v-show="!isError"></video>
<!-- 播放失败显示图片 -->
<img src="@/assets/img/video_err.png" v-show="isError" width="100%" height="100%" />
<!-- 控制栏 -->
<div class="video-control">
<!-- 调节音量 -->
<el-slider v-model="audioNum" style="width:70px;margin-right:15px;" :min="0" :max="100" @input="changeAudio"></el-slider>
<!-- 控制全屏 -->
<i class="control-btn fa fa-arrows-alt" v-if="!isFullScreen" @click.stop="fullscreen(true)"></i>
<i class="control-btn fa fa-compress" v-else @click.stop="fullscreen(false)"></i>
</div>
</div>
</template>
<script>
import flvjs from 'flv.js/dist/flv.min.js';
export default {
data() {
return {
livePlayer: null,
isError: false,
isFullScreen: false,
audioNum: 0, // 播放音量值
videoUrl: "http://xxx.flv"
};
},
mounted() {
// 监听全屏
document.addEventListener('fullscreenchange', this.changeFullscreen);
this.createPlayVideo();
},
beforeDestroy() {
document.removeEventListener('fullscreenchange', this.changeFullscreen);
this.destroyPlayer();
},
methods: {
fullscreen(value) {
let dom = document.querySelector('.container');
this.$nextTick(() => {
if (value) {
dom.requestFullscreen();
} else {
document.exitFullscreen();
}
});
},
changeFullscreen() {
this.isFullScreen = !this.isFullScreen;
let dom = document.querySelector('.container');
this.$nextTick(() => {
if (this.isFullScreen) {
dom.requestFullscreen();
} else {
document.exitFullscreen();
}
});
},
createPlayVideo() {
this.isError = false;
let that = this;
let videoElement = document.querySelector(".player");
if (flvjs.isSupported() && videoElement) {
this.livePlayer = flvjs.createPlayer({
type: 'flv',
url: this.videoUrl,
isLive: true,
});
this.livePlayer.attachMediaElement(videoElement);
this.livePlayer.load();
this.livePlayer.play();
this.livePlayer.on(flvjs.Events.ERROR, (errorType, errorDetail, errorInfo) => {
that.isError = true;
if (that.livePlayer && that.livePlayer != null && errorDetail == "UnrecoverableEarlyEof") {
that.livePlayer.pause();
that.livePlayer.unload();
that.livePlayer.detachMediaElement();
that.livePlayer.destroy();
that.livePlayer = null;
// 视频出错后销毁重建
that.$nextTick(() => {
that.createPlayVideo();
})
}
});
}
},
destroyPlayer() {
if (this.livePlayer && this.livePlayer !== null) {
try {
this.livePlayer.pause();
this.livePlayer.unload();
this.livePlayer.detachMediaElement();
this.livePlayer.destroy();
this.livePlayer = null;
} catch (err) {
console.log(err)
}
}
},
// 改变音量
changeAudio() {
setTimeout(() => {
if (this.livePlayer.volume || this.livePlayer.volume == 0) {
this.livePlayer.volume = this.audioNum / 100;
if (this.livePlayer.volume == 0) {
this.livePlayer.muted = true;
} else {
this.livePlayer.muted = false;
}
}
}, 200);
},
},
};
</script>
<style lang="stylus" scoped>
.container {
width: 800px;
height: 450px;
position: relative;
.player {
width: 100%;
height: 100%;
}
.video-control {
width: 100%;
height: 30px;
position: absolute;
bottom: 0;
left: 0;
background: #333333;
display: flex;
justify-content: flex-end;
align-items: center;
box-sizing: border-box;
padding: 0 10px;
}
.control-btn {
color: #dbdbdb;
font-size: 16px;
cursor: pointer;
margin-right: 10px;
cursor: pointer;
}
}
</style>