當前位置:網站首頁>flv.js--播放直播流時出現的累積延遲、斷流重連以及畫面卡頓的解决方法

flv.js--播放直播流時出現的累積延遲、斷流重連以及畫面卡頓的解决方法

2022-01-28 05:41:50 daqinzl

本文參考了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>

版權聲明
本文為[daqinzl]所創,轉載請帶上原文鏈接,感謝
https://cht.chowdera.com/2022/01/202201280541495327.html

隨機推薦