vue3使用flv.js播放推流视频的示例代码

 更新时间:2023年05月10日 14:19:41   作者:山野里的小菊花  
本文主要介绍了vue3使用flv.js播放推流视频的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

前言

本人是在vue3中使用flv.js处理推流时,遇到的一些问题,以及处理办法,归纳总结为一个组件,仅限于推流使用。

目前只贴出部分关键代码,若需要完整的代码,请往github下载

1、构建

    /**
     * @description: 构建播放器
     * @return {*}
     * @Author: liuxin
     */
    function flvCreated() {
      try {
        const videoElement = flvPlayerVideo.value;
        if (flvjs.isSupported() && videoElement) {
          addLog(`flv created,address:${prop.url}`);
          const flvOption = {
            url: prop.url, // 播放地址
            hasAudio: false, // 是否有音频
            hasVideo: true, //是否有视频
            isLive: true, // 是否是直播流,默认 true
            type: "flv", // 是否是直播流,默认 true
            stashInitialSize: 128, // 减少首帧显示等待时长
            ...prop.option,
          };
          state.flvPlayer = flvjs.createPlayer(flvOption, {
            enableWorker: false, // 不启用分离的线程进行转换,之前为true
            enableStashBuffer: false, // 关闭IO隐藏缓冲区
            stashInitialSize: 128, // 减少首帧显示等待时长
            autoCleanupSourceBuffer: true, // 打开自动清除缓存
            fixAudioTimestampGap: false, //false才会音视频同步,新增
            lazyLoad: false, // 去掉懒加载,新增
          });
          state.flvPlayer.attachMediaElement(videoElement);
          state.flvPlayer.load();
          state.flvPlayer.play();
          state.endedReloadFlag = true; // 重置画面停滞的播放状态,下次停滞了会再次打开
          videoElementEvent(); // 手动跳帧,防止延时
          flvPlayerEvent(); // 断流、卡顿处理
        }
      } catch (error) {
        console.error("构建错误", error);
      }
    }

2、销毁

    /**
     * @description: 销毁播放器
     * @return {*}
     * @Author: liuxin
     */
    function flvDestory() {
      if (state.delayTimer) {
        clearTimeout(state.delayTimer); // 清除推迟打开播放器定时器
      }
      if (state.flvPlayer == null) return; // 空对象,不执行销毁
      /* ----- 销毁开始 ----- */
      addLog(`flv destory,address:${prop.url}`);
      try {
        state.flvPlayer.off(flvjs.Events.ERROR, errorHandle);
        if (state.flvPlayer._hasPendingLoad) {
          state.flvPlayer.pause();
          state.flvPlayer.unload();
        }
        state.flvPlayer.detachMediaElement();
        state.flvPlayer.destroy();
        state.flvPlayer = null;
      } catch (error) {
        console.error("销毁错误");
      }
    }

3、断流、卡顿重连

      state.flvPlayer.on(flvjs.Events.STATISTICS_INFO, statisticsInfoHanle); // 断流重连
    /**
     * @description: 视频卡顿,销毁后重建
     * @param {*} errorType
     * @param {*} errorDetail
     * @param {*} errorInfo
     * @return {*}
     * @Author: liuxin
     */
    function statisticsInfoHanle(res) {
      // 初始化播放
      if (state.lastDecodedFrame == 0) {
        state.lastDecodedFrame = res.decodedFrames;
        return;
      }
      // 正常播放
      if (state.lastDecodedFrame != res.decodedFrames) {
        state.lastDecodedFrame = res.decodedFrames;
        state.loading = false; // 去掉loading动画
        state.errorCount = 0; // 错误连接次数归0
      }
      // 播放异常
      else {
        if (state.player) {
          addLog(`Reconnect after video freezes, address:${prop.url}`); // 添加日志
          state.errorCount = 0; // 错误连接次数归0
          state.lastDecodedFrame = 0; // 最后播放编码号
          flvDestory(); // 销毁对象
          flvCreated("statistics_info"); // 创建对象
        }
      }
    }

4、报错、停滞重连

      state.flvPlayer.on(flvjs.Events.ERROR, errorHandle); // 监听出错消息后,销毁后重连
      state.flvPlayer.on(flvjs.Events.LOADING_COMPLETE, errorHandle); // ctrl+f5刷新,会莫名因为停止end不播放
    /**
     * @description: 错误回调事件
     * @param {*} errorType
     * @param {*} errorDetail
     * @param {*} errorInfo
     * @return {*}
     * @Author: liuxin
     */
    function errorHandle() {
      //视频出错后销毁重新创建 网络错误
      if (state.flvPlayer && state.errorCount <= state.maxReconnectCount) {
        addLog(`Video error ${state.errorCount} reconnection,
            address:${prop.url}`); // 视频报错N重连
        state.loading = true; // 添加loading动画
        state.errorCount++; //错误重连次数+1
        flvDestory();
        flvCreated("ERROR");
      }
      if (state.errorCount > state.maxReconnectCount) {
        state.loading = false; // 去掉loading
      }
    }

5、累计延时处理

     /**
       * @description: 浏览器下载流事件,手动跳帧,防止累计延时
       * @return {*}
       * @Author: liuxin
       */
      videoElement.onprogress = (e) => {
        // 不需要跳帧,如:异常视频   或者没有数据流,则不进行跳帧
        if (!prop.isBufferedEnd || state.flvPlayer.buffered.length <= 0) {
          return;
        }
        state.loading = false;
        /* ----- 跳帧操作 ----- */
        let end = state.flvPlayer.buffered.end(0); //获取当前时间值
        let diff = end - state.flvPlayer.currentTime; //获取相差差值
        // 延迟过大或帧率不正常,通过跳帧的方式更新视频
        if (diff > 20 || diff < 0) {
          // addLog(`Manual frame skipping,address:${prop.url}`); // 添加日志
          state.flvPlayer.currentTime = state.flvPlayer.buffered.end(0) - 0.5; // 手动跳帧到最后
          return;
        }
        // 正常帧率,正常播放
        if (diff <= 1) {
          videoElement.playbackRate = 1;
        }
        // 10秒内的延时,1.1倍速播放
        else if (diff <= 10) {
          // addLog(`Chase frames manually 1.1,address:${prop.url}`); // 手动追帧
          videoElement.playbackRate = 1.1;
        }
        // 20秒内的延时,1.2倍速播放
        else if (diff <= 20) {
          // addLog(`Chase frames manually 1.2,address:${prop.url}`); // 手动追帧
          videoElement.playbackRate = 1.2;
        }
      };

6、手动全屏

    /**
     * @description: 全屏 / 退出全屏
     * @return {*}
     * @Author: liuxin
     */
    function fullscreenHandle() {
      state.isFlullscreen = !state.isFlullscreen;
      document.addEventListener("keydown", function (e) {
        //此处填写你的业务逻辑即可
        if (e.key == "Escape") {
          e.stopPropagation();
          state.isFlullscreen = false;
        }
      });

到此这篇关于vue3使用flv.js播放推流视频的示例代码的文章就介绍到这了,更多相关vue3 flv.js播放推流视频内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • vue+springboot前后端分离实现单点登录跨域问题解决方法

    vue+springboot前后端分离实现单点登录跨域问题解决方法

    这篇文章主要介绍了vue+springboot前后端分离实现单点登录跨域问题的解决方法,需要的朋友可以参考下
    2018-01-01
  • vite的搭建与使用的详细步骤

    vite的搭建与使用的详细步骤

    本文主要介绍了vite的搭建与使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • 解决vue-seamless-scroll滚动加点赞衔接处数据不同步问题

    解决vue-seamless-scroll滚动加点赞衔接处数据不同步问题

    这篇文章主要介绍了解决vue-seamless-scroll滚动加点赞衔接处数据不同步问题,初步判断可能是因为下方悬接vue-seamless-scroll是静态的,没同步DOM,本文给大家分享解决方法,感兴趣的朋友一起看看吧
    2021-11-11
  • 解决vue项目路径不正确,自动跳转404的问题

    解决vue项目路径不正确,自动跳转404的问题

    这篇文章主要介绍了解决vue项目路径不正确,自动跳转404的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-10-10
  • Vue实现列表跑马灯效果

    Vue实现列表跑马灯效果

    这篇文章主要为大家详细介绍了Vue实现列表跑马灯效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • 解决vue使用vant下拉框van-dropdown-item 绑定title值不变问题

    解决vue使用vant下拉框van-dropdown-item 绑定title值不变问题

    这篇文章主要介绍了解决vue使用vant下拉框van-dropdown-item 绑定title值不变问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • vue+elementUI面包屑组件封装方法详解

    vue+elementUI面包屑组件封装方法详解

    这篇文章主要为大家详细介绍了vue+elementUI面包屑组件封装方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • Vue3中使用this的详细教程

    Vue3中使用this的详细教程

    在vue3中新的组合式API中没有this,那我们如果需要用到this怎么办?下面这篇文章主要给大家介绍了关于Vue3中使用this的详细教程,需要的朋友可以参考下
    2023-07-07
  • vue3.0+vite2实现动态异步组件懒加载

    vue3.0+vite2实现动态异步组件懒加载

    学了vue写项目这么久,忽然发现路由懒加载的写法,节省了加载所有路由的时间。本文主要介绍了vue3.0+vite2实现动态异步组件懒加载,感兴趣的可以了解一下
    2021-06-06
  • nuxt实现封装axios并且获取token

    nuxt实现封装axios并且获取token

    这篇文章主要介绍了nuxt实现封装axios并且获取token,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-10-10

最新评论