<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')
};
flv 轮播功能(单个、多个)
于 2023-12-03 19:18:36 首次发布