使用flv.js的踩坑记录及解决方法

目录

      • 安装
      • 使用
      • 踩坑
        • 警告:[FlvPlayer] > Playback seems stuck at 0, seek to 1.32
          • 解决方法:
        • 报错1: Uncaught (in promise) DOMException: Failed to read the 'buffered' property from 'SourceBuffer': This SourceBuffer has been removed from the parent media source.
          • 解决方法:
        • 报错2: Error while initialize transmuxing worker, fallback to inline transmuxing
          • 解决方法:
        • 报错3: The play() request was interrupted by a call to pause().
          • 解决方法:
        • 报错4: The play() request was interrupted by a new load request
          • 解决方法:

安装

npm install --save flv.js

使用

<template>
  <div>
	<video
      id="videoElement"
      ref="videoRef"
      autoplay
      controls
      width="100%"
      height="100%"
      muted
    />
  <div>
</template>

<script>
  import flvjs from 'flv.js'

  // 实现播放
  async createPlayer(pid) {
    const {data } = await findVideo(pid)
    const preUrl = 'http://192.168.0.176:7016'
    if (data[0]) {
      const testUrl1 = preUrl + data[0].urls
      const videoElement1 = this.$refs.videoRef
      let flvPlayer1 = flvjs.createPlayer({
        type: 'flv', // 类型
        isLive: true, // 数据源是否为直播流
        stashInitialSize: 128, // 减少首帧显示等待时长
        url: testUrl1 // 数据源地址
      }, {
        enableStashBuffer: false, // 关闭IO隐藏缓冲区
        enableWorker: false, // 启用分离的线程进行转换
        autoCleanupSourceBuffer: true, // 自动清除缓存
        fixAudioTimestampGap: false // 音视频同步
      })
      this.flvPlayer = flvPlayer1
      // 使用typescript支持基于类的vue组件格式可能导致attachMediaElement()方法报错
      flvPlayer1.attachMediaElement(videoElement1)
      flvPlayer1.load() // 加载数据流
      flvPlayer1.play() // 播放数据流
    }
  }

  // 关闭视频播放
  closePlay() {
    this.flvPlayer.pause() // 暂停播放数据流
    this.flvPlayer.unload() // 取消数据流加载
    this.flvPlayer.detachMediaElement() // 将播放实例从节点中取出
    this.flvPlayer.destroy() // 销毁播放实例
  }
</script>

踩坑

警告:[FlvPlayer] > Playback seems stuck at 0, seek to 1.32

解决方法:
data() {
  return {
    interval: 0,
    flvPlayer: ''
  }
},
mounted() {
  let lastDecodedFrames = 0
  let stuckTime = 0
  if(this.interval && clearInterval(this.interval)) {
	this.interval = setInterval(() => {
	  const decodeedFrames = this.flvPlayer.statisticsInfo.decodedFrames
	  if (!decodedFrames) return
	  if (lastDecodedFrames === decodedFrames && !this.videoElement.paused) {
	    stuckTime++
	    if (stuckTime > 1) {
	      this.closePlay()
	      this.createPlayer()
	    }
	  } else {
	    lastDecodedfRAMES = decodedFrames
	    stuckTime = 0
	  }
	}, 1000)
  }
}

报错1: Uncaught (in promise) DOMException: Failed to read the ‘buffered’ property from ‘SourceBuffer’: This SourceBuffer has been removed from the parent media source.

介绍: 我使用的是flv.js1.6.2版本的,报错后使用了以下的方法但仍然无法解决,降低到了flv.js1.5.0版本后再使用以下方法才能解决这个报错。

解决方法:

进入node_modules/flv.js/src/core/mse-controller.js文件中
在appendMediaSegment()和_needCleanupSourceBuffer()两个方法下第一行加入以下代码:

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

报错2: Error while initialize transmuxing worker, fallback to inline transmuxing

解决方法:

添加以下配置:

enableWorker: false, // 是否启用分离的线程进行转换

报错3: The play() request was interrupted by a call to pause().

play()请求被pause()调用中断

解决方法:

给播放数据流的地方添加一个定时器,如下:

setTimeout(function() {
  flvPlayer1.play() // 播放数据流
}, 300)

注意区分上下两个错误

报错4: The play() request was interrupted by a new load request

play()被新的请求中断

解决方法:

建立新的连接前先销毁之前的连接

async switchPlay() {
  this.closePlay()
  this.createPlayer(pid)
}

你可能感兴趣的:(javascript,音视频,vue.js)