首页 > 其他分享 >flv.js视频流出错,断流处理

flv.js视频流出错,断流处理

时间:2023-06-25 22:36:01浏览次数:45  
标签:lastDecodedFrames 视频流 flv player js true

flv.js视频流出错,断流处理

可乐加冰515创作等级LV.3 2023年02月20日 17:45 ·  阅读 274
  • 场景:前端使用flv.js播放视频流

Bug表现:

  • 视频流播放两分钟左右video标签出现暂停按钮,控制台flv.js报错:Failed to execute 'appendBuffer' on 'SourceBuffer': The HTMLMediaElement.error attribute is not null

Bug原因:

  • 百度出来是flv.js内部原因

image.png

Bug修复:

  • 网上大部分解决方案是修改浏览器视频编解码配置(Chrome浏览器输入chrome://flags/,搜索video,选择disabled,如下图),但是此方法在我项目中无效,遂继续翻阅百度,终于找到破解之法。

image.png

  • 修复之法:监听视频播放错误信息,出错时销毁重建,就是如此简单,我之前怎么没有想到

完整代码

  js 复制代码
<template>
    <div v-if="propValue.rtspUrl === 'src'">
        <span>视频加载中</span>
    </div>
    <video
        v-else
        muted
        autoplay
        controls
        class="videoPlayer"
        :id="propValue.id"
    ></video>
</template>
<script>
import flvjs from "flv.js";
export default {
    props: {
        propValue: {
            type: Object,
            default: () => {
                return {
                    id: "player",
                    rtspUrl: "",
                };
            },
        },
    },
    data() {
        return {
            player: null,
            lastDecodedFrames: 0
        };
    },
    watch: {
        propValue: {
            handler(newVal, oldVal) {
                if (newVal && newVal != oldVal) {
                    this.init();
                }
            },
            deep: true,
            immediate: true,
        },
    },
    mounted() {
        this.init();
    },
    beforeDestroy() {
        this.destroyFlv();
    },
    methods: {
        init() {
            if (!flvjs.isSupported()) return;
            if (this.propValue.rtspUrl === "") return;
            const videoContainer = document.getElementById(this.propValue.id);
            if (videoContainer) {
                this.player = flvjs.createPlayer(
                    {
                        type: "flv", // flv,mp4
                        isLive: true,
                        // url: `ws://localhost:80/rtsp/${this.id}/?url=${this.rtsp}`,
                        url: this.propValue.rtspUrl,
                        hasAudio: false,
                    },
                    {
                        autoCleanupSourceBuffer: true,
                        enableWorker: false, //不启用分离线程
                        enableStashBuffer: true, //关闭IO隐藏缓冲区
                        isLive: true,
                        lazyLoad: false,
                    }
                );
                this.player.attachMediaElement(videoContainer);
                try {
                    this.player.load();
                    this.player.play();
                    this.listenVideo();
                } catch (error) {
                    console.log(error);
                }
            }
        },
        destroyFlv() {
            if (this.player) {
                this.player.pause();
                this.player.unload();
                this.player.detachMediaElement();
                this.player.destroy();
                this.player = null;
            }
        },
        // 监听视频流是否断流或者卡顿
        listenVideo() {
            const that = this;
            this.player.on(
                flvjs.Events.ERROR,
                (errorType, errorDetail, errorInfo) => {
                    console.log("errorType", errorType);
                    console.log("errorDetail", errorDetail);
                    console.log("errorInfo", errorInfo);
                    // 视频出错后销毁重建
                    that.destroyFlv();
                    that.init();
                }
            );
            // 视频断流
            this.player.on("statistics_info", function (res) {
                if(that.lastDecodedFrames === 0){
                    that.lastDecodedFrames = res.decodedFrames
                    return
                }
                if(that.lastDecodedFrames != res.decodedFrames){
                    that.lastDecodedFrames = res.decodedFrames
                }else{
                    that.lastDecodedFrames = 0
                    that.destroyFlv()
                    that.init()
                }
            });
        },
    },
};
</script>
<style scoped lang='scss'>
div {
    position: relative;
    width: 100%;
    height: 100%;
    border: 1px solid #fff;
    > span {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
    }
}
.videoPlayer {
    width: 100%;
    height: 100%;
}
</style>

总结

标签:lastDecodedFrames,视频流,flv,player,js,true
From: https://www.cnblogs.com/sexintercourse/p/17504144.html

相关文章

  • JS(数组)
    一数组的概念问:之前学习的数据类型,只能存储一个值。如果我们想存储班级中所有学生的姓名,那么该如何存储呢?答:可以使用数组(Array)。数组可以把一组相关的数据一起存放,并提供方便的访问(获取)方式。问:什么是数组呢?答:数组是指一组数据的集合,其中的每个数据被称作元素,在数组中可以存......
  • springboot中自定义JavaBean返回的json对象属性名称大写变小写问题
    目录一、继承类二、手动添加Get方法三、@JsonProperty四、spring-bootjson(jackson)属性命名策略开发过程中发现查询返回的数据出现自定义的JavaBean的属性值大小写格式出现问题,导致前端无法接受到数据,目前有四种解决方法,根据大佬的经验之谈,前两种是最简单便捷的,后两种是比较通......
  • 使用flv.js直播不能自动播放的问题
    使用flv.js直播不能自动播放的问题问题使用Flv.js做直播,最近发现进入页面后不能自动播放。原因查询了一下发现是因为Chromeautoplaypolicy的影响。目前的解决方案由于项目的视频不需要播放音频,所以直接给video标签加上muted属性,进入后可以自动播放。......
  • 文件上传-js前端验证
    先上传一个文件看看  这里有标识文件类型 方法一:禁用js前端验证使用工具禁用所有的js脚本  或者修改onsubmit参数      保证 returncheckFile()函数返回值为true 第二种方法: 上传png文件改为php后缀远程执行命令,回显成功......
  • 记一次曲折的fastjson事件应急响应
    01事件背景介绍某内部应急演练中,安全部门收到通知,称公司内部资产被入侵,且可能已经开始内网横向入侵,现需根据流量情况进行安全事件分析。02事件分析过程通过数据包发现10.X.X.2对80.X.X.1/24使用扫描器发起扫描,包括80.X.X.12,80.X.X.48,80.X.X.61查看源IP80.X.X.12外连情况发现无......
  • Python 中的 JSON 操作:简单、高效的数据交换格式
    在现代的数据交换和存储中,JSON(JavaScriptObjectNotation)作为一种轻量级的数据交换格式,备受青睐。它不仅易于阅读和理解,还可以灵活地表达和存储高维数据。本文将介绍如何在Python中操作JSON文件,实现数据的序列化和反序列化。1.JSON数据格式JSON格式采用键值对的方式......
  • D365: 将多个关联的表数据转换为JSON格式
    最近碰到一个需求,将D365系统中的多个关联表的数据转换成JSON格式导出然后上传到blobstorage,实现方式记录一下,以便将来使用首先在调用是引用usingNewtonsoft.Json,usingSystem.IO引用后,我们用到两个classSystem.IO.StringWriterNewtonsoft.Json.JsonTextWriter分别定义这......
  • JS(循环)
    一for循环在程序中,一组被重复执行的语句被称之为循环体,能否继续重复执行,取决于循环的终止条件。由循环体及循环的终止条件组成的语句,被称之为循环语句1语法结构for循环主要用于把某些代码循环若干次,通常跟技术有关系。其语法结构如下for(初始化变量;条件表达式;操作表达式......
  • electron中调用node.js API
    主进程在node.js环境中运行,等同于它拥有调用require模块和使用所有node.jsAPI的能力。但是在渲染器进程中,渲染器是无法直接访问require和其他node.jsAPI的,想要访问有以下两种方法:Preload脚本预加载脚本运行在渲染器环境中,可以在BrowserWindow构造方法中的webPreferences选项里被......
  • React基本引入和JSX语法
    1.1React介绍1.1.1.官网英文官网:https://reactjs.org/中文官网:https://react.docschina.org/1.1.2.介绍描述用于动态构建用户界面的JavaScript库(只关注于视图)由Facebook开源1.1.3.React的特点声明式编码组件化编码ReactNative编写原生应用高效(优秀......