Commit a3d210c3 by haojie

音频直播

parent 4e45bf47
......@@ -591,52 +591,54 @@ export default function () {
try {
let res: any = await getLiveDetail(getRouteId());
if (res.code == 0) {
if (isDev()) {
// 创建url
res.data = {};
let url =
'http://yunyi-live.oss-cn-hangzhou.aliyuncs.com/upload/1/2023-08-22c130e428-cab2-4e1e-8904-88054d84bc1b.mp4';
// if (isDev()) {
// // 创建url
// res.data = {};
// let url =
// 'http://yunyi-live.oss-cn-hangzhou.aliyuncs.com/upload/1/2023-08-21c68c10b7-611a-47b3-a3e7-8362c4a206b3.mp4';
let list = [
{
url: url,
type: 1,
},
// 'http://yunyi-live.oss-cn-hangzhou.aliyuncs.com/upload/1/2023-08-22c130e428-cab2-4e1e-8904-88054d84bc1b.mp4';
// // let url =
// // 'http://yunyi-live.oss-cn-hangzhou.aliyuncs.com/upload/1/2023-08-21c68c10b7-611a-47b3-a3e7-8362c4a206b3.mp4';
// let list = [
// {
// url: 'http://yunyi-live.oss-cn-hangzhou.aliyuncs.com/upload/2/2023-08-217a51d89c-1a9f-476b-950c-f81d0423b816.mp4',
// type: 3,
// play_time: 10,
// },
// 动作视频
// {
// url: 'http://yunyi-live.oss-cn-hangzhou.aliyuncs.com/upload/2/2023-08-2192d4a904-c78a-4a87-9728-d93bb40cad77.mp4',
// type: 3,
// play_time: 172,
// url: url,
// type: 1,
// },
// // {
// // url: 'http://yunyi-live.oss-cn-hangzhou.aliyuncs.com/upload/2/2023-08-217a51d89c-1a9f-476b-950c-f81d0423b816.mp4',
// // type: 3,
// // play_time: 10,
// // },
// // 动作视频
// // {
// // url: 'http://yunyi-live.oss-cn-hangzhou.aliyuncs.com/upload/2/2023-08-2192d4a904-c78a-4a87-9728-d93bb40cad77.mp4',
// // type: 3,
// // play_time: 172,
// // },
// // {
// // url: 'http://yunyi-live.oss-cn-hangzhou.aliyuncs.com/upload/2/2023-08-217a51d89c-1a9f-476b-950c-f81d0423b816.mp4',
// // type: 3,
// // play_time: 172,
// // },
// {
// url: 'http://yunyi-live.oss-cn-hangzhou.aliyuncs.com/upload/2/2023-08-217a51d89c-1a9f-476b-950c-f81d0423b816.mp4',
// type: 3,
// play_time: 172,
// url: url,
// type: 1,
// },
{
url: url,
type: 1,
},
// {
// url: 'http://yunyi-live.oss-cn-hangzhou.aliyuncs.com/upload/2/2023-08-217a51d89c-1a9f-476b-950c-f81d0423b816.mp4',
// type: 3,
// play_time: 0,
// },
];
res.data.url = list;
}
// // {
// // url: 'http://yunyi-live.oss-cn-hangzhou.aliyuncs.com/upload/2/2023-08-217a51d89c-1a9f-476b-950c-f81d0423b816.mp4',
// // type: 3,
// // play_time: 0,
// // },
// ];
// res.data.url = list;
// }
console.log(res.data);
if (DataType(res.data, 'object') && res.data.url && res.data.url.length) {
res.data.url.forEach((item: any) => {
item.uuid = v4();
});
const mainUrl = res.data.url.filter((item: any) => item.type == mainVideoType);
console.log(mainUrl, 'mainUrl');
const actionUrl = res.data.url.filter((item: any) => {
if (item.type == actionVideoType) {
item.remove = false;
......
......@@ -2,6 +2,7 @@
<div class="my-digtal-people">
<Grid :length="myDigtalList.list.length" :marginLeft="35">
<template v-for="item in myDigtalList.list" :key="item.id">
<template v-if="item.type == LIVE_TYPES.VIDEO_LIVE">
<CardTwo
:id="item.id"
:img="item.cover_url"
......@@ -19,7 +20,11 @@
</template>
<template v-else>
<Button class="digtal-people-start-end" theme="danger" height="40px">开播中</Button>
<Button class="digtal-people-ctrl" theme="danger" height="40px" @click="openInteractiveResponse(item)"
<Button
class="digtal-people-ctrl"
theme="danger"
height="40px"
@click="openInteractiveResponse(item)"
>控制台</Button
>
</template>
......@@ -44,6 +49,28 @@
</template>
</CardTwo>
</template>
<template v-else>
<div class="my-digtal-people-audio">
<div class="digtal-people-audio-content">
<img :src="imgs.start" alt="" @click="startLive(item)" />
<Button
class="digtal-people-ctrl"
v-if="item.is_live || isDev()"
theme="danger"
height="40px"
@click="openInteractiveResponse(item)"
>控制台</Button
>
</div>
<div class="digtal-people-audio-footer">
<ChangeName :value="item.name" @change="nameChange"></ChangeName>
<div class="create-time">
{{ item.created_at }}
</div>
</div>
</div>
</template>
</template>
</Grid>
<CustomLoading v-show="myDigtalList.loading"></CustomLoading>
<ConfirmDialog v-model="confirmVisible" title="确定删除吗?" @confirm="confirm"></ConfirmDialog>
......@@ -51,6 +78,7 @@
</template>
<script lang="ts" setup>
import ChangeName from '@/components/changeName.vue';
import OtherLoading from '@/components/Loading/FirstCircle.vue';
import Grid from '@/components/Grid.vue';
import { onMounted, reactive, ref, watch } from 'vue';
......@@ -64,6 +92,7 @@ import { onUpdateLiveTask } from '@/service/Common';
import { getLiveTask, deleteLiveTask, liveVideoDownload } from '@/utils/api/userApi';
import { isDev, show_message } from '@/utils/tool';
import { callPyjsInWindow, injectWindow, pyDownloadVideo } from '@/utils/pyqt';
import { LIVE_TYPES } from '@/service/Live';
// import { jumpToCreateLivePage } from '@/router/jump';
const props = withDefaults(
......@@ -73,6 +102,11 @@ const props = withDefaults(
{},
);
const imgs = {
start: new URL('@/assets/svg/custom/startAudio.svg', import.meta.url).href,
stop: new URL('@/assets/svg/custom/stopAudio.svg', import.meta.url).href,
};
const router = useRouter();
const myDigtalList = reactive({
......@@ -86,24 +120,36 @@ const confirmId = ref('');
// 页面跳转前的校验
const beforePageJump = (item: any) => {
if (item.status == 2) {
if (item.status == 2 && !isDev()) {
show_message('直播未准备完毕');
return;
}
let obj = myDigtalList.list.find((it: any) => it.is_live == 1);
if (obj && obj.id != item.id) {
if (obj && obj.id != item.id && !isDev()) {
show_message('已有开播任务,请先关闭直播');
return;
}
let params = {
let params: {
id: number;
status: number;
digital_image?: string;
digital_name?: string;
is_live: number;
page_path?: string;
type: number;
} = {
id: item.id,
status: item.status,
digital_image: item.cover_url,
digital_name: item.name,
is_live: item.is_live,
page_path: '',
type: item.type,
};
if (item.type == LIVE_TYPES.VIDEO_LIVE) {
params.digital_image = item.cover_url;
params.digital_name = item.name;
} else if (item.type == LIVE_TYPES.AUDIO_LIVE) {
// params = {};
}
return params;
};
......@@ -135,8 +181,10 @@ const downLoadVideo = async (item: any) => {
};
const startLive = (item: any) => {
// 视频直播页
let params = beforePageJump(item);
if (params) {
if (item.type == LIVE_TYPES.VIDEO_LIVE) {
if (isDev()) {
// 新的播放页面
router.push({
......@@ -149,6 +197,16 @@ const startLive = (item: any) => {
// 打开只有视频播放的页面
callPyjsInWindow('openLivePage', params);
}
} else if (item.type == LIVE_TYPES.AUDIO_LIVE) {
// 音频直播页
if (isDev()) {
router.push({
path: routerConfig.onlyVideoLive.path,
name: routerConfig.onlyVideoLive.name,
query: params,
});
}
}
}
};
......@@ -252,6 +310,38 @@ watch(
background: #303030;
position: relative;
min-height: 300px;
.my-digtal-people-audio {
width: 200px;
height: 411px;
border-radius: 8px;
background: #1e1e1e;
.dja();
flex-direction: column;
.digtal-people-audio-content {
flex: 1;
.dja(space-evenly);
flex-direction: column;
img {
cursor: pointer;
}
.t-button {
width: 176px;
}
}
.digtal-people-audio-footer {
width: 100%;
padding: 6px 12px;
display: flex;
flex-direction: column;
border-top: 1px solid #303030;
justify-content: space-evenly;
.create-time {
font-size: @size-13;
color: #b3b3b3;
text-align: left;
}
}
}
.custom-loading-two {
top: 150px;
transform: translate(-50%, 0);
......
<template>
<div class="custom-start-only-video-page">
<div class="start-only-video-live">
<AddVideoPlay
v-model:currentPlayMainIndex="currentPlayMainIndex"
v-model:showActionVideo="showActionVideo"
v-model:firstVideoIsMain="firstVideoIsMain"
v-model:endVideoIsMain="endVideoIsMain"
:loading="loading"
:playId="addVideoId"
:liveDetail="liveDetail"
:video2="addVideo"
:actionVideo="actionVideo"
:mainVideoList="mainVideoList"
:currentMainVideoIndex="currentMainVideoIndex"
:playInfo="playInfo"
:realVideoList="realVideoList"
@playEnd="playEnd"
@actionPlayChange="actionPlayChange"
@initActionVideo="initActionVideo"
@currentTime="currentTimeChange"
@mainVideoListChange="mainVideoListChange"
></AddVideoPlay>
</div>
</div>
</template>
<script lang="ts" setup>
import AddVideoPlay from '@/components/AddVideoPlay.vue';
import useScript from './useScript';
const {
currentPlayMainIndex,
loading,
addVideoId,
liveDetail,
addVideo,
actionVideo,
mainVideoList,
currentMainVideoIndex,
playInfo,
firstVideoIsMain,
endVideoIsMain,
showActionVideo,
realVideoList,
playEnd,
actionPlayChange,
currentTimeChange,
mainVideoListChange,
initActionVideo,
} = useScript();
</script>
<style lang="less">
@import '@/style/variables.less';
.custom-start-only-video-page {
display: flex;
width: 100% !important;
padding: 0 !important;
overflow: hidden;
& > * {
width: 100%;
background: #303030;
height: 100%;
}
.start-only-video-live {
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
}
}
</style>
<template>
<div class="custom-start-only-video-page">
<div class="start-only-video-live">
<AddVideoPlay
v-model:playMainIndex="currentPlayMainIndex"
v-model:progress="progress"
:loading="loading"
:playId="addVideoId"
:liveDetail="liveDetail"
:video2="addVideo"
:mainVideoList="mainVideoList"
@playEnd="playEnd"
@currentTime="currentTimeChange"
@mainVideoListChange="mainVideoListChange"
></AddVideoPlay>
</div>
</div>
</template>
<script lang="ts" setup>
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue';
import AddVideoPlay from '@/components/AddVideoPlay.vue';
import { getLiveDetail, closeLiveTask } from '@/utils/api/userApi';
import { useRoute, useRouter } from 'vue-router';
import { show_message, isDev, DataType, randomIntFormList } from '@/utils/tool';
......@@ -33,61 +12,76 @@ import { CONFUSE_STATUS } from '@/service/Live';
import { processTextCallback } from '@/hooks/useScript';
import { scriptTypeText } from '@/service/CreateLive';
import { writeLog } from '@/utils/pyqt';
const { currentConfuseId, confuseList, stopConfuse, openConfuseInterval } = useConfuse();
const { openInterval: confuseInterval } = processTextCallback();
import { getDurationOfAudioFile } from '@/utils/audio';
const store = useStore();
const route = useRoute();
const router = useRouter();
const routeQuery = route.query;
export default function () {
const { currentConfuseId, confuseList, stopConfuse, openConfuseInterval } = useConfuse();
const { openInterval: confuseInterval } = processTextCallback();
const mainVideoType = 1;
const actionVideoType = 3;
const userInfo = computed(() => store.getters['user/userInfo']);
const store = useStore();
const route = useRoute();
const router = useRouter();
const routeQuery = route.query;
// 视频加载loading
const loading = ref(true);
const userInfo = computed(() => store.getters['user/userInfo']);
const progress = ref(0);
// 视频加载loading
const loading = ref(true);
// 剩余多少时长时开始洗稿并获取下一个视频
const esidueTime = 60 * 10;
// 剩余多少时长时开始洗稿并获取下一个视频
const esidueTime = 60 * 10;
const imgs = {
const imgs = {
mp4: new URL('../../assets/img/1.mp4', import.meta.url).href,
};
// 本次测试用的变量
const requestNum = ref(0);
const isFirst = ref(true);
// 定时检测python的方法是否注入成功
let interval = null;
// 定时获取直播互动内容
let intervalLive = null;
// 定时获取后台主视频任务
let intervalMainVideo = null;
// 定时获取下一个要播放的主视频
let intervalLocalMainVideo = null;
// 主视频列表
const realVideoList = ref([]);
// 互动视频
const addVideo = ref(imgs.mp4);
// 互动视频列表
const addVideoList = ref([]);
// 互动视频当前播放id
const addVideoId = ref('');
// 直播详情
const liveDetail = ref({});
};
// 当前正在播放的主视频下标
const currentPlayMainIndex = ref(null);
// 本次测试用的变量
const requestNum = ref(0);
const isFirst = ref(true);
// 获取已经存到本地的互动列表,播放
let interval = null;
// 定时获取后台直播互动内容
let intervalLive = null;
// 定时获取本地的动作视频
let intervalAction = null;
// 定时获取后台主视频任务
let intervalMainVideo = null;
// 定时获取下一个要播放的主视频
let intervalLocalMainVideo = null;
// 主视频列表
const realVideoList = ref([]);
// 当前播放的视频中,第一个视频是否为主视频
const firstVideoIsMain = ref(true);
// 当前播放的视频中,最后一个视频是否为主视频
const endVideoIsMain = ref(true);
// 互动视频
const addVideo = ref(imgs.mp4);
// 动作视频
const actionVideo = ref(imgs.mp4);
const showActionVideo = ref(false);
// 互动视频列表
const addVideoList = ref([]);
// 互动视频当前播放id
const addVideoId = ref('');
// 直播详情
const liveDetail = ref<any>({});
// 通知视频播放
const playInfo = ref({
mainStart: true,
num: 0,
});
// 主视频列表
const mainVideoList = ref([
// 主视频列表
const mainVideoList = ref([
{
name: 'mainVideo1',
// 播放链接
......@@ -111,10 +105,30 @@ const mainVideoList = ref([
total: 0,
videoIndex: null,
},
]);
]);
// 主视频列表状态更新
const mainVideoListChange = (params: any) => {
// 获取当前页面的id
const getRouteId = () => {
if (typeof route.query.id === 'string' || typeof route.query.id === 'number') {
return route.query.id;
}
return '';
};
// 当前正在播放的主视频标签下标
const currentPlayMainIndex = ref(null);
// 当前正在播放的主视频列表下标
const currentMainVideoIndex = computed(() => {
if (typeof currentPlayMainIndex.value === 'number') {
return mainVideoList.value[currentPlayMainIndex.value].videoIndex;
}
return null;
});
// 当前播放的动作视频的下标
const currentActionIndex = ref();
// 主视频列表状态更新
const mainVideoListChange = (params: any) => {
if (typeof params.index === 'number' && !params.type) {
mainVideoList.value[params.index][params.key] = params.value;
if (params.key == 'show') {
......@@ -137,9 +151,9 @@ const mainVideoListChange = (params: any) => {
console.log(realVideoList.value[videoIndex], '更新主视频列表');
}
}
};
};
const submitAudioTask = async (list: any[]) => {
const submitAudioTask = async (list: any[]) => {
for (let i = 0; i < list.length; i++) {
let params = {
// 音色
......@@ -157,10 +171,10 @@ const submitAudioTask = async (list: any[]) => {
console.log('等待音频生成完成');
// 开始轮询
confuseInterval(true, '', false, currentConfuseId.value, regenerate, list.length);
};
};
// 洗稿列表变化
watch(
// 洗稿列表变化
watch(
() => confuseList.value,
(v) => {
if (v.length) {
......@@ -169,10 +183,10 @@ watch(
submitAudioTask(v);
}
},
);
);
// 提交洗稿
const submitConfuse = async () => {
// 提交洗稿
const submitConfuse = async () => {
try {
// currentConfuseId.value = v4();
// let content = '';
......@@ -195,20 +209,23 @@ const submitConfuse = async () => {
} catch (e) {
console.log(e);
}
};
};
// 找一个已经播放完毕的视频,加入video标签中
const findOneVideoInit = () => {
// 找一个已经播放完毕的视频,加入video标签中
const findOneVideoInit = () => {
// 是否需要执行
let status = false;
let videoTagIndex = mainVideoList.value.findIndex((item: any, index: number) => index !== currentPlayMainIndex.value);
let videoTagIndex = mainVideoList.value.findIndex(
(item: any, index: number) => index !== currentPlayMainIndex.value,
);
if (videoTagIndex !== -1) {
let hideVideo = mainVideoList.value[videoTagIndex];
let hideVideo: any = mainVideoList.value[videoTagIndex];
// 隐藏的视频已经播放结束 且 视频列表中不存在有url,没取走的视频
let notRemove = realVideoList.value.find((item: any) => item.result && !item.remove);
if (!hideVideo.play && hideVideo.playEnd && !notRemove) {
console.log('需要重新入队');
status = true;
hideVideo.restart = true;
}
// start
......@@ -219,17 +236,21 @@ const findOneVideoInit = () => {
const changeVideo = (url: string, index: number | boolean = false) => {
hideVideo.play = false;
hideVideo.playEnd = false;
if (hideVideo.url !== url) {
hideVideo.url = url;
}
if (index !== false) {
hideVideo.videoIndex = index;
}
};
// 找到所有已经播放完毕的主视频
let playEndVideos = realVideoList.value.filter((row: any, index: number) => {
if (row.remove && item.result && item.status) {
return index;
let playEndVideos = [];
realVideoList.value.forEach((row: any, index: number) => {
if (row.remove && row.result && row.status && typeof index === 'number') {
playEndVideos.push(index);
}
});
console.log(playEndVideos, '随机下标列表');
if (playEndVideos.length) {
if (playEndVideos.length === 1) {
console.log('只有一条视频播放完毕,重新播放该视频');
......@@ -238,7 +259,22 @@ const findOneVideoInit = () => {
// 多条视频
// 随机下标
let num = randomIntFormList(playEndVideos);
// 防止出错
try {
if (typeof num !== 'number' || !realVideoList.value[num]) {
console.log('num格式错误,初始化第1个视频', num);
num = 0;
}
} catch (e) {
num = 0;
console.log(e, '初始化旧视频出错了,将num改为0');
writeLog({
name: '初始化旧视频出错了,将num改为0',
value: e,
});
}
console.log(`初始化第${num}个视频`);
console.log(realVideoList.value[num]);
// 链接是否一致
if (realVideoList.value[num].result === item.url) {
// 循环播放
......@@ -257,18 +293,23 @@ const findOneVideoInit = () => {
}
}
}
};
};
// 当前播放进度变化
const currentTimeChange = (index: number, value: number) => {
// 当前播放进度变化
const currentTimeChange = (index: number, value: number) => {
try {
// console.log(value, '当前主视频进度');
let row = mainVideoList.value[index];
// 剩余多少没有播放
let currentEsidueTime = row.total - value;
let currentVideoRow = realVideoList.value[row.videoIndex];
// 更新当前进度
currentVideoRow.current = value;
// 低于设置的值、没有开始洗稿、有文本内容 、必须是文本脚本
if (
currentEsidueTime < esidueTime &&
currentVideoRow.confuse === CONFUSE_STATUS.CONFUSE_STATUS_WAIT &&
liveDetail.value.type_content &&
liveDetail.value.type_content.length &&
typeof liveDetail.value.phonetic_timbres_id === 'number' &&
typeof liveDetail.value.tone_id === 'number' &&
......@@ -287,10 +328,13 @@ const currentTimeChange = (index: number, value: number) => {
if (currentEsidueTime < 20 && typeof currentPlayMainIndex.value === 'number') {
findOneVideoInit();
}
};
} catch (e) {
console.log(e);
}
};
// 互动视频播放结束
const playEnd = (id: any) => {
// 互动视频播放结束
const playEnd = (id: any) => {
if (id) {
//
let index = addVideoList.value.findIndex((item: any) => item.id == id);
......@@ -301,45 +345,71 @@ const playEnd = (id: any) => {
addVideoList.value.splice(index, 1);
}
}
};
};
// 开启主视频任务定时器
const StartIntervalMainVideo = () => {
// 动作视频更新
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.mainStart) {
// 是主视频--通知视频直接播放
playInfo.value.mainStart = true;
playInfo.value.num += 1;
}
};
// 开启主视频任务定时器
const StartIntervalMainVideo = () => {
intervalMainVideo = window.setInterval(() => {
getDetail();
}, 10000);
};
};
// 关闭主视频任务定时器
const closeIntervalMainVideo = () => {
// 关闭主视频任务定时器
const closeIntervalMainVideo = () => {
window.clearInterval(intervalMainVideo);
clearInterval(intervalMainVideo);
intervalMainVideo = null;
};
const stopInterval = () => {
window.clearInterval(interval);
clearInterval(interval);
interval = null;
};
};
// 开启本地主视频定时器
const openLocalMainVideoInterval = () => {
// 开启本地主视频定时器
const openLocalMainVideoInterval = () => {
intervalLocalMainVideo = window.setInterval(() => {
takeMainVideoV2(false);
}, 5000);
};
};
// 关闭本地主视频定时器
const closeLocalMainVideoInterval = () => {
// 关闭本地主视频定时器
const closeLocalMainVideoInterval = () => {
window.clearInterval(intervalLocalMainVideo);
clearInterval(intervalLocalMainVideo);
intervalLocalMainVideo = null;
};
};
// 获取最新的要播放的互动内容
const openInterval = () => {
// 获取最新的要播放的互动内容
const openInterval = () => {
interval = window.setInterval(() => {
try {
// 找到第一个没有播放的
for (let i = 0; i < addVideoList.value.length; i++) {
let item = addVideoList.value[i];
......@@ -349,6 +419,29 @@ const openInterval = () => {
break;
}
if (item.play_status === false && item.remove === false) {
const realVideoRow = realVideoList.value[currentMainVideoIndex.value];
// 当前主视频播放时长
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');
......@@ -360,11 +453,76 @@ const openInterval = () => {
break;
}
}
} catch (e) {
console.log('轮询获取本地互动视频失败');
writeLog({
name: '轮询获取本地互动视频失败',
value: e,
});
console.log(e);
}
}, 100);
};
};
// 关闭本地互动定时器
const stopInterval = () => {
window.clearInterval(interval);
clearInterval(interval);
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;
// 最后一个视频是动作视频,当前找到的url和最后一个动作的链接一致的
if (!currentMain.mainEnd.status && currentAction.uuid == currentMain.mainEnd.uuid) {
// console.log('最后一个视频是动作视频,这里不处理');
return;
}
// 是否到了播放时间
if (currentProgress >= currentAction.play_time) {
// 可以播放
actionVideo.value = currentAction.url;
console.log(index, '动作视频下标');
currentActionIndex.value = index;
// 更新状态
currentAction.remove = true;
currentAction.play = true;
}
}
}
}
};
// 打开本地动作视频定时器
const openLocalActionInterval = () => {
intervalAction = window.setInterval(() => {
retrieveLocalActionVideo();
}, 1000);
};
// 关闭本地动作视频定时器
const closeLocalActionInterval = () => {
window.clearInterval(intervalAction);
clearInterval(intervalAction);
intervalAction = null;
};
// 获取直播互动内容
const getLive = async () => {
// 获取直播互动内容
const getLive = async () => {
try {
let res: any = await getliveTaskReply(route.query.id);
if (res.code == 0 && res.data && res.data.length) {
......@@ -384,9 +542,9 @@ const getLive = async () => {
});
console.log(e);
}
};
// 重新生成直播
const regenerate = async (list: any[]) => {
};
// 重新生成直播
const regenerate = async (list: any[]) => {
try {
let params = {
digital_man_id: liveDetail.value.digital_man_id,
......@@ -394,8 +552,8 @@ const regenerate = async (list: any[]) => {
phonetic_timbres_id: liveDetail.value.phonetic_timbres_id,
tone_id: liveDetail.value.tone_id,
type: liveDetail.value.type,
type_content: list,
};
params.type_content = list;
let res: any = await liveTaskRegenerate(liveDetail.value.id, params);
if (res.code == 0) {
//
......@@ -408,76 +566,112 @@ const regenerate = async (list: any[]) => {
});
console.log(e);
}
};
};
// 开启
const startLiveInterval = () => {
// 开启
const startLiveInterval = () => {
closeLiveInterval();
intervalLive = window.setInterval(() => {
getLive();
}, 3000);
};
};
// 关闭
const closeLiveInterval = () => {
// 关闭
const closeLiveInterval = () => {
window.clearInterval(intervalLive);
clearInterval(intervalLive);
intervalLive = null;
};
};
const getDetail = async (type: string = '') => {
if (!routeQuery.id) {
const getDetail = async (type: string = '') => {
if (!getRouteId()) {
show_message('禁止访问');
return;
}
try {
let res: any = await getLiveDetail(routeQuery.id);
let res: any = await getLiveDetail(getRouteId());
if (res.code == 0) {
if (isDev()) {
// 创建url
res.data = {};
let list = [
{
url: 'http://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/files/user/admin/e9f3d546-05f2-4dc1-a37d-d6c0ca960e43.mp4',
type: 1,
},
{
url: 'http://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/files/user/admin/9604b4aa-e509-4f74-a73f-a0dc130f8f28.mp4',
type: 3,
// 是否需要播放
},
{
url: 'http://yunyi-tiktok.oss-cn-shenzhen.aliyuncs.com/files/user/admin/f2112aea-6f69-4403-acef-33d0fda7e736.mp4',
type: 1,
},
];
// 哪些时间段不能播放动作视频和互动视频
res.data.period = [
{
start: 1,
end: 5,
},
{
start: 12,
end: 30,
},
];
res.data.url = list;
}
// if (isDev()) {
// // 创建url
// res.data = {};
// let url =
// 'http://yunyi-live.oss-cn-hangzhou.aliyuncs.com/upload/1/2023-08-22c130e428-cab2-4e1e-8904-88054d84bc1b.mp4';
// // let url =
// // 'http://yunyi-live.oss-cn-hangzhou.aliyuncs.com/upload/1/2023-08-21c68c10b7-611a-47b3-a3e7-8362c4a206b3.mp4';
// let list = [
// {
// url: url,
// type: 1,
// },
// // {
// // url: 'http://yunyi-live.oss-cn-hangzhou.aliyuncs.com/upload/2/2023-08-217a51d89c-1a9f-476b-950c-f81d0423b816.mp4',
// // type: 3,
// // play_time: 10,
// // },
// // 动作视频
// // {
// // url: 'http://yunyi-live.oss-cn-hangzhou.aliyuncs.com/upload/2/2023-08-2192d4a904-c78a-4a87-9728-d93bb40cad77.mp4',
// // type: 3,
// // play_time: 172,
// // },
// // {
// // url: 'http://yunyi-live.oss-cn-hangzhou.aliyuncs.com/upload/2/2023-08-217a51d89c-1a9f-476b-950c-f81d0423b816.mp4',
// // type: 3,
// // play_time: 172,
// // },
// {
// url: url,
// type: 1,
// },
// // {
// // url: 'http://yunyi-live.oss-cn-hangzhou.aliyuncs.com/upload/2/2023-08-217a51d89c-1a9f-476b-950c-f81d0423b816.mp4',
// // type: 3,
// // play_time: 0,
// // },
// ];
// res.data.url = list;
// }
console.log(res.data);
if (DataType(res.data, 'object') && res.data.url && res.data.url.length) {
// 初始化视频列表的状态
res.data.url.forEach((item: any) => {
// 是否播放完毕
item.status = false;
// 是否取走
item.uuid = v4();
});
const mainUrl = res.data.url.filter((item: any) => item.type == mainVideoType);
console.log(mainUrl, 'mainUrl');
const actionUrl = res.data.url.filter((item: any) => {
if (item.type == actionVideoType) {
item.remove = false;
// 是否正在播放
item.play = false;
item.status = false;
return item;
}
});
// 取出所有 type==1 的主视频,计算总时长
// 最后一个视频是否是动作视频
const lastRow = res.data.url[res.data.url.length - 1];
let mainEnd = lastRow.type === mainVideoType ? true : false;
let url = '';
let uuid = '';
if (mainEnd) {
url = lastRow.url;
} else {
// 最后一个不是主视频,才有uuid
uuid = lastRow.uuid;
}
realVideoList.value.push({
url: res.data.url,
// 主视频列表
url: mainUrl,
// 过滤动作视频
actionUrl: actionUrl,
// 第一个视频是否是主视频
mainStart: res.data.url[0].type === mainVideoType ? true : false,
// 最后一个视频是否是主视频
mainEnd: {
status: mainEnd,
url: url,
// 生成一个uid
uuid: uuid,
},
// 合并后的地址
result: '',
// 是否播放完毕
......@@ -494,11 +688,20 @@ const getDetail = async (type: string = '') => {
if (isDev()) {
if (isFirst.value) {
if (realVideoList.value[0].mainStart) {
// 首个视频是主视频的
mergeCallback({
video: res.data.url[0].url,
video: mainUrl[0].url,
index: realVideoList.value.length - 1,
childIndex: 0,
});
} else {
// 首个视频是互动视频的
mergeCallback({
video: mainUrl[0].url,
index: realVideoList.value.length - 1,
});
}
isFirst.value = false;
}
} else {
......@@ -530,10 +733,10 @@ const getDetail = async (type: string = '') => {
});
console.log(e);
}
};
};
// 视频列表提交到py
const submitVideo = () => {
// 视频列表提交到py
const submitVideo = () => {
try {
if (window.pyjs) {
if (window.pyjs.run) {
......@@ -563,22 +766,45 @@ const submitVideo = () => {
value: e,
});
}
};
};
// 取主视频(v2)
const takeMainVideoV2 = (first: boolean = true) => {
// 取主视频(v2)
const takeMainVideoV2 = async (first: boolean = true) => {
// 找到第一个播放完毕的
let index = mainVideoList.value.findIndex((item: any) => item.playEnd);
if (index !== -1) {
let videoIndex = realVideoList.value.findIndex((item: any) => !item.remove && item.result && !item.status);
if (videoIndex !== -1) {
const realVideoRow = realVideoList.value[videoIndex];
if (!realVideoRow.mainStart) {
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;
}
// 最后一个视频是否主视频
if (!realVideoRow.mainEnd.status) {
endVideoIsMain.value = false;
} else {
endVideoIsMain.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].videoIndex = videoIndex;
// 视频已被取走
realVideoList.value[videoIndex].remove = true;
realVideoRow.remove = true;
console.log(mainVideoList.value[index], '取出下一条要播放的视频', index, videoIndex);
if (first) {
// 视频加载完毕
......@@ -586,10 +812,10 @@ const takeMainVideoV2 = (first: boolean = true) => {
}
}
}
};
};
// python 回调
const mergeCallback = (params: any) => {
// python 回调
const mergeCallback = (params: any) => {
try {
// console.log('python回调',params);
let index = params.index;
......@@ -609,6 +835,10 @@ const mergeCallback = (params: any) => {
StartIntervalMainVideo();
}
} else {
writeLog({
name: 'mergeCallback 回调格式错误',
value: params,
});
console.log('回调格式错误');
console.log(params);
}
......@@ -619,21 +849,21 @@ const mergeCallback = (params: any) => {
});
console.log(e);
}
};
};
const getTone = async () => {
const getTone = async () => {
try {
let res = await getLiveTaskInfo(route.query.id);
let res: any = await getLiveTaskInfo(getRouteId());
if (res.code == 0) {
liveDetail.value = res.data;
}
} catch (e) {
console.log(e);
}
};
};
//
const closeLive = async () => {
//
const closeLive = async () => {
try {
let res: any = await closeLiveTask(route.query.id);
if (res.code == 0) {
......@@ -643,9 +873,9 @@ const closeLive = async () => {
} catch (e) {
console.log(e);
}
};
};
onMounted(async () => {
onMounted(async () => {
// 将通知方法注入window
injectWindow('mergeCallback', mergeCallback);
injectWindow('closeLive', closeLive);
......@@ -660,32 +890,34 @@ onMounted(async () => {
await getDetail('init');
// 获取音调和音色
getTone();
});
onBeforeUnmount(() => {
// 开启动作视频轮询
openLocalActionInterval();
});
onBeforeUnmount(() => {
closeLiveInterval();
stopInterval();
closeIntervalMainVideo();
closeLocalMainVideoInterval();
});
</script>
<style lang="less">
@import '@/style/variables.less';
.custom-start-only-video-page {
display: flex;
width: 100% !important;
padding: 0 !important;
overflow: hidden;
& > * {
width: 100%;
background: #303030;
height: 100%;
}
.start-only-video-live {
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
}
closeLocalActionInterval();
});
return {
currentPlayMainIndex,
loading,
addVideoId,
liveDetail,
addVideo,
actionVideo,
currentMainVideoIndex,
mainVideoList,
playInfo,
firstVideoIsMain,
endVideoIsMain,
showActionVideo,
realVideoList,
playEnd,
actionPlayChange,
currentTimeChange,
mainVideoListChange,
initActionVideo,
};
}
</style>
......@@ -20,3 +20,11 @@ export const CONFUSE_STATUS = {
CONFUSE_STATUS_PROGRESS: 2, // 进行中
CONFUSE_STATUS_SUCCESS: 3, // 已完成
};
/**
* 直播间类型
*/
export const LIVE_TYPES = {
VIDEO_LIVE: 1, // 视频直播
AUDIO_LIVE: 2, // 音频直播
};
......@@ -8,7 +8,8 @@ const error_messaage = '请求错误';
const getBaseUrl = async () => {
if (isDev()) {
return 'http://rpc.chensav.top';
// return 'http://rpc.chensav.top';
// return 'http://156.247.11.21:93';
return '';
}
// 默认线上地址
......
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