基于hls.js封装一个vue视频组件

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,比如错误处理的更人性化设置....基本已实现,后续有空再接着记录一下。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值