flv 轮播功能(单个、多个)


<template>
  <div>

开始和停止按钮
<img @click="carouselClick" src="@/assets/images/start.png" class="imgStyle" alt="" v-if="photeVis==false">
              <img @click="stopClick" src="@/assets/images/stop.png" class="imgStyle" alt="" v-if="photeVis==true">
            </div>
          </div>
        </div>
      </el-col>
    </el-row>
  </div>

</template>
  
<script setup>
import {
  defineComponent,
  toRefs,
  reactive,
  getCurrentInstance,
  ref,
  onMounted,
  computed,
  watch,
  nextTick,
  onBeforeUnmount

} from "vue";


let CarouselRef = ref('');
const photeVis=ref(false)
const carouselClick = async () => {
  CarouselRef.value.show();
};
const stopphoteVis=()=>{
  photeVis.value=true;
}
const stopClick = async () => {
  if (onesetInterTimeInter.value) { 
    clearInterval(onesetInterTimeInter.value)
  }
  console.log(twosetInterTimeInter.value, 'twosetInterTimeInter')
  if (twosetInterTimeInter.value) {
    clearInterval(twosetInterTimeInter.value)

  }
  cutArray.value = []
  // 显示x
  flyshow.value = false;
  // 显示图标
  photeVis.value=false;

};
const currentVideoIndex = ref(0)
// 二维数组
const twoDimensionalArray = ref([])
const cutArray = ref([])
const flyshow = ref(false)
const getHandList = (List,times) => {
  setInterTime.value=times
  twosetInterTime.value=times
  // x号
  flyshow.value = true
  // 图标显示
  photeVis.value=true
  if (onesetInterTimeInter.value) {
    clearInterval(onesetInterTimeInter.value)
  }
  if (twosetInterTimeInter.value) {
    clearInterval(twosetInterTimeInter.value)
  }
  // 提前清除二维数组对应的下标取余数
  // 当多分屏进入单分屏的话currentVideoIndex.value 可能会有问题,不能保证选择的视频是从index=0开始的
  currentVideoIndex.value = 0
  cutArray.value = List
  // 看当前是几个屏,把几屏和数据源传入进行二维分组
  twoDimensionalArray.value = convertToTwoDimensionalArray(List, huaNum.value);
  console.log(twoDimensionalArray.value, 'twoDimensionalArray.value')
  if (huaNum.value == '1') {
    oneHua();
  } else {

//多个
    twoHua();
  }

}
const setInterTime = ref(1)
const twosetInterTime = ref(1)
const onesetInterTimeInter = ref(null)
const clearonedestoryVideo = () => {
  // 清除单个播放器
  if (flvPlayer.value && flvPlayer.value[0] && flvPlayer.value[0]["player"]) {
    destoryVideo(flvPlayer.value[0]["player"])
  }
  flvPlayer.value = []
}
const oneHua = () => {
  // 添加当前的视频源
  if (url.value.length) {
    url.value = []
  }
  url.value.push({ "url": twoDimensionalArray.value[currentVideoIndex.value][0].url, "id": twoDimensionalArray.value[currentVideoIndex.value][0].id, "shename": twoDimensionalArray.value[currentVideoIndex.value][0].shename, "index": 0 });
  clearonedestoryVideo()
  // // 赋值url
  // 默认索引0,取二维数组第一项的id    1为视频时,调用init改变dom和index
  init(0, twoDimensionalArray.value[currentVideoIndex.value][0].id, 'oneNum')
  // 定时器进行轮播
  if (twoDimensionalArray.value.length > 1) {
    onesetInterTimeInter.value = setInterval(rotateVideo, setInterTime.value * 1000)
  } else {
    clearInterval(onesetInterTimeInter.value)
  }
  console.log(onesetInterTimeInter.value, 'onesetInterTimeInter')
}
const rotateVideo = () => {
  clearonedestoryVideo()
  url.value = []
  // 对数据twoDimensionalArray列表进行取余
  currentVideoIndex.value = (currentVideoIndex.value + 1) % twoDimensionalArray.value.length
  url.value.push({ "url": twoDimensionalArray.value[currentVideoIndex.value][0].url, "id": twoDimensionalArray.value[currentVideoIndex.value][0].id, "shename": twoDimensionalArray.value[currentVideoIndex.value][0].shename, "index": 0 });
  // 进行调用初始化方法
  // currentVideoIndex.value取余二维范围区间
  init(currentVideoIndex.value, twoDimensionalArray.value[currentVideoIndex.value][0].id, 'oneNum')
}


const twoclearonedestoryVideo = () => {
  // 清除多个播放器
  for (let i = 0; i < flvPlayer.value.length; i++) {
    if (flvPlayer.value[i].hasOwnProperty("player") && flvPlayer.value[i]["player"]) {
      destoryVideo(flvPlayer.value[i]["player"])
    }
  }
  flvPlayer.value = []
}
const twosetInterTimeInter = ref(null)
const twoHua = () => {
  // 清除当前的视频源
  if (url.value.length) {
    url.value = []
  }
  // 二维数组取余数,currentVideoIndex.value,第一次加url数据
  if (twoDimensionalArray.value && twoDimensionalArray.value[currentVideoIndex.value]) {
    twoDimensionalArray.value[currentVideoIndex.value]?.forEach((item, index) => {
      url.value.push({ "url": item.url, "id": item.id, "shename": item.shename, "index": index });
    })
  }
  twoclearonedestoryVideo();
  // 用url创建dom
  url.value.forEach((item, index) => {
    console.log(item, 'item')
    nextTick(() => {
      init(index, item.id)
    })
  })
  console.log(twoDimensionalArray.value.length, 'twoDimensionalArray.value.length')
  if (twoDimensionalArray.value.length > 1) {
    // 二维数组大于1说明当前数据 为[[],[]]超过1个屏
    twosetInterTimeInter.value = setInterval(tworotateVideo, twosetInterTime.value * 1000)
  } else {
    clearInterval(twosetInterTimeInter.value)
  }
  console.log(twosetInterTimeInter.value, 'twosetInterTimeIntertwosetInterTimeInter')
}

const tworotateVideo = () => {
  if (twoDimensionalArray.value.length > 1) {
    // 当前的值取余的值大于0说明有多组 然后循环,如果<0的话,不循环停止
    // 取余
    currentVideoIndex.value = (currentVideoIndex.value + 1) % twoDimensionalArray.value.length

    console.log(twoDimensionalArray.value.length, '2222222222')
    console.log(flvPlayer.value, 'flvPlayer.value')
    twoclearonedestoryVideo()
    url.value = []
    if (twoDimensionalArray.value && twoDimensionalArray.value[currentVideoIndex.value]) {
      twoDimensionalArray.value[currentVideoIndex.value]?.forEach((item, index) => {
        url.value.push({ "url": item.url, "id": item.id, "shename": item.shename, "index": index });
      })
    }
    console.log(url.value, 'urlurlurlurl')
    url.value.forEach((item, index) => {
      console.log(item, 'item')
      nextTick(() => {
        init(index, item.id)
      })
    })
  } else {
    clearInterval(twosetInterTimeInter.value)
  }
}
// 根据当前几分屏,分成几个二维数组
const convertToTwoDimensionalArray = (arr, num) => {
  var result = [];
  var length = arr.length;
  var rows = Math.ceil(length / num); // 计算行数

  for (var i = 0; i < rows; i++) {
    var row = arr.slice(i * num, (i + 1) * num); // 根据给定的数字切割一维数组
    result.push(row);
  }

  return result;
}

const setInterTimeInter = ref(null);
let flvPlayer = ref([]);
let arr = ref([])
const init = (i, id, type) => {
  console.log(i, id, "i-id");
  if (url.value && url.value.length) {
    // 拿到点击的树形id那一项和数组里url一项id匹配
    const item = url.value.find(item => item.id == id)
    console.log(url.value, "init url");
    console.log(item);
    if (type == 'oneNum') {
      // 说明是单个页面,单个页面一个dom节点
      i = 0
    }
    let player = null;
    var videoElement = document.getElementById("myFlvVideo" + i);
    console.log(videoElement, "videoElement");
    player = flvjs.createPlayer(
      {
        type: "flv",
        url: item["url"],
      },
      {
        cors: true, // 是否跨域
        enableWorker: false, //启用分离的线程进行转换
        autoCleanupSourceBuffer: true, //对SourceBuffer进行自动清理缓存
        enableStashBuffer: false, //关闭IO隐藏缓冲区
        stashInitialSize: 128, //减少首帧显示等待时长
        fixAudioTimestampGap: false, //音频同步
      }
    );
    // 添加信息播放器
    player.posIndex=i
    player.attachMediaElement(videoElement);
    player.load();
    setInterTimeInter.value = setInterval(function () {
      if (videoElement.buffered.length > 0) {
        // console.log(videoElement.buffered,'videoElement.buffered')
        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) {
          console.log("相差超过4秒,进行跳转");
          videoElement.currentTime = end - 1.5;
          console.log(videoElement.currentTime, 'videoElement.currentTime')
          playbackRate = Math.max(1, Math.min(diffCritical, 16));
        } else if (diff > diffSpeedUp) {
          // console.log("相差超过1秒,进行加速");
          console.log("相差超过1秒,进行加速");
          playbackRate = Math.max(1, Math.min(diff, maxPlaybackRate, 16));
        }
        videoElement.playbackRate = playbackRate;
      }
    }, 1000);
    // 断开重连

    player.on(flvjs.Events.ERROR, (errorInfo, errType, errDetail) => {
      createdDestory(player.posIndex);
    })
    setTimeout(function () {
      player.play() // 播放数据流
    }, 300)
    // 过滤掉同一个位置,相同的数据,保证数据唯一性
    flvPlayer.value = flvPlayer.value.filter(item => item.index != i)
    flvPlayer.value.push({ "id": id, "player": player, "index": i })
  }

}
const createdDestory = (i) => {
  console.log('进来1')
  destoryVideo(flvPlayer.value[i].player)
  init(i, flvPlayer.value[i].id)
}
const destoryVideo = (flv) => {
  console.log(flv, 'flvPlayer1')
  if (flv && flv !== null) {
    try {
      flv.unload();
      flv.detachMediaElement();
      flv.destroy();
      console.log("销毁销毁销毁销毁");
    } catch (error) {

    }


  }
  console.log(flvPlayer.value, 'flvPlayer2')
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值