vue+flv.js 實時播放單個和多個視頻流dome


安裝vlc 地址https://www.videolan.org/vlc/ 

 

 

打開網絡串流測試視頻流是否可用


安裝 npm install --save flv.js

1.單個flv.js dome

<template>
    <div>
        <video class="demo-video" ref="player" muted autoplay></video>
    </div>
</template>
<script>
import flvjs from "flv.js";
export default {
    data () {
        return {
            player: null
        }
    },
    mounted () {
        if (flvjs.isSupported()) {
            let video = this.$refs.player;
            if (video) {
                this.player = flvjs.createPlayer({
                    type: "flv",
                    isLive: true,
                    url: `http://1011.hlsplay.aodianyun.com/demo/game.flv`
                });
                this.player.attachMediaElement(video);
                try {
                    this.player.load();
                    this.player.play();
                } catch (error) {
                    console.log(error);
                };
            }
        }
    },
    beforeDestroy () {
        this.player.destory();
    }
}
</script>
<style>
    .demo-video {
        max-width: 880px; 
        max-height: 660px;
    }
</style>


原文鏈接:https://blog.csdn.net/weixin_42536639/article/details/102870788

 

2.點擊列表顯示相應flv流 (注:瀏覽器頁面最多顯示6個flv流 )

功能:點擊右邊菜單出現實時監控畫面,頁面有四個窗體,每個窗體播放不同的視頻,當四個窗體都在播放時,點擊下一個會依次替換每個窗體,隨機點四個頁面會出現對應的實時視頻

這段代碼解決了

開發問題1:離開頁面視頻會暫停(就沒有實時性)
開發問題2:頁面會瘋狂報錯(不影響功能,但是瀏覽器受不了)
開發問題3:怎么當四個窗體都在播放時,點擊下一個會依次替換每個窗體
開發問題4:怎么斷掉上一個視頻的推流(視頻會卡頓)
開發問題5:怎么斷開重新連接

<template>
  <div class="videobox">
    <div class="videolist">
      <div class="search">
        <ul>
          <li
            v-for="(item, index) in rtsplist"
            :key="index"
            @click="clickhandleitem(item, index)"
          >
            <i class="el-icon-video-camera-solid"></i>
            列表{{index}}
          </li>
        </ul>
      </div>
    </div>
    <div class="video">
      <video
        autoplay
        muted
        width="400px"
        height="300px"
        v-for="(i,index) in 4"
        :id="'videoElement' + i"
        :key="index"
      ></video>
    </div>
  </div>
</template>

<script>
import flvjs from "flv.js";
export default {
  data() {
    return {
       rtsplist: [
        {
          rtsp: "http://1011.hlsplay.aodianyun.com/demo/game.flv",
          player: null
        },
        {
          rtsp: "http://1011.hlsplay.aodianyun.com/demo/game.flv",
          player: null
        },
        
        {
          rtsp: "http://1011.hlsplay.aodianyun.com/demo/game.flv",
          player: null
        },
        {
          rtsp: "http://1011.hlsplay.aodianyun.com/demo/game.flv",
          player: null
        },
        {
          rtsp: "http://1011.hlsplay.aodianyun.com/demo/game.flv",
          player: null
        },
        {
          rtsp: "http://1011.hlsplay.aodianyun.com/demo/game.flv",
          player: null
        },
        
        {
          rtsp: "http://1011.hlsplay.aodianyun.com/demo/game.flv",
          player: null
        },
        {
          rtsp: "http://1011.hlsplay.aodianyun.com/demo/game.flv",
          player: null
        },
        
      ],
      flvPlayer: null,
      inputvalue: "",
      devicename: "60",
      url: "",
      list: [],
      count: 1, // 當前點擊標識
      flvPlayerList: [],
      datalist:[]
    };
  },
  methods: {
    clickhandleitem(data, index) {
      let ip = data.ipAddress;
      let admin = data.videoname;
      let password = data.videopas;

      this.url =this.rtsplist[index].rtsp
      console.log(this.flvPlayerList,'flvPlayerList')
      if (this.flvPlayerList.length > 3) {
        this.destoryVideo(this.flvPlayerList[0]);
        this.flvPlayerList.shift();
      }
      this.createVideo();
      console.log(index)
      this.count > 3 ? (this.count = 1) : this.count++;
      console.log(this.count)
    },
    createVideo() {
      if (flvjs.isSupported()) {
        var videoElement = document.getElementById("videoElement" + this.count);
        this.flvPlayer = flvjs.createPlayer(
          {
            type: "flv",
            isLive: true,
            hasAudio: false,
            url: this.url
          },
          {
            enableWorker: false, //不啟用分離線程
            enableStashBuffer: false, //關閉IO隱藏緩沖區
            reuseRedirectedURL: true, //重用301/302重定向url,用於隨后的請求,如查找、重新連接等。
            autoCleanupSourceBuffer: true //自動清除緩存
          }
        );

        this.flvPlayer.attachMediaElement(videoElement);
        // this.flvPlayer.load();

        if (this.url !== "" && this.url !== null) {
          this.flvPlayer.load();
          this.flvPlayer.play();
        }
      }

      //定時方法是為了用戶離開頁面視頻是實時播放的,暫停按鈕無用
      setInterval(function() {
        // console.log(videoElement.buffered,"idididid");
        if (videoElement.buffered.length > 0) {
          const end = videoElement.buffered.end(0); // 視頻結尾時間
          const current = videoElement.currentTime; //  視頻當前時間
          const diff = end - current; // 相差時間
          // console.log(diff);
          const diffCritical = 4; // 這里設定了超過4秒以上就進行跳轉
          const diffSpeedUp = 1; // 這里設置了超過1秒以上則進行視頻加速播放
          const maxPlaybackRate = 4; // 自定義設置允許的最大播放速度
          let playbackRate = 1.0; // 播放速度
          if (diff > diffCritical) {
            //  this.flvPlayer.load();
            // console.log("相差超過4秒,進行跳轉");
            videoElement.currentTime = end - 1.5;
            playbackRate = Math.max(1, Math.min(diffCritical, 16));
          } else if (diff > diffSpeedUp) {
            // console.log("相差超過1秒,進行加速");
            playbackRate = Math.max(1, Math.min(diff, maxPlaybackRate, 16));
          }
          videoElement.playbackRate = playbackRate;
          if (videoElement.paused) {
            videoElement.play();
          }
        }
        //  if (videoElement.buffered.length) {
        //   let end = this.flvPlayer.buffered.end(0);//獲取當前buffered值
        //   let diff = end - this.flvPlayer.currentTime;//獲取buffered與currentTime的差值
        //   if (diff >= 0.5) {//如果差值大於等於0.5 手動跳幀 這里可根據自身需求來定
        //     this.flvPlayer.currentTime = this.flvPlayer.buffered.end(0);//手動跳幀
        //  }
        // }
      }, 1000);

      this.flvPlayer.on(flvjs.Events.ERROR, (errType, errDetail) => {
        // alert("網絡波動,正在嘗試連接中...");
        if (this.flvPlayer) {
          this.reloadVideo(this.flvPlayer);
        }
        // errType是 NetworkError時,對應errDetail有:Exception、HttpStatusCodeInvalid、ConnectingTimeout、EarlyEof、UnrecoverableEarlyEof
        // errType是 MediaError時,對應errDetail是MediaMSEError   或MEDIA_SOURCE_ENDED
      });
      this.flvPlayerList.push(this.flvPlayer);
    },

    reloadVideo(flvPlayer) {
      this.destoryVideo(flvPlayer);
      this.createVideo();
    },
    destoryVideo(flvPlayer) {
      flvPlayer.pause();
      flvPlayer.unload();
      flvPlayer.detachMediaElement();
      flvPlayer.destroy();
      flvPlayer = null;
    },
  }
};
</script>

<style lang="scss" scoped>
.videobox {
  display: flex;
  /* justify-content: space-between; */
  /* flex-wrap: wrap; */
}
.videolist {
  width: 550px;
  height: 906px;
  display: flex;
  .search {
    margin-left: 50px;
    .el-input {
      width: 300px;
      margin-top: 20px;
    }
    ul {
      width: 100%;
      height: 777px;
      overflow: hidden;
      overflow-y: auto;
      list-style: none;
      li {
        padding: 7px;
        margin: 1px 0;
        text-decoration: none;
        white-space: nowrap;
        font-size: 14px;
        cursor: pointer;
        &:hover {
          background: #fff;
        }
        .el-icon-video-camera-solid {
          font-size: 16px;
          color: #67c23a;
        }
      }
    }
  }
}
.video {
  display: flex;
  flex-wrap: wrap;
  width: 100%;
  justify-content: space-evenly;
  video {
    object-fit: contain;
    width: 600px;
    height: 390px;
  }
}
</style>

 

 

 

 

原文鏈接:https://blog.csdn.net/weixin_45906632/article/details/115031633

 

遇到的問題

第一種報錯情況:谷歌瀏覽器控制台出現的報錯
使用報錯如下:Failed to read the ‘buffered’ property from ‘SourceBuffer’: This SourceBuffer has been removed from the parent media source.

這種錯誤提示一般是在flv源發生異常中斷的時候產生的。錯誤提示大多數都在 mse-controller.js 這個模塊中。
解決辦法:在 mse-controller.js中(flv.js/src/core/mse-controller.js),appendMediaSegment()、_needCleanupSourceBuffer()這些方法的入口處調用檢查以下MediaSource的合法性。

if (!this._mediaSource || this._mediaSource.readyState !== 'open') {
          return;
      }

原文鏈接:https://blog.csdn.net/xyy1234567891/article/details/110005429


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM