flv.js--播放直播流时出现的累积延迟、断流重连以及画面卡顿的解决方法

本文参考了https://blog.csdn.net/HJFQC/article/details/113188241,有细微的改动

解决延迟见

https://blog.csdn.net/daqinzl/article/details/122370388

断流重连

通过监听flvjs.Events.ERROR来判断连接是否已经断开,然后进行断流重连:

player的定义

<div class="mainContainer">
        <video id="videoElement" class="centeredVideo" controls muted autoplay width="1024" height="576">Your browser is too old which doesn't support HTML5 video.</video>
</div>

代码如下:

$('#videoElement').on(flvjs.Events.ERROR, (errorType, errorDetail, errorInfo) => {
        console.log("errorType:", errorType);
        console.log("errorDetail:", errorDetail);
        console.log("errorInfo:", errorInfo);
        //视频出错后销毁重新创建
         if (this.player) {
          this.player.pause();
          this.player.unload();
          this.player.detachMediaElement();
          this.player.destroy();
          this.player= null;
          this.createPlayer(videoElement, this.url);
        }
      });

画面卡顿
如果画面卡住不动,可能是服务端推流突然断开,然后在很快的时间内继续推流,此时因为客户端还未超时,流会继续推送到原链接,此时视频会卡在掉线的那个时间,不会继续播放.这时需要监听推流的decodedFrame,如果decodedFrame不再发生变化,我们就销毁掉该实例并进行重新连接,代码如下:

$('#videoElement').on("statistics_info", function (res) {
       if (this.lastDecodedFrame == 0) {
         this.lastDecodedFrame = res.decodedFrames;
         return;
       }
       if (this.lastDecodedFrame != res.decodedFrames) {
         this.lastDecodedFrame = res.decodedFrames;
       } else {
           this.lastDecodedFrame = 0;
           if (this.player) {
             this.player.pause();
             this.player.unload();
             this.player.detachMediaElement();
             this.player.destroy();
             this.player= null;
             this.createPlayer(videoElement, this.url);
         }
       }
     });

完整的flv播放的html页面

<!DOCTYPE html>
<html>

<head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
    <title>flv.js demo</title>
    <style>
        .mainContainer {
    display: block;
    width: 1024px;
    margin-left: auto;
    margin-right: auto;
}

.urlInput {
    display: block;
    width: 100%;
    margin-left: auto;
    margin-right: auto;
    margin-top: 8px;
    margin-bottom: 8px;
}

.centeredVideo {
    display: block;
    width: 100%;
    height: 576px;
    margin-left: auto;
    margin-right: auto;
    margin-bottom: auto;
}

.controls {
    display: block;
    width: 100%;
    text-align: left;
    margin-left: auto;
    margin-right: auto;
}
    </style>
</head>

<body>
    <div class="mainContainer">
        <video id="videoElement" class="centeredVideo" controls muted autoplay width="1024" height="576">Your browser is too old which doesn't support HTML5 video.</video>
    </div>
    <br>
    <div class="controls">
        <button οnclick="flv_load()">加载</button>
        <button οnclick="flv_start()">开始</button>
        <button οnclick="flv_pause()">暂停</button>
        <button οnclick="flv_destroy()">停止</button>
        <input style="width:100px" type="text" name="seekpoint" />
        <button οnclick="flv_seekto()">跳转</button>
    </div>
    <script src="./dist/flv.min.js"></script>
    <script src="./jquery-3.4.1.min.js"></script>
    <script>
        var player = document.getElementById('videoElement');
        
        $('#videoElement').on(flvjs.Events.ERROR, (errorType, errorDetail, errorInfo) => {
        console.log("errorType:", errorType);
        console.log("errorDetail:", errorDetail);
        console.log("errorInfo:", errorInfo);
        //视频出错后销毁重新创建
         if (this.player) {
          this.player.pause();
          this.player.unload();
          this.player.detachMediaElement();
          this.player.destroy();
          this.player= null;
          this.createPlayer(videoElement, this.url);
        }
      });
        
        $('#videoElement').on("statistics_info", function (res) {
       if (this.lastDecodedFrame == 0) {
         this.lastDecodedFrame = res.decodedFrames;
         return;
       }
       if (this.lastDecodedFrame != res.decodedFrames) {
         this.lastDecodedFrame = res.decodedFrames;
       } else {
           this.lastDecodedFrame = 0;
           if (this.player) {
             this.player.pause();
             this.player.unload();
             this.player.detachMediaElement();
             this.player.destroy();
             this.player= null;
             this.createPlayer(videoElement, this.url);
         }
       }
     });
        
        function flv_load() {
            //player.load();
            start();
        }
        
        function flv_start() {
            player.play();
        }

        function flv_pause() {
            player.pause();
        }

        function flv_destroy() {
            player.pause();
            player.unload();
            player.detachMediaElement();
            player.destroy();
            player = null;
        }

        function flv_seekto() {
            player.currentTime = parseFloat(document.getElementsByName('seekpoint')[0].value);
        }
        
        function start() {
            if (flvjs.isSupported()) {
                var flvPlayer = flvjs.createPlayer({
                    enableWorker:false,
                    lazyLoadMaxDuration:3*60,
                    enableStashBuffer:false,
                    fixAudioTimeStampGap:false,
                    autoCleanupSourceBuffer:true,
                    isLive:true,
                    type: 'flv',
                    url: 'http://192.168.0.110:80/flv?port=1935&app=hls&stream=desktop'
                });
                flvPlayer.attachMediaElement(videoElement);
                flvPlayer.load(); //加载
                player.play(); //add
            }
        }
        
        document.addEventListener('DOMContentLoaded', function () {
            start();
          });

        var int1 = self.setInterval("clock()", 5000);
        function clock() {
          if (this.player.buffered.length) {
            let end = this.player.buffered.end(0);//获取当前buffered值
            let diff = end - this.player.currentTime;//获取buffered与currentTime的差值
            if (diff >= 1.0) {//如果差值大于等于1.0 手动跳帧 这里可根据自身需求来定
              //this.player.currentTime = this.player.buffered.end(0)-0.2;//手动跳帧,卡顿
              this.player.playbackRate +=0.1;//采用加速方式追帧
            }
            else
               this.player.playbackRate =1.0;
           
          }
       }

    </script>
</body>

</html>

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值