Ctrl + CV 即用
官方定义:
hls.js是一个JavaScript库,可实现HTTP Live Streaming客戶端,它可以直接在video标签上运行。
<template>
<div class="video-play" :class="{ 'video-bg-wrap': !videoId }">
<video v-show="!error" :id="videoId" autoplay muted></video>
</div>
</template>
<script>
import Hls from "hls.js";
export default {
props: {
videoId: {
type: String,
required: true,
default: () => "",
},
videoUrl: {
type: String,
default: () => "",
}
},
data() {
return {
hls: null,
error: false,
};
},
watch: {
videoUrl: {
handler(val) {
setTimeout(() => {
this.playVideo(this.videoId, val);
}, 1000);
},
deep: true,
immediate: true,
},
},
mounted() {
this.playVideo(this.videoId, this.videoUrl);
},
methods: {
playVideo(id, url) {
if (id && url) {
this.showloading = true;
this.error = false;
let video = document.getElementById(id);
this.hls = new Hls();
this.hls.attachMedia(video);
this.hls.on(Hls.Events.MEDIA_ATTACHED, () => {
this.hls.loadSource(url);
});
this.hls.on(Hls.Events.MANIFEST_PARSED, (event, data) => {
this.showloading = false;
});
this.hls.on(Hls.Events.ERROR, (event, data) => {
console.log("MANIFEST_ERROR", id, url, event, data);
if (data.fatal) {
this.showloading = false;
this.error = true;
this.hls.stopLoad();
switch (data.type) {
case Hls.ErrorTypes.NETWORK_ERROR:
//
break;
case Hls.ErrorTypes.MEDIA_ERROR:
//
break;
default:
this.hls.destroy()
break;
}
}
});
}
},
},
unmounted() {
if (this.hls) {
this.hls?.detachMedia();
this.hls?.destroy();
}
this.hls = null;
},
beforeRouteLeave(to, from, next) {
if (this.hls) {
this.hls.detachMedia();
this.hls.destroy();
next();
}
},
};
</script>
<style lang="scss" scoped>
.video-play {
width: 100%;
height: 100%;
position: relative;
video {
object-fit: fill;
height: 100%;
width: 100%;
}
}
</style>
条件控制:
如果使用判断条件控制video的显隐,建议v-show。
v-if在初始化的状态下没有问题,但是在v-if条件为false,video销毁,而后条件为true重建的时候,会因为video标签加载过慢导致使用getElementById取dom为null,也就是attachMedia(video)挂载了个寂寞, 等video标签渲染完成后也,也就没有播放来源。
结果就是播放页面黑屏,但是在网络请求里还在不停的解析ts流。使用v-if,可以在loadSource之前setTimeOut,等待video重新加载完成后再进行后续操作。
错误处理:
fatal为false,错误不致命,hls.js尝试处理;
fatal为true,致命错误,需要手动处理:官方提供了hls.startLoad()和
hls.recoverMediaError()分别处理网络错误和播放器媒体错误,也可以不做处理,直接destroy(),重新走一遍playVideo()的流程。
持续优化:
以上仅仅是hls.js的入门级应用,真实项目中可以给组件丰富完善更多的功能,比如视频窗口全屏,比如加载loading,比如错误处理的更人性化设置....基本已实现,后续有空再接着记录一下。