Commit 7227ad85 by haojie

解决闪屏问题

parent 298da579
<template>
<div class="add-video-play">
<!-- <button @click="onPlay">开始播放</button> -->
<div class="main-video-play" v-show="showFirstVideo">
<template v-for="(item, index) in mainVideoList" :key="item.name">
<video
......@@ -11,7 +10,7 @@
:src="item.url"
:loop="loop"
@canplay="mainVideoCanplay(index)"
@ended="firstVideoEnded"
@ended="firstVideoEnded(index)"
></video>
</template>
</div>
......@@ -52,42 +51,32 @@ import Loading from '@/components/Loading/FirstCircle.vue';
import { onBeforeRouteLeave } from 'vue-router';
import { injectWindow } from '@/utils/pyqt';
import { show_message } from '@/utils/tool';
import { scriptTypePhonetics } from '@/service/CreateLive';
const props = withDefaults(
defineProps<{
playMainIndex: number | null;
video1: string;
video2: string;
playId?: any;
progress: number;
mainIndex?: number | null;
totalTime: number;
liveDetail: any;
eplay?: number;
mainVideoList: any[];
loading: boolean;
}>(),
{
mainIndex: null,
eplay: 0,
},
);
const emit = defineEmits([
'update:totalTime',
'currentTime',
'playEnd',
'mainVideoStartPlay',
'mainVideoPlayEnd',
'update:progress',
'update:playMainIndex',
'mainVideoListChange',
]);
const emit = defineEmits(['currentTime', 'playEnd', 'update:progress', 'update:playMainIndex', 'mainVideoListChange']);
const store = useStore();
const videoNum = computed(() => store.getters['live/getVideoNum']);
const liveVideoStatus = computed(() => store.getters['live/getLiveVideoStatus']);
// 视频类型
const liveInfo = ref({});
const loop = ref(false);
const footerStatus = ref(false);
const showFirstVideo = ref(true);
......@@ -148,26 +137,79 @@ const closeInterval = () => {
const confirm = () => {
openInterval();
onPlay();
videoFirstPlay.value = false;
emit('mainVideoStartPlay', props.mainIndex);
};
// 主视频可以播放
const mainVideoCanplay = (index: number) => {
// 获取视频总时长
let mainVideoTotalTime = videoFirst.value[index].duration;
emit('mainVideoListChange', index, 'total', mainVideoTotalTime);
if (!videoFirstPlay.value) {
//
onPlay();
emit('mainVideoStartPlay', props.mainIndex);
}
emit('mainVideoListChange', {
index: index,
key: 'total',
value: mainVideoTotalTime,
});
};
// 主视频播放要更新的状态
const mainVideoPlayStatus = (index: number) => {
emit('mainVideoListChange', {
index: index,
key: 'play',
value: true,
});
emit('mainVideoListChange', {
index: index,
key: 'show',
value: true,
});
};
// 下一个要播放的视频
const nextVideoToPlay = () => {
const { mainVideoList } = props;
return mainVideoList.findIndex((item: any) => item.url && !item.playEnd && !item.play);
};
// 主视频播放完毕
const firstVideoEnded = () => {
if (videoFirst.value.ended) {
emit('mainVideoPlayEnd', props.mainIndex);
const firstVideoEnded = (index: number) => {
if (videoFirst.value[index].ended) {
// 播放状态
emit('mainVideoListChange', {
index: index,
key: 'play',
value: false,
});
// 播放结束
emit('mainVideoListChange', {
index: index,
key: 'playEnd',
value: true,
});
// 视频状态(完成)
emit('mainVideoListChange', {
index: index,
type: 'videoIndex',
videoKey: 'status',
videoValue: true,
});
if (!loop.value) {
// 找到下一个要播放的
let nextIndex = nextVideoToPlay();
if (nextIndex !== -1) {
console.log('开始播放下一个主视频');
mainVideoPlayStatus(nextIndex);
videoFirst.value[nextIndex].play();
// 更新当前正在播放的video标签下标
emit('update:playMainIndex', nextIndex);
} else {
console.log(props.mainVideoList);
console.log('未找到下一条视频');
}
} else {
console.log('循环播放不需要找下一个视频');
}
}
};
......@@ -176,7 +218,7 @@ const secondVideoEnded = () => {
if (videoSecond.value?.ended) {
emit('playEnd', props.playId);
showFirstVideo.value = true;
videoFirst.value?.play();
videoFirst.value[currentPlayMainIndex.value].play();
}
};
......@@ -194,21 +236,22 @@ const canplay2 = () => {
};
const secondPlay = () => {
videoFirst.value?.pause();
videoFirst.value[currentPlayMainIndex.value].pause();
videoSecond.value?.play();
};
// 主视频播放
const onPlay = () => {
console.log('执行几次');
// 找到要播放的
const { mainVideoList } = props;
let index = mainVideoList.findIndex((item: any) => !item.playEnd && item.url && !item.play);
if (index !== -1) {
// 更新状态
mainVideoPlayStatus(index);
console.log(index, '开始播放', mainVideoList[index]);
// 开始播放
videoFirst.value[index].play();
// 更新状态
emit('mainVideoListChange', index, 'play', true);
emit('update:playMainIndex', index);
}
// 第一个视频连带着第二个视频一起播放--立马暂停是为了处理后续进来的视频
videoSecond.value.play();
......@@ -217,7 +260,7 @@ const onPlay = () => {
};
const onStop = () => {
videoFirst.value.pause();
videoFirst.value[currentPlayMainIndex.value].pause();
};
watch(
......@@ -233,9 +276,9 @@ watch(
watch(
() => props.eplay,
(v) => {
videoFirst.value.currentTime = 0;
videoFirst.value[currentPlayMainIndex.value].currentTime = 0;
// 播放video
videoFirst.value.play();
videoFirst.value[currentPlayMainIndex.value].play();
},
);
......@@ -243,12 +286,17 @@ watch(
watch(
() => props.liveDetail,
(v) => {
if (v && v.is_disorganize === 0) {
// 不洗稿,开启循环播放
console.log('不洗稿,开启循环播放');
loop.value = true;
} else {
console.log('需要洗稿,loop设置false');
if (v) {
liveInfo.value = v;
if (v.type == scriptTypePhonetics) {
// 音频类型--不洗稿,但是要获取轮询获取下一个视频
} else if (v.is_disorganize === 0) {
// 不洗稿,开启循环播放
console.log('不洗稿,开启循环播放');
loop.value = true;
} else {
console.log('需要洗稿,loop设置false');
}
}
},
);
......@@ -278,11 +326,15 @@ watch(
);
const updateTime = () => {
if (total.value) {
let row = videoFirst.value[currentPlayMainIndex.value];
// 获取当前下标的total
const { mainVideoList } = props;
let total = mainVideoList[currentPlayMainIndex.value].total;
if (total) {
// 计算百分比
emit('update:progress', Math.floor((videoFirst.value.currentTime / total.value) * 100));
emit('update:progress', Math.floor((row.currentTime / total) * 100));
// 提交当前进度
emit('currentTime', videoFirst.value.currentTime);
emit('currentTime', currentPlayMainIndex.value, row.currentTime);
}
};
// 减小正在播放的视频音量
......
......@@ -172,7 +172,9 @@ export default defineComponent({
if (item.url) {
list.push(item.url);
// 计算文件大小
totalSize += item.file.size;
if (item.file) {
totalSize += item.file.size;
}
}
}
submitList(list, false);
......
......@@ -4,18 +4,13 @@
<AddVideoPlay
v-model:playMainIndex="currentPlayMainIndex"
v-model:progress="progress"
v-model:totalTime="totalTime"
:loading="loading"
:mainIndex="mainVideoIndex"
:playId="addVideoId"
:video1="getCurrentMainVideo"
:liveDetail="liveDetail"
:video2="addVideo"
:mainVideoList="mainVideoList"
:eplay="eplay"
@playEnd="playEnd"
@mainVideoPlayEnd="mainVideoPlayEnd"
@mainVideoStartPlay="mainVideoStartPlay"
@currentTime="currentTimeChange"
@mainVideoListChange="mainVideoListChange"
></AddVideoPlay>
......@@ -24,7 +19,7 @@
</template>
<script lang="ts" setup>
import { computed, onBeforeUnmount, onMounted, reactive, ref, watch } from 'vue';
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue';
import AddVideoPlay from '@/components/AddVideoPlay.vue';
import { getLiveDetail } from '@/utils/api/userApi';
import { useRoute, useRouter } from 'vue-router';
......@@ -37,6 +32,7 @@ import { v4 } from 'uuid';
import useConfuse from '@/hooks/useConfuse';
import { CONFUSE_STATUS } from '@/service/Live';
import { processTextCallback } from '@/hooks/useScript';
import { scriptTypeText } from '@/service/CreateLive';
const { currentConfuseId, confuseList, currentStartConfuse } = useConfuse();
const { openInterval: confuseInterval } = processTextCallback();
......@@ -54,11 +50,6 @@ const eplay = ref(0);
// 剩余多少时长时开始洗稿并获取下一个视频
const esidueTime = 60 * 10;
// 当前播放的主视频的总视频时长
const totalTime = ref(0);
// 当前的播放进度
const currentTime = ref(0);
const imgs = {
mp4: new URL('../../assets/img/1.mp4', import.meta.url).href,
mp3: new URL('../../assets/img/2.wav', import.meta.url).href,
......@@ -70,14 +61,14 @@ let interval = null;
// 定时获取直播互动内容
let intervalLive = null;
// 定时获取主视频任务
// 定时获取后台主视频任务
let intervalMainVideo = null;
// 定时获取下一个要播放的主视频
let intervalLocalMainVideo = null;
// 主视频列表
const realVideoList = ref([]);
// 当前主视频的下标
const mainVideoIndex = ref();
// 当前洗稿的下标(在主视频列表中的下标)
const confuseIndex = ref();
......@@ -122,9 +113,29 @@ const mainVideoList = ref([
]);
// 主视频列表状态更新
const mainVideoListChange = (index: number, key: string, value: any) => {
mainVideoList.value[index][key] = value;
console.log(mainVideoList.value[index], '状态');
const mainVideoListChange = (params: any) => {
if (typeof params.index === 'number' && !params.type) {
mainVideoList.value[params.index][params.key] = params.value;
if (params.key == 'show') {
// 列表其他index全部隐藏
for (let i = 0; i < mainVideoList.value.length; i++) {
let item = mainVideoList.value[i];
if (params.index != i) {
item.show = false;
}
}
}
}
// 更新视频列表
if (typeof params.index === 'number' && params.type === 'videoIndex') {
// 找到下标
let mainIndex = mainVideoList.value.findIndex((item: any, index: any) => index == params.index);
if (mainIndex !== -1) {
let videoIndex = mainVideoList.value[mainIndex].videoIndex;
realVideoList.value[videoIndex][params.videoKey] = params.videoValue;
console.log(realVideoList.value[videoIndex], '更新主视频列表');
}
}
};
const submitAudioTask = async (list: any[]) => {
......@@ -159,14 +170,6 @@ watch(
},
);
// 当前主视频
const getCurrentMainVideo = computed(() => {
if (typeof mainVideoIndex.value === 'number' && realVideoList.value[mainVideoIndex.value].result) {
return realVideoList.value[mainVideoIndex.value].result;
}
return '';
});
// 提交洗稿
const submitConfuse = async () => {
try {
......@@ -174,7 +177,7 @@ const submitConfuse = async () => {
let content = '';
let contentList = liveDetail.value.type_content;
// 记录本次洗稿id
confuseIndex.value = mainVideoIndex.value;
// confuseIndex.value = mainVideoIndex.value;
if (contentList.length) {
contentList.forEach((item: any) => {
content += item.content;
......@@ -193,19 +196,20 @@ const submitConfuse = async () => {
};
// 当前播放进度变化
const currentTimeChange = (value: number) => {
currentTime.value = value;
const currentTimeChange = (index: number, value: number) => {
let row = mainVideoList.value[index];
// 剩余多少没有播放
let currentEsidueTime = totalTime.value - value;
let currentVideoRow = realVideoList.value[mainVideoIndex.value];
// 低于设置的值、没有开始洗稿、有文本内容
let currentEsidueTime = row.total - value;
let currentVideoRow = realVideoList.value[row.videoIndex];
// 低于设置的值、没有开始洗稿、有文本内容 、必须是文本脚本
if (
currentEsidueTime < esidueTime &&
currentVideoRow.confuse === CONFUSE_STATUS.CONFUSE_STATUS_WAIT &&
liveDetail.value.type_content.length &&
typeof liveDetail.value.phonetic_timbres_id === 'number' &&
typeof liveDetail.value.tone_id === 'number' &&
liveDetail.value.is_disorganize
liveDetail.value.is_disorganize &&
liveDetail.value.type == scriptTypeText
) {
currentVideoRow.confuse = CONFUSE_STATUS.CONFUSE_STATUS_PROGRESS;
console.log('直播开始洗稿');
......@@ -214,19 +218,6 @@ const currentTimeChange = (value: number) => {
}
};
// 主视频开始播放
const mainVideoStartPlay = (index: number) => {
// realVideoList.value[index].play = true;
};
// 主视频播放完毕
const mainVideoPlayEnd = (index: number) => {
console.log('主视频播放完毕');
realVideoList.value[index].status = true;
// 找下一个
takeMainVideo();
};
// 互动视频播放结束
const playEnd = (id: any) => {
if (id) {
......@@ -248,7 +239,7 @@ const StartIntervalMainVideo = () => {
}, 10000);
};
// 关闭
// 关闭主视频任务定时器
const closeIntervalMainVideo = () => {
window.clearInterval(intervalMainVideo);
clearInterval(intervalMainVideo);
......@@ -261,7 +252,21 @@ const stopInterval = () => {
interval = null;
};
// 获取最新的内容
// 开启本地主视频定时器
const openLocalMainVideoInterval = () => {
intervalLocalMainVideo = window.setInterval(() => {
takeMainVideoV2(false);
}, 5000);
};
// 关闭本地主视频定时器
const closeLocalMainVideoInterval = () => {
window.clearInterval(intervalLocalMainVideo);
clearInterval(intervalLocalMainVideo);
intervalLocalMainVideo = null;
};
// 获取最新的要播放的互动内容
const openInterval = () => {
interval = window.setInterval(() => {
// 找到第一个没有播放的
......@@ -387,9 +392,18 @@ const getDetail = async (type: string = '') => {
});
if (isDev()) {
let list = [
'http://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/files/user/admin/e9f3d546-05f2-4dc1-a37d-d6c0ca960e43.mp4',
'http://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/files/user/admin/9604b4aa-e509-4f74-a73f-a0dc130f8f28.mp4',
'http://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/files/user/admin/f2112aea-6f69-4403-acef-33d0fda7e736.mp4',
];
if (realVideoList.value.length > list.length) {
console.log('不需要添加了');
return;
}
mergeCallback({
// video: imgs.mp4,
video: 'http://yunyi-live.oss-cn-hangzhou.aliyuncs.com/live/output/87.mp4',
video: list[realVideoList.value.length - 1],
index: realVideoList.value.length - 1,
});
} else {
......@@ -445,28 +459,8 @@ const submitVideo = () => {
}
};
// 取主视频(v1)
const takeMainVideo = () => {
let index = realVideoList.value.findIndex((item: any) => !item.remove && item.result && !item.status);
if (index !== -1) {
realVideoList.value[index].remove = true;
if (
typeof mainVideoIndex.value === 'number' &&
realVideoList.value[index].result == realVideoList.value[mainVideoIndex.value].result
) {
console.log('本次获取到的视频与上次一致,重新播放');
eplay.value += 1;
}
mainVideoIndex.value = index;
} else {
console.log('重新播放当前视频');
// 手动重新开始播放
eplay.value += 1;
}
};
// 取主视频(v2)
const takeMainVideoV2 = () => {
const takeMainVideoV2 = (first: boolean = true) => {
// 找到第一个播放完毕的
let index = mainVideoList.value.findIndex((item: any) => item.playEnd);
if (index !== -1) {
......@@ -476,10 +470,14 @@ const takeMainVideoV2 = () => {
mainVideoList.value[index].url = realVideoList.value[videoIndex].result;
// 更新状态
mainVideoList.value[index].playEnd = false;
mainVideoList.value[index].videoIndex = videoIndex;
// 视频已被取走
realVideoList.value[videoIndex].remove = true;
// 视频加载完毕
loading.value = false;
console.log(mainVideoList.value[index], '取出下一条要播放的视频', index, videoIndex);
if (first) {
// 视频加载完毕
loading.value = false;
}
}
}
};
......@@ -487,8 +485,7 @@ const takeMainVideoV2 = () => {
// python 回调
const mergeCallback = (params: any) => {
try {
console.log('python回调');
console.log(params);
// console.log('python回调',params);
let index = params.index;
if (index) {
index = parseInt(index + '');
......@@ -499,7 +496,6 @@ const mergeCallback = (params: any) => {
// 首次播放
let list = realVideoList.value.filter((item: any) => item.remove === true);
if (!list.length) {
console.log('首次播放');
// takeMainVideo();
takeMainVideoV2();
}
......@@ -533,11 +529,14 @@ onMounted(async () => {
console.error('没有pyjs');
}
// 获取互动
// 获取后台互动
startLiveInterval();
// 获取主视频
// 获取后台主视频
StartIntervalMainVideo();
// 本地轮询获取要播放的互动视频
openInterval();
// 本地轮询获取要播放的主视频
openLocalMainVideoInterval();
// 可以开播
await getDetail('init');
// 获取音调和音色
......@@ -547,6 +546,7 @@ onBeforeUnmount(() => {
closeLiveInterval();
stopInterval();
closeIntervalMainVideo();
closeLocalMainVideoInterval();
});
</script>
......
......@@ -434,7 +434,14 @@ const updateInfo = (info: any) => {
} else if (info.content) {
// 草稿
type = info.content.type;
type_content = info.content.type_content;
console.log(type);
if (type == scriptTypeText) {
// 文本
type_content = info.content.content;
} else {
// 音频
type_content = info.content.type_content;
}
phonetic_timbres_id = info.content.phonetic_timbres_id ? info.content.phonetic_timbres_id : '';
tone_id = info.content.tone_id ? info.content.tone_id : '';
}
......@@ -452,15 +459,32 @@ const updateInfo = (info: any) => {
} else {
// 音频
currentOption.value = scriptTypePhonetics;
// mp3Url.value = type_content;
if (type_content) {
audioScriptList.value = type_content.map((item: any) => {
return {
data: item,
};
});
if (route.query.type == 'edit') {
if (type_content) {
audioScriptList.value = type_content.map((item: any) => {
return {
data: item,
};
});
} else {
audioScriptList.value = [];
}
} else {
audioScriptList.value = [];
// 草稿
if (type_content) {
audioScriptList.value = type_content.map((item: any) => {
item.forEach((it: any) => {
it.audio_url = it.content;
it.status = true;
it.url = it.content;
});
return {
data: item,
};
});
} else {
audioScriptList.value = [];
}
}
if (phonetic_timbres_id) {
......
......@@ -219,17 +219,17 @@ const getEditInfo = async (id: any, type: string) => {
[createLiveKeys.commentMethod]: 1,
[createLiveKeys.interactiveLibrary]: content.interaction_ids,
};
if (res.data.type == '2') {
if (content.type == '2') {
// 文本
params[createLiveKeys.textSoundColor] = content.phonetic_timbres_id ? content.phonetic_timbres_id : '';
if (content.type_content) {
params[createLiveKeys.textScriptList] = [content.type_content];
if (content.content) {
params[createLiveKeys.textScriptList] = [content.content];
}
} else {
// 音频音色
params[createLiveKeys.phoneticsSoundColor] = content.phonetic_timbres_id ? content.phonetic_timbres_id : '';
if (content.type_content) {
params[createLiveKeys.phoneticsFile] = content.type_content.map((item: any) => {
params[createLiveKeys.audioScriptList] = content.type_content.map((item: any) => {
return {
data: item,
};
......
......@@ -11,8 +11,8 @@ const getBaseUrl = () => {
// return 'http://156.247.11.21:92/';
return '';
}
return 'http://video-assistant.test';
// return 'http://156.247.11.21:92/';
// return 'http://video-assistant.test';
return 'http://156.247.11.21:92/';
};
const instance = axios.create({
......
......@@ -26,9 +26,9 @@ export default defineConfig(({ command, mode }) => {
plugins: [
createVuePlugin(),
vueJsx(),
eslintPlugin({
include: ['src/**/*.ts', 'src/**/*.vue', 'src/*.ts', 'src/*.vue'],
}),
// eslintPlugin({
// include: ['src/**/*.ts', 'src/**/*.vue', 'src/*.ts', 'src/*.vue'],
// }),
viteMockServe({
mockPath: 'mock',
localEnabled: true,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment