Commit dfa5964d by haojie

修复创建直播页面重复请求动作接口的问题

parent 85c88a23
<template> <template>
<div class="add-video-play"> <div class="add-video-play">
<div class="main-video-play" v-show="showFirstVideo"> <div class="main-video-play" v-show="showFirstVideo && !showActionVideo">
<template v-for="(item, index) in mainVideoList" :key="item.name"> <template v-for="(item, index) in mainVideoList" :key="item.name">
<video <video
v-show="item.show" v-show="item.show"
...@@ -14,9 +14,9 @@ ...@@ -14,9 +14,9 @@
></video> ></video>
</template> </template>
</div> </div>
<!-- --> <!-- 互动 -->
<video <video
v-show="!showFirstVideo" v-show="!showFirstVideo && !showActionVideo"
ref="videoSecond" ref="videoSecond"
:volume="secondVideoVolume" :volume="secondVideoVolume"
class="video-default" class="video-default"
...@@ -24,6 +24,15 @@ ...@@ -24,6 +24,15 @@
@ended="secondVideoEnded" @ended="secondVideoEnded"
@canplay="canplay2" @canplay="canplay2"
></video> ></video>
<!-- 动作 -->
<video
v-show="showActionVideo"
ref="videoAction"
class="video-default"
:src="actionVideo"
@ended="actionVideoEnded"
@canplay="actionCanplay"
></video>
<ConfirmDialog <ConfirmDialog
v-model="confirmVisible" v-model="confirmVisible"
:closeOnOverlayClick="false" :closeOnOverlayClick="false"
...@@ -58,18 +67,34 @@ const props = withDefaults( ...@@ -58,18 +67,34 @@ const props = withDefaults(
defineProps<{ defineProps<{
playMainIndex: number | null; playMainIndex: number | null;
video2: string; video2: string;
actionVideo?: string;
playId?: any; playId?: any;
progress?: number; progress?: number;
liveDetail: any; liveDetail: any;
mainVideoList: any[]; mainVideoList: any[];
loading: boolean; loading: boolean;
currentMainVideoIndex: number | null;
playInfo: any;
firstVideoIsMain: boolean;
showActionVideo: boolean;
}>(), }>(),
{ {
progress: 0, progress: 0,
actionVideo: '',
}, },
); );
const emit = defineEmits(['currentTime', 'playEnd', 'update:progress', 'update:playMainIndex', 'mainVideoListChange']); const emit = defineEmits([
'currentTime',
'playEnd',
'actionPlayChange',
'update:progress',
'update:playMainIndex',
'mainVideoListChange',
'initActionVideo',
'update:showActionVideo',
'update:firstVideoIsMain',
]);
const store = useStore(); const store = useStore();
const videoNum = computed(() => store.getters['live/getVideoNum']); const videoNum = computed(() => store.getters['live/getVideoNum']);
...@@ -78,6 +103,7 @@ const liveVideoStatus = computed(() => store.getters['live/getLiveVideoStatus']) ...@@ -78,6 +103,7 @@ const liveVideoStatus = computed(() => store.getters['live/getLiveVideoStatus'])
// 视频类型 // 视频类型
const liveInfo = ref({}); const liveInfo = ref({});
const loop = ref(false); const loop = ref(false);
// 主视频与互动视频的显隐
const showFirstVideo = ref(true); const showFirstVideo = ref(true);
// 第二个视频是否播放 // 第二个视频是否播放
const videoSecondPlay = ref(false); const videoSecondPlay = ref(false);
...@@ -86,6 +112,7 @@ const confirmVisible = ref(true); ...@@ -86,6 +112,7 @@ const confirmVisible = ref(true);
// 第二个视频是否首次播放 // 第二个视频是否首次播放
const videoSecondFirstPlay = ref(true); const videoSecondFirstPlay = ref(true);
const actionVideoFirstPlay = ref(true);
// 当前正在播放的主视频下标 // 当前正在播放的主视频下标
const currentPlayMainIndex = ref(props.playMainIndex); const currentPlayMainIndex = ref(props.playMainIndex);
...@@ -95,9 +122,10 @@ const currentPlayMainIndex = ref(props.playMainIndex); ...@@ -95,9 +122,10 @@ const currentPlayMainIndex = ref(props.playMainIndex);
*/ */
// 主视频 // 主视频
const videoFirst = ref<HTMLVideoElement>(); const videoFirst = ref<HTMLVideoElement>();
// 互动视频 // 互动视频
const videoSecond = ref<HTMLVideoElement>(); const videoSecond = ref<HTMLVideoElement>();
// 动作视频
const videoAction = ref<HTMLVideoElement>();
// 初始音量 // 初始音量
const initVolume = 1; const initVolume = 1;
...@@ -108,6 +136,43 @@ const secondVideoVolume = ref(initVolume); ...@@ -108,6 +136,43 @@ const secondVideoVolume = ref(initVolume);
let interval = null; let interval = null;
// 更新动作视频显示状态
const updateActionVideoShow = (status: boolean) => {
emit('update:showActionVideo', status);
};
// 更新主视频的显示和隐藏状态
const updateMainVideoShow = (status: boolean, index: number | boolean = false) => {
emit('mainVideoListChange', {
index: typeof index === 'number' ? index : currentPlayMainIndex.value,
key: 'show',
value: status,
});
};
// 更新主视频播放状态
const mainVideoPlayChange = (status: boolean, index: number | boolean = false) => {
if (status) {
closeInterval();
if (index === false && typeof currentPlayMainIndex.value === 'number') {
updateMainVideoShow(true);
videoFirst.value[currentPlayMainIndex.value].play();
} else if (typeof index === 'number') {
updateMainVideoShow(true, index);
videoFirst.value[index].play();
}
openInterval();
} else {
if (index === false && typeof currentPlayMainIndex.value === 'number') {
updateMainVideoShow(false);
videoFirst.value[currentPlayMainIndex.value].pause();
} else if (typeof index === 'number') {
updateMainVideoShow(false, index);
videoFirst.value[index].pause();
}
}
};
// 离开前先关闭弹窗 // 离开前先关闭弹窗
onBeforeRouteLeave((to, from, next) => { onBeforeRouteLeave((to, from, next) => {
confirmVisible.value = false; confirmVisible.value = false;
...@@ -128,10 +193,16 @@ const closeInterval = () => { ...@@ -128,10 +193,16 @@ const closeInterval = () => {
// 确定播放 // 确定播放
const confirm = () => { const confirm = () => {
openInterval(); if (props.firstVideoIsMain) {
onPlay(); openInterval();
// 通知python开始播放了 onPlay();
// callPyjsInWindow('') } else {
currentPlayMainIndex.value = 0;
// 准备播放动作视频
actionVideoPlayChange(true);
}
// 确定之后修改状态
emit('update:firstVideoIsMain', true);
}; };
// 主视频可以播放 // 主视频可以播放
...@@ -161,20 +232,42 @@ const mainVideoPlayStatus = (index: number) => { ...@@ -161,20 +232,42 @@ const mainVideoPlayStatus = (index: number) => {
}; };
// 下一个要播放的视频 // 下一个要播放的视频
const nextVideoToPlay = () => { const nextVideoToPlay = (status: boolean = true) => {
const { mainVideoList } = props; const { mainVideoList } = props;
if (!loop.value) { if (!loop.value) {
// 找到下一个要播放的 // 找到下一个要播放的
let nextIndex = mainVideoList.findIndex((item: any) => item.url && !item.playEnd && !item.play); let nextIndex = mainVideoList.findIndex((item: any) => item.url && !item.playEnd && !item.play);
if (nextIndex !== -1) { if (nextIndex !== -1 && status) {
console.log('开始播放下一个主视频');
mainVideoPlayStatus(nextIndex); mainVideoPlayStatus(nextIndex);
videoFirst.value[nextIndex].play();
// 更新当前正在播放的video标签下标 // 更新当前正在播放的video标签下标
emit('update:playMainIndex', nextIndex); emit('update:playMainIndex', nextIndex);
if (mainVideoList[nextIndex].restart && status) {
// 本次播放是重复播放,通知父组件初始化动作视频的状态
console.log('本次播放是重复播放,初始化动作视频的状态');
emit('initActionVideo', props.currentMainVideoIndex);
return;
}
// 更新状态
emit('mainVideoListChange', {
index: nextIndex,
key: 'restart',
value: false,
});
// 播放
console.log('开始播放下一个主视频,1');
mainVideoPlayChange(true, nextIndex);
} else if (nextIndex == -1 && !status) {
// 更新状态
emit('mainVideoListChange', {
index: currentPlayMainIndex.value,
key: 'restart',
value: false,
});
// 播放
console.log('开始播放下一个主视频,2');
mainVideoPlayChange(true);
} else { } else {
console.log(props.mainVideoList); console.log('未找到下一个要播放的主视频');
console.log('未找到下一条视频');
} }
} else { } else {
console.log('循环播放不需要找下一个视频'); console.log('循环播放不需要找下一个视频');
...@@ -204,7 +297,7 @@ const firstVideoEnded = (index: number) => { ...@@ -204,7 +297,7 @@ const firstVideoEnded = (index: number) => {
videoValue: true, videoValue: true,
}); });
// 强制关闭自己的播放状态,防止loop生效 // 强制关闭自己的播放状态,防止loop生效
videoFirst.value[currentPlayMainIndex.value].pause(); mainVideoPlayChange(false);
nextVideoToPlay(); nextVideoToPlay();
} }
...@@ -215,7 +308,28 @@ const secondVideoEnded = () => { ...@@ -215,7 +308,28 @@ const secondVideoEnded = () => {
if (videoSecond.value?.ended) { if (videoSecond.value?.ended) {
emit('playEnd', props.playId); emit('playEnd', props.playId);
showFirstVideo.value = true; showFirstVideo.value = true;
videoFirst.value[currentPlayMainIndex.value].play(); mainVideoPlayChange(true);
}
};
// 动作视频播放完毕
const actionVideoEnded = () => {
if (videoAction.value.ended) {
// 更新状态
emit('actionPlayChange', {
key: 'play',
value: false,
index: props.currentMainVideoIndex,
});
emit('actionPlayChange', {
key: 'status',
value: true,
index: props.currentMainVideoIndex,
clear: true,
});
// 重新播放
mainVideoPlayChange(true);
updateActionVideoShow(false);
} }
}; };
...@@ -232,8 +346,32 @@ const canplay2 = () => { ...@@ -232,8 +346,32 @@ const canplay2 = () => {
} }
}; };
// 动作视频播放状态改变
const actionVideoPlayChange = (status: boolean) => {
if (status) {
videoAction.value.play();
updateActionVideoShow(true);
} else {
videoAction.value.pause();
updateActionVideoShow(false);
}
};
// 动作视频可以播放
const actionCanplay = () => {
if (actionVideoFirstPlay.value) {
return;
}
if (props.firstVideoIsMain) {
console.log('动作视频开始播放');
// 停止播放主视频
mainVideoPlayChange(false);
actionVideoPlayChange(true);
}
};
const secondPlay = () => { const secondPlay = () => {
videoFirst.value[currentPlayMainIndex.value].pause(); mainVideoPlayChange(false);
videoSecond.value?.play(); videoSecond.value?.play();
}; };
...@@ -247,7 +385,7 @@ const onPlay = () => { ...@@ -247,7 +385,7 @@ const onPlay = () => {
mainVideoPlayStatus(index); mainVideoPlayStatus(index);
console.log(index, '开始播放', mainVideoList[index]); console.log(index, '开始播放', mainVideoList[index]);
// 开始播放 // 开始播放
videoFirst.value[index].play(); mainVideoPlayChange(true, index);
emit('update:playMainIndex', index); emit('update:playMainIndex', index);
} }
// 第一个视频连带着第二个视频一起播放--立马暂停是为了处理后续进来的视频 // 第一个视频连带着第二个视频一起播放--立马暂停是为了处理后续进来的视频
...@@ -257,7 +395,7 @@ const onPlay = () => { ...@@ -257,7 +395,7 @@ const onPlay = () => {
}; };
const onStop = () => { const onStop = () => {
videoFirst.value[currentPlayMainIndex.value].pause(); mainVideoPlayStatus(false);
}; };
watch( watch(
...@@ -269,6 +407,14 @@ watch( ...@@ -269,6 +407,14 @@ watch(
}, },
); );
watch(props.playInfo, (v) => {
if (v && v.is_main) {
//
console.log('开始播放主视频-watch');
nextVideoToPlay(false);
}
});
// 判断是否洗稿 // 判断是否洗稿
watch( watch(
() => props.liveDetail, () => props.liveDetail,
...@@ -280,7 +426,7 @@ watch( ...@@ -280,7 +426,7 @@ watch(
} else if (v.is_disorganize === 0) { } else if (v.is_disorganize === 0) {
// 不洗稿,开启循环播放 // 不洗稿,开启循环播放
console.log('不洗稿,开启循环播放'); console.log('不洗稿,开启循环播放');
loop.value = true; // loop.value = true;
} else { } else {
console.log('需要洗稿,loop设置false'); console.log('需要洗稿,loop设置false');
} }
...@@ -306,6 +452,15 @@ watch( ...@@ -306,6 +452,15 @@ watch(
); );
watch( watch(
() => props.actionVideo,
(v) => {
if (v) {
actionVideoFirstPlay.value = false;
}
},
);
watch(
() => currentPlayMainIndex.value, () => currentPlayMainIndex.value,
(v) => { (v) => {
emit('update:playMainIndex', v); emit('update:playMainIndex', v);
......
...@@ -3,12 +3,19 @@ ...@@ -3,12 +3,19 @@
<div class="start-only-video-live"> <div class="start-only-video-live">
<AddVideoPlay <AddVideoPlay
v-model:playMainIndex="currentPlayMainIndex" v-model:playMainIndex="currentPlayMainIndex"
v-model:showActionVideo="showActionVideo"
v-model:firstVideoIsMain="firstVideoIsMain"
:loading="loading" :loading="loading"
:playId="addVideoId" :playId="addVideoId"
:liveDetail="liveDetail" :liveDetail="liveDetail"
:video2="addVideo" :video2="addVideo"
:actionVideo="actionVideo"
:mainVideoList="mainVideoList" :mainVideoList="mainVideoList"
:currentMainVideoIndex="currentMainVideoIndex"
:playInfo="playInfo"
@playEnd="playEnd" @playEnd="playEnd"
@actionPlayChange="actionPlayChange"
@initActionVideo="initActionVideo"
@currentTime="currentTimeChange" @currentTime="currentTimeChange"
@mainVideoListChange="mainVideoListChange" @mainVideoListChange="mainVideoListChange"
></AddVideoPlay> ></AddVideoPlay>
...@@ -25,10 +32,17 @@ const { ...@@ -25,10 +32,17 @@ const {
addVideoId, addVideoId,
liveDetail, liveDetail,
addVideo, addVideo,
actionVideo,
mainVideoList, mainVideoList,
currentMainVideoIndex,
playInfo,
firstVideoIsMain,
showActionVideo,
playEnd, playEnd,
actionPlayChange,
currentTimeChange, currentTimeChange,
mainVideoListChange, mainVideoListChange,
initActionVideo,
} = useScript(); } = useScript();
/** /**
* 合并主视频,动作视频开始时间从后台取 * 合并主视频,动作视频开始时间从后台取
......
...@@ -12,6 +12,7 @@ import { CONFUSE_STATUS } from '@/service/Live'; ...@@ -12,6 +12,7 @@ import { CONFUSE_STATUS } from '@/service/Live';
import { processTextCallback } from '@/hooks/useScript'; import { processTextCallback } from '@/hooks/useScript';
import { scriptTypeText } from '@/service/CreateLive'; import { scriptTypeText } from '@/service/CreateLive';
import { writeLog } from '@/utils/pyqt'; import { writeLog } from '@/utils/pyqt';
import { getDurationOfAudioFile } from '@/utils/audio';
export default function () { export default function () {
const { currentConfuseId, confuseList, stopConfuse, openConfuseInterval } = useConfuse(); const { currentConfuseId, confuseList, stopConfuse, openConfuseInterval } = useConfuse();
...@@ -56,8 +57,14 @@ export default function () { ...@@ -56,8 +57,14 @@ export default function () {
// 主视频列表 // 主视频列表
const realVideoList = ref([]); const realVideoList = ref([]);
// 当前播放的视频中,第一个视频是否为主视频
const firstVideoIsMain = ref(true);
// 互动视频 // 互动视频
const addVideo = ref(imgs.mp4); const addVideo = ref(imgs.mp4);
// 动作视频
const actionVideo = ref(imgs.mp4);
const showActionVideo = ref(false);
// 互动视频列表 // 互动视频列表
const addVideoList = ref([]); const addVideoList = ref([]);
// 互动视频当前播放id // 互动视频当前播放id
...@@ -65,6 +72,11 @@ export default function () { ...@@ -65,6 +72,11 @@ export default function () {
// 直播详情 // 直播详情
const liveDetail = ref<any>({}); const liveDetail = ref<any>({});
// 通知视频播放
const playInfo = ref({
is_main: true,
num: 0,
});
// 主视频列表 // 主视频列表
const mainVideoList = ref([ const mainVideoList = ref([
...@@ -110,6 +122,8 @@ export default function () { ...@@ -110,6 +122,8 @@ export default function () {
} }
return null; return null;
}); });
// 当前播放的动作视频的下标
const currentActionIndex = ref();
// 主视频列表状态更新 // 主视频列表状态更新
const mainVideoListChange = (params: any) => { const mainVideoListChange = (params: any) => {
...@@ -203,12 +217,13 @@ export default function () { ...@@ -203,12 +217,13 @@ export default function () {
(item: any, index: number) => index !== currentPlayMainIndex.value, (item: any, index: number) => index !== currentPlayMainIndex.value,
); );
if (videoTagIndex !== -1) { if (videoTagIndex !== -1) {
let hideVideo = mainVideoList.value[videoTagIndex]; let hideVideo: any = mainVideoList.value[videoTagIndex];
// 隐藏的视频已经播放结束 且 视频列表中不存在有url,没取走的视频 // 隐藏的视频已经播放结束 且 视频列表中不存在有url,没取走的视频
let notRemove = realVideoList.value.find((item: any) => item.result && !item.remove); let notRemove = realVideoList.value.find((item: any) => item.result && !item.remove);
if (!hideVideo.play && hideVideo.playEnd && !notRemove) { if (!hideVideo.play && hideVideo.playEnd && !notRemove) {
console.log('需要重新入队'); console.log('需要重新入队');
status = true; status = true;
hideVideo.restart = true;
} }
// start // start
...@@ -261,10 +276,13 @@ export default function () { ...@@ -261,10 +276,13 @@ export default function () {
// 当前播放进度变化 // 当前播放进度变化
const currentTimeChange = (index: number, value: number) => { const currentTimeChange = (index: number, value: number) => {
// console.log(value, '当前进度');
let row = mainVideoList.value[index]; let row = mainVideoList.value[index];
// 剩余多少没有播放 // 剩余多少没有播放
let currentEsidueTime = row.total - value; let currentEsidueTime = row.total - value;
let currentVideoRow = realVideoList.value[row.videoIndex]; let currentVideoRow = realVideoList.value[row.videoIndex];
// 更新当前进度
currentVideoRow.current = value;
// 低于设置的值、没有开始洗稿、有文本内容 、必须是文本脚本 // 低于设置的值、没有开始洗稿、有文本内容 、必须是文本脚本
if ( if (
currentEsidueTime < esidueTime && currentEsidueTime < esidueTime &&
...@@ -303,6 +321,37 @@ export default function () { ...@@ -303,6 +321,37 @@ export default function () {
} }
}; };
// 动作视频更新
const actionPlayChange = (params: any) => {
try {
const { key, value, index } = params;
const current = realVideoList.value[index].actionUrl[currentActionIndex.value];
current[key] = value;
// 播放完毕,清空url
if (params.clear) {
actionVideo.value = '';
}
} catch (e) {
console.log('动作视频更新失败');
console.log(e);
}
};
// 初始化动作视频的状态
const initActionVideo = (index: number) => {
const row = realVideoList.value[index];
row.actionUrl.forEach((item: any) => {
item.remove = false;
item.play = false;
item.status = false;
});
if (row.is_main) {
// 是主视频--通知视频直接播放
playInfo.value.is_main = true;
playInfo.value.num += 1;
}
};
// 开启主视频任务定时器 // 开启主视频任务定时器
const StartIntervalMainVideo = () => { const StartIntervalMainVideo = () => {
intervalMainVideo = window.setInterval(() => { intervalMainVideo = window.setInterval(() => {
...@@ -334,25 +383,57 @@ export default function () { ...@@ -334,25 +383,57 @@ export default function () {
// 获取最新的要播放的互动内容 // 获取最新的要播放的互动内容
const openInterval = () => { const openInterval = () => {
interval = window.setInterval(() => { interval = window.setInterval(() => {
// 找到第一个没有播放的 try {
for (let i = 0; i < addVideoList.value.length; i++) { // 找到第一个没有播放的
let item = addVideoList.value[i]; for (let i = 0; i < addVideoList.value.length; i++) {
if (item.play_status === false && item.remove) { let item = addVideoList.value[i];
// 已有取走的任务正在执行 if (item.play_status === false && item.remove) {
// console.log('已有取走的任务正在执行'); // 已有取走的任务正在执行
break; // console.log('已有取走的任务正在执行');
} break;
if (item.play_status === false && item.remove === false) { }
if (addVideo.value == item.reply_content) { if (item.play_status === false && item.remove === false) {
// 本次播放的视频与上次一致,通知视频模块重新播放 const realVideoRow = realVideoList.value[currentMainVideoIndex.value];
store.commit('live/videoReload'); // 当前主视频播放时长
// console.log('本次视频与上次一致'); const currentMainVideoTime = realVideoRow.current;
// 判断当前时间段能否播放
const markers = liveDetail.value.markers;
if (DataType(markers, 'array')) {
for (let j = 0; j < markers.length; j++) {
const row = markers[j];
if (currentMainVideoTime >= row.start && currentMainVideoTime <= row.end) {
// 禁止播放
console.log('当前时间段无法播放', row, currentMainVideoTime);
return;
}
}
} else {
console.log('markers不是数组');
}
// 动作视频是否正在播放
const playVideo = realVideoRow.actionUrl.find((it: any) => it.play);
if (playVideo) {
console.log('当前有动作视频在播放');
return;
}
if (addVideo.value == item.reply_content) {
// 本次播放的视频与上次一致,通知视频模块重新播放
store.commit('live/videoReload');
// console.log('本次视频与上次一致');
}
addVideoList.value[i].remove = true;
addVideo.value = item.reply_content;
addVideoId.value = item.id;
break;
} }
addVideoList.value[i].remove = true;
addVideo.value = item.reply_content;
addVideoId.value = item.id;
break;
} }
} catch (e) {
console.log('轮询获取本地互动视频失败');
writeLog({
name: '轮询获取本地互动视频失败',
value: e,
});
console.log(e);
} }
}, 100); }, 100);
}; };
...@@ -364,11 +445,42 @@ export default function () { ...@@ -364,11 +445,42 @@ export default function () {
interval = null; interval = null;
}; };
// 取本地动作视频
const retrieveLocalActionVideo = () => {
if (typeof currentMainVideoIndex.value === 'number') {
// 当前主视频对象
const currentMain = realVideoList.value[currentMainVideoIndex.value];
const actionUrl = currentMain.actionUrl;
// 没有正在播放的动作视频,再找
const list = actionUrl.filter((item: any) => !item.play);
if (list.length === actionUrl.length) {
// 找到第一个没有取走的视频
const index = actionUrl.findIndex((item: any) => !item.remove && !item.status);
if (index !== -1) {
const currentAction = actionUrl[index];
// 当前正在播放的主视频的进度
const currentProgress = currentMain.current;
// 是否到了播放时间
if (currentProgress >= currentAction.play_time) {
// 可以播放
actionVideo.value = currentAction.url;
console.log(index, '动作视频下标');
currentActionIndex.value = index;
// 更新状态
currentAction.remove = true;
currentAction.play = true;
}
}
}
}
};
// 打开本地动作视频定时器 // 打开本地动作视频定时器
const openLocalActionInterval = () => { const openLocalActionInterval = () => {
intervalAction = window.setInterval(() => { intervalAction = window.setInterval(() => {
console.log(currentMainVideoIndex.value); retrieveLocalActionVideo();
}, 3000); }, 1000);
}; };
// 关闭本地动作视频定时器 // 关闭本地动作视频定时器
...@@ -451,41 +563,55 @@ export default function () { ...@@ -451,41 +563,55 @@ export default function () {
if (isDev()) { if (isDev()) {
// 创建url // 创建url
res.data = {}; res.data = {};
let url =
'http://yunyi-live.oss-cn-hangzhou.aliyuncs.com/upload/1/2023-08-21cff27bcf-ebb2-4380-b328-3069247c02c7.mp4';
let list = [ let list = [
// 动作视频
{ {
url: 'http://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/files/user/admin/e9f3d546-05f2-4dc1-a37d-d6c0ca960e43.mp4', url: 'http://yunyi-live.oss-cn-hangzhou.aliyuncs.com/upload/1/2023-08-217a507cc4-55c3-4c70-81d6-24594944e3c9.mp4',
type: 1,
},
{
url: 'http://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/files/user/admin/9604b4aa-e509-4f74-a73f-a0dc130f8f28.mp4',
type: 3, type: 3,
start: 10, play_time: 0,
}, },
{ {
url: 'http://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/files/user/admin/f2112aea-6f69-4403-acef-33d0fda7e736.mp4', url: url,
type: 1, type: 1,
}, },
]; // 动作视频
// 哪些时间段不能播放动作视频和互动视频
res.data.period = [
{ {
start: 1, url: 'http://yunyi-live.oss-cn-hangzhou.aliyuncs.com/upload/1/2023-08-217a507cc4-55c3-4c70-81d6-24594944e3c9.mp4',
end: 5, type: 3,
play_time: 10,
}, },
// 动作视频
{ {
start: 12, url: 'http://yunyi-live.oss-cn-hangzhou.aliyuncs.com/upload/1/2023-08-217a507cc4-55c3-4c70-81d6-24594944e3c9.mp4',
end: 30, type: 3,
play_time: 20,
},
{
url: url,
type: 1,
}, },
]; ];
res.data.url = list; res.data.url = list;
} }
if (DataType(res.data, 'object') && res.data.url && res.data.url.length) { if (DataType(res.data, 'object') && res.data.url && res.data.url.length) {
const mainUrl = res.data.url.filter((item: any) => item.type == mainVideoType);
realVideoList.value.push({ realVideoList.value.push({
// 主视频列表 // 主视频列表
url: res.data.url.filter((item: any) => item.type == mainVideoType), url: mainUrl,
// 过滤动作视频 // 过滤动作视频
actionUrl: res.data.url.filter((item: any) => item.type == actionVideoType), actionUrl: res.data.url.filter((item: any) => {
if (item.type == actionVideoType) {
item.remove = false;
item.play = false;
item.status = false;
return item;
}
}),
// 第一个视频是否是主视频
is_main: res.data.url[0].type === mainVideoType ? true : false,
// 合并后的地址 // 合并后的地址
result: '', result: '',
// 是否播放完毕 // 是否播放完毕
...@@ -502,10 +628,20 @@ export default function () { ...@@ -502,10 +628,20 @@ export default function () {
if (isDev()) { if (isDev()) {
if (isFirst.value) { if (isFirst.value) {
mergeCallback({ if (realVideoList.value[0].is_main) {
video: res.data.url[0].url, // 首个视频是主视频的
index: realVideoList.value.length - 1, mergeCallback({
}); video: mainUrl[0].url,
index: realVideoList.value.length - 1,
});
} else {
// 首个视频是互动视频的
mergeCallback({
video: mainUrl[0].url,
index: realVideoList.value.length - 1,
});
}
isFirst.value = false; isFirst.value = false;
} }
} else { } else {
...@@ -573,19 +709,36 @@ export default function () { ...@@ -573,19 +709,36 @@ export default function () {
}; };
// 取主视频(v2) // 取主视频(v2)
const takeMainVideoV2 = (first: boolean = true) => { const takeMainVideoV2 = async (first: boolean = true) => {
// 找到第一个播放完毕的 // 找到第一个播放完毕的
let index = mainVideoList.value.findIndex((item: any) => item.playEnd); let index = mainVideoList.value.findIndex((item: any) => item.playEnd);
if (index !== -1) { if (index !== -1) {
let videoIndex = realVideoList.value.findIndex((item: any) => !item.remove && item.result && !item.status); let videoIndex = realVideoList.value.findIndex((item: any) => !item.remove && item.result && !item.status);
if (videoIndex !== -1) { if (videoIndex !== -1) {
const realVideoRow = realVideoList.value[videoIndex];
if (!realVideoRow.is_main) {
console.log('当前要播放的主视频列表中,第一个视频是动作视频');
firstVideoIsMain.value = false;
mainVideoList.value[0].show = false;
actionVideo.value = realVideoRow.actionUrl[0].url;
realVideoRow.actionUrl[0].remove = true;
realVideoRow.actionUrl[0].play = true;
currentActionIndex.value = 0;
// 显示动作视频
showActionVideo.value = true;
} else {
firstVideoIsMain.value = true;
}
// 存入视频 // 存入视频
mainVideoList.value[index].url = realVideoList.value[videoIndex].result; mainVideoList.value[index].url = realVideoRow.result;
// 获取视频总长度
realVideoRow.total = await getDurationOfAudioFile(realVideoRow.result);
// 更新状态 // 更新状态
mainVideoList.value[index].playEnd = false; mainVideoList.value[index].playEnd = false;
mainVideoList.value[index].videoIndex = videoIndex; mainVideoList.value[index].videoIndex = videoIndex;
// 视频已被取走 // 视频已被取走
realVideoList.value[videoIndex].remove = true; realVideoRow.remove = true;
console.log(mainVideoList.value[index], '取出下一条要播放的视频', index, videoIndex); console.log(mainVideoList.value[index], '取出下一条要播放的视频', index, videoIndex);
if (first) { if (first) {
// 视频加载完毕 // 视频加载完毕
...@@ -683,9 +836,16 @@ export default function () { ...@@ -683,9 +836,16 @@ export default function () {
addVideoId, addVideoId,
liveDetail, liveDetail,
addVideo, addVideo,
actionVideo,
currentMainVideoIndex,
mainVideoList, mainVideoList,
playInfo,
firstVideoIsMain,
showActionVideo,
playEnd, playEnd,
actionPlayChange,
currentTimeChange, currentTimeChange,
mainVideoListChange, mainVideoListChange,
initActionVideo,
}; };
} }
...@@ -27,13 +27,13 @@ import Dialog from '@/components/Dialog.vue'; ...@@ -27,13 +27,13 @@ import Dialog from '@/components/Dialog.vue';
import CustomInput from '@/components/input/index.vue'; import CustomInput from '@/components/input/index.vue';
import CustomTextarea from '@/components/textarea.vue'; import CustomTextarea from '@/components/textarea.vue';
import { show_message } from '@/utils/tool'; import { show_message } from '@/utils/tool';
import { getLiveMovementList } from '@/service/Common';
import { movementTypeStart, movementTypeEnd } from '@/service/CreateLive'; import { movementTypeStart, movementTypeEnd } from '@/service/CreateLive';
import CustomRadio from '@/components/radio'; import CustomRadio from '@/components/radio';
const props = withDefaults( const props = withDefaults(
defineProps<{ defineProps<{
modelValue: boolean; modelValue: boolean;
info: any; info: any;
actionList: any[];
}>(), }>(),
{}, {},
); );
...@@ -47,7 +47,6 @@ const contentValue = ref(''); ...@@ -47,7 +47,6 @@ const contentValue = ref('');
// 当前选择的动作 // 当前选择的动作
const currentSelect = ref(''); const currentSelect = ref('');
const actionList = ref([]);
const currentRadio = ref(''); const currentRadio = ref('');
// 单选列表 // 单选列表
...@@ -62,28 +61,12 @@ const radioGroup = [ ...@@ -62,28 +61,12 @@ const radioGroup = [
}, },
]; ];
const getAction = async () => {
let list = await getLiveMovementList(true);
actionList.value = list.map((item: any) => {
return {
label: item.name,
value: item.id,
url: item.url,
};
});
};
onMounted(() => {
getAction();
});
const confirm = () => { const confirm = () => {
let movement_name = ''; let movement_name = '';
let movement_url = ''; let movement_url = '';
if (currentSelect.value) { if (currentSelect.value) {
// 找到对应的数据 // 找到对应的数据
let obj = actionList.value.find((item: any) => item.value == currentSelect.value); let obj = props.actionList.find((item: any) => item.value == currentSelect.value);
if (obj) { if (obj) {
movement_name = obj.label; movement_name = obj.label;
movement_url = obj.url; movement_url = obj.url;
......
...@@ -29,12 +29,11 @@ ...@@ -29,12 +29,11 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { watch, ref, onActivated, onMounted } from 'vue'; import { watch, ref } from 'vue';
import Select from '@/components/Select.vue'; import Select from '@/components/Select.vue';
import Dialog from '@/components/Dialog.vue'; import Dialog from '@/components/Dialog.vue';
import CustomInput from '@/components/input/index.vue'; import CustomInput from '@/components/input/index.vue';
import { show_message } from '@/utils/tool'; import { show_message } from '@/utils/tool';
import { getLiveMovementList } from '@/service/Common';
import { movementTypeStart, movementTypeEnd } from '@/service/CreateLive'; import { movementTypeStart, movementTypeEnd } from '@/service/CreateLive';
import CustomRadio from '@/components/radio'; import CustomRadio from '@/components/radio';
import MultipleUpload from '@/components/MultipleUpload'; import MultipleUpload from '@/components/MultipleUpload';
...@@ -44,6 +43,7 @@ const props = withDefaults( ...@@ -44,6 +43,7 @@ const props = withDefaults(
modelValue: boolean; modelValue: boolean;
info: any; info: any;
ossConfig: any; ossConfig: any;
actionList: any[];
}>(), }>(),
{}, {},
); );
...@@ -57,7 +57,6 @@ const audioList = ref([]); ...@@ -57,7 +57,6 @@ const audioList = ref([]);
// 当前选择的动作 // 当前选择的动作
const currentSelect = ref(''); const currentSelect = ref('');
const actionList = ref([]);
const currentRadio = ref(''); const currentRadio = ref('');
// 单选列表 // 单选列表
...@@ -72,26 +71,6 @@ const radioGroup = [ ...@@ -72,26 +71,6 @@ const radioGroup = [
}, },
]; ];
const getAction = async () => {
let list = await getLiveMovementList(true);
actionList.value = list.map((item: any) => {
return {
label: item.name,
value: item.id,
url: item.url,
};
});
};
onMounted(() => {
getAction();
});
onActivated(() => {
getAction();
});
const confirm = () => { const confirm = () => {
if (!titleValue.value) { if (!titleValue.value) {
show_message('标题必填'); show_message('标题必填');
...@@ -113,7 +92,7 @@ const confirm = () => { ...@@ -113,7 +92,7 @@ const confirm = () => {
let movement_url = ''; let movement_url = '';
if (currentSelect.value) { if (currentSelect.value) {
// 找到对应的数据 // 找到对应的数据
let obj = actionList.value.find((item: any) => item.value == currentSelect.value); let obj = props.actionList.find((item: any) => item.value == currentSelect.value);
if (obj) { if (obj) {
movement_name = obj.label; movement_name = obj.label;
movement_url = obj.url; movement_url = obj.url;
......
...@@ -185,10 +185,16 @@ ...@@ -185,10 +185,16 @@
</div> </div>
</ScriptTemplate> </ScriptTemplate>
</div> </div>
<TextScriptDialog v-model="textScriptVisible" @submit="textScriptSubmit" :info="editTextInfo"></TextScriptDialog> <TextScriptDialog
v-model="textScriptVisible"
:actionList="actionList"
@submit="textScriptSubmit"
:info="editTextInfo"
></TextScriptDialog>
<AudioScriptDialog <AudioScriptDialog
v-model="audioScriptVisible" v-model="audioScriptVisible"
:ossConfig="ossConfig" :ossConfig="ossConfig"
:actionList="actionList"
@submit="audioScriptSubmit" @submit="audioScriptSubmit"
:info="editAudioInfo" :info="editAudioInfo"
></AudioScriptDialog> ></AudioScriptDialog>
...@@ -206,7 +212,7 @@ ...@@ -206,7 +212,7 @@
</template> </template>
<script lang="tsx" setup> <script lang="tsx" setup>
import { computed, onMounted, reactive, ref, watch, toRaw } from 'vue'; import { computed, onMounted, reactive, ref, watch, toRaw, onActivated } from 'vue';
import AudioSvg from '@/assets/svg/upload/audio.svg'; import AudioSvg from '@/assets/svg/upload/audio.svg';
import Button from '@/components/Button.vue'; import Button from '@/components/Button.vue';
import CheckBox from '@/components/CheckBox.vue'; import CheckBox from '@/components/CheckBox.vue';
...@@ -225,7 +231,7 @@ import { ...@@ -225,7 +231,7 @@ import {
mergeSameAudio, mergeSameAudio,
} from '@/service/CreateLive'; } from '@/service/CreateLive';
import { useLiveInfoSubmit } from '@/hooks/useStoreCommit'; import { useLiveInfoSubmit } from '@/hooks/useStoreCommit';
import { getUploadConfig, getTonesList } from '@/service/Common'; import { getUploadConfig, getTonesList, getLiveMovementList } from '@/service/Common';
import { useStore } from 'vuex'; import { useStore } from 'vuex';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import { v4 } from 'uuid'; import { v4 } from 'uuid';
...@@ -248,6 +254,9 @@ const imgs = { ...@@ -248,6 +254,9 @@ const imgs = {
const store = useStore(); const store = useStore();
const route = useRoute(); const route = useRoute();
// 动作列表
const actionList = ref([]);
// 编辑信息 // 编辑信息
const editInfo = computed(() => store.getters['live/getEditLive']); const editInfo = computed(() => store.getters['live/getEditLive']);
...@@ -608,6 +617,18 @@ const getList = async () => { ...@@ -608,6 +617,18 @@ const getList = async () => {
updateTonesInfo(tonesValue.value, soundColorValue.value); updateTonesInfo(tonesValue.value, soundColorValue.value);
}; };
const getAction = async () => {
let list = await getLiveMovementList(true);
actionList.value = list.map((item: any) => {
return {
label: item.name,
value: item.id,
url: item.url,
};
});
};
onMounted(async () => { onMounted(async () => {
// 获取上传配置 // 获取上传配置
ossConfig.value = await getUploadConfig(); ossConfig.value = await getUploadConfig();
...@@ -620,6 +641,10 @@ onMounted(async () => { ...@@ -620,6 +641,10 @@ onMounted(async () => {
// 获取音色音调列表 // 获取音色音调列表
getList(); getList();
}); });
onActivated(() => {
getAction();
});
</script> </script>
<style lang="less"> <style lang="less">
......
...@@ -92,6 +92,7 @@ import { ...@@ -92,6 +92,7 @@ import {
filterFiled, filterFiled,
getAudioUrl, getAudioUrl,
getAudioUrlKey, getAudioUrlKey,
getDurationOfAudioFileList,
} from '@/service/CreateLive'; } from '@/service/CreateLive';
import { getLiveTaskInfo, createDrafts, getDraftsDetail, liveTts, createLiveTask } from '@/utils/api/userApi'; import { getLiveTaskInfo, createDrafts, getDraftsDetail, liveTts, createLiveTask } from '@/utils/api/userApi';
import { useRoute, onBeforeRouteLeave } from 'vue-router'; import { useRoute, onBeforeRouteLeave } from 'vue-router';
...@@ -496,7 +497,7 @@ const convertCallback = (convertInfo: any) => { ...@@ -496,7 +497,7 @@ const convertCallback = (convertInfo: any) => {
}; };
// python切割回调 // python切割回调
const splitCallback = (splitInfo: any) => { const splitCallback = async (splitInfo: any) => {
console.log(splitInfo); console.log(splitInfo);
let num = 0; let num = 0;
if ('url' in splitInfo && 'list' in splitInfo) { if ('url' in splitInfo && 'list' in splitInfo) {
...@@ -508,6 +509,14 @@ const splitCallback = (splitInfo: any) => { ...@@ -508,6 +509,14 @@ const splitCallback = (splitInfo: any) => {
let row = item[j]; let row = item[j];
if (getAudioUrl(row) == splitInfo.url) { if (getAudioUrl(row) == splitInfo.url) {
row.new_content = splitInfo.list.join('|'); row.new_content = splitInfo.list.join('|');
// 更新时长
let durationList = await getDurationOfAudioFileList(splitInfo.list);
// 四舍五入
durationList = durationList.map((it: any) => {
return Math.round(it);
});
row.duration = durationList.join('|');
console.log(row.duration, 'row.duration,切割后的时长字段');
row.py_split_status = true; row.py_split_status = true;
} }
// 统计完成数量 // 统计完成数量
...@@ -665,6 +674,7 @@ const audioScriptLiveTaskSubmit = async () => { ...@@ -665,6 +674,7 @@ const audioScriptLiveTaskSubmit = async () => {
} }
let params = filterFiled(getCreateLiveInfo(), type); let params = filterFiled(getCreateLiveInfo(), type);
console.log('创建提交的参数', params); console.log('创建提交的参数', params);
console.log('创建提交的参数json', JSON.stringify(params));
let res: any = await createLiveTask(params); let res: any = await createLiveTask(params);
if (res.code == 0) { if (res.code == 0) {
console.log('创建成功-', res.data.id); console.log('创建成功-', res.data.id);
......
...@@ -5,6 +5,7 @@ import store from '@/store'; ...@@ -5,6 +5,7 @@ import store from '@/store';
import { v4 } from 'uuid'; import { v4 } from 'uuid';
import { writeLog } from '@/utils/pyqt'; import { writeLog } from '@/utils/pyqt';
import { getDurationOfAudioFile } from '@/utils/audio'; import { getDurationOfAudioFile } from '@/utils/audio';
import CustomException from '@/utils/error';
/** /**
* 创建直播的版本 * 创建直播的版本
...@@ -57,6 +58,21 @@ export const typeSoundColor = 2; // 音色 ...@@ -57,6 +58,21 @@ export const typeSoundColor = 2; // 音色
export const movementTypeStart = 1; // 开头插入 export const movementTypeStart = 1; // 开头插入
export const movementTypeEnd = 2; // 结尾插入 export const movementTypeEnd = 2; // 结尾插入
// 获取音频文件列表的时长
export const getDurationOfAudioFileList = async (list: string[]) => {
let durationList = [];
try {
for (let i = 0; i < list.length; i++) {
const duration = await getDurationOfAudioFile(list[i]);
durationList.push(duration);
}
} catch (e) {
console.log('音频文件列表的时长失败');
console.log(e);
}
return durationList;
};
// 计算音频块列表的开始时间和结束时间 // 计算音频块列表的开始时间和结束时间
export const getAudioStartTimeAndEndTime = async (list: any[]) => { export const getAudioStartTimeAndEndTime = async (list: any[]) => {
try { try {
...@@ -332,9 +348,7 @@ export const filterFiled = (item: any, type: string = '') => { ...@@ -332,9 +348,7 @@ export const filterFiled = (item: any, type: string = '') => {
let content: any = list.map((child: any) => { let content: any = list.map((child: any) => {
return child.url; return child.url;
}); });
console.log(content, '合并前的数组content');
let str = content.join('|'); let str = content.join('|');
console.log(str, '合并后的str');
return str; return str;
}; };
// 音频 // 音频
...@@ -348,8 +362,21 @@ export const filterFiled = (item: any, type: string = '') => { ...@@ -348,8 +362,21 @@ export const filterFiled = (item: any, type: string = '') => {
uuid: v4(), uuid: v4(),
duration: 0, duration: 0,
}; };
// 创建时的时长
if (it.duration) { if (it.duration) {
params.duration = parseInt(it.duration); if (typeof it.duration === 'number') {
params.duration = Math.round(it.duration);
} else {
params.duration = it.duration;
}
}
// 编辑时的时长
if (it.children && it.children.length) {
params.duration = it.children
.map((row: any) => {
return row.duration;
})
.join('|');
} }
// 草稿类型的 // 草稿类型的
if (type == 'edit_drafts') { if (type == 'edit_drafts') {
...@@ -368,9 +395,9 @@ export const filterFiled = (item: any, type: string = '') => { ...@@ -368,9 +395,9 @@ export const filterFiled = (item: any, type: string = '') => {
params.content = it.url; params.content = it.url;
} }
} else { } else {
// 获取编辑状态下的content // 编辑
if (it.children && it.children.length > 1) { if (it.children && it.children.length > 1) {
console.log(it.children, 'it.children,编辑状态下的参数'); // 获取编辑状态下的content
// 修改content // 修改content
params.content = audioConversion(it.children); params.content = audioConversion(it.children);
params.old_content = getAudioUrl(it); params.old_content = getAudioUrl(it);
......
...@@ -32,7 +32,6 @@ export const callPyjsInWindow = ( ...@@ -32,7 +32,6 @@ export const callPyjsInWindow = (
toJson: boolean = true, toJson: boolean = true,
) => { ) => {
if (!window.pyjs) { if (!window.pyjs) {
console.log('py没有注入');
return; return;
} }
try { try {
......
This source diff could not be displayed because it is too large. You can view the blob instead.
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