Commit 0e8b3413 by haojie

音频直播,未完成

parent c9ec9cdc
......@@ -74,6 +74,13 @@ export const getRoutes = () => {
component: () => import('@/pages/OnlyVideoLive/indexV2.vue'),
meta: { title: 'snowhome', header: false, navbar: false },
},
// 只有音频的页面
{
path: routerConfig.onlyAudioLive.path,
name: routerConfig.onlyAudioLive.name,
component: () => import('@/pages/onlyAudioLive/index.vue'),
meta: { title: 'snowhome', header: false, navbar: false },
},
// 只有人工回复的页面
{
path: routerConfig.interactiveResponse.path,
......
......@@ -201,10 +201,12 @@ const startLive = (item: any) => {
// 音频直播页
if (isDev()) {
router.push({
path: routerConfig.onlyVideoLive.path,
name: routerConfig.onlyVideoLive.name,
path: routerConfig.onlyAudioLive.path,
name: routerConfig.onlyAudioLive.name,
query: params,
});
} else {
callPyjsInWindow('openAudioLivePage', params);
}
}
}
......
<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 class="only-audio-page">
<template v-for="(item, index) in mainVideoList" :key="item.name">
<audio
:src="item.url"
@canplay="onCanplay(index)"
:ref="(ref:HTMLAudioElement) => (item.ref = ref)"
@ended="onPlayEnd(index)"
></audio>
</template>
</div>
</template>
<script lang="ts" setup>
import AddVideoPlay from '@/components/AddVideoPlay.vue';
import { ref } from 'vue';
import useScript from './useScript';
const {
currentPlayMainIndex,
loading,
addVideoId,
liveDetail,
addVideo,
......@@ -47,26 +32,26 @@ const {
currentTimeChange,
mainVideoListChange,
initActionVideo,
audioCanplay,
onPlayEnd,
} = useScript();
const isFirst = ref(true);
const onCanplay = async (index: number) => {
if (isFirst.value) {
audioCanplay();
isFirst.value = false;
}
};
</script>
<style lang="less">
@import '@/style/variables.less';
.custom-start-only-video-page {
.only-audio-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>
......@@ -27,9 +27,6 @@ export default function () {
const userInfo = computed(() => store.getters['user/userInfo']);
// 视频加载loading
const loading = ref(true);
// 剩余多少时长时开始洗稿并获取下一个视频
const esidueTime = 60 * 10;
......@@ -37,8 +34,6 @@ export default function () {
mp4: new URL('../../assets/img/1.mp4', import.meta.url).href,
};
// 本次测试用的变量
const requestNum = ref(0);
const isFirst = ref(true);
// 获取已经存到本地的互动列表,播放
......@@ -54,6 +49,9 @@ export default function () {
// 定时获取下一个要播放的主视频
let intervalLocalMainVideo = null;
// 当前播放进度定时器
let currentTimeInterval = null;
// 主视频列表
const realVideoList = ref([]);
......@@ -81,7 +79,17 @@ export default function () {
});
// 主视频列表
const mainVideoList = ref([
const mainVideoList = ref<
{
name: string;
url: string;
playEnd: boolean;
play: boolean;
total: number;
videoIndex: number | null;
ref: HTMLAudioElement;
}[]
>([
{
name: 'mainVideo1',
// 播放链接
......@@ -90,9 +98,9 @@ export default function () {
playEnd: true,
// 是否正在播放
play: false,
show: true,
total: 0,
videoIndex: null,
ref: null,
},
{
name: 'mainVideo2',
......@@ -101,12 +109,15 @@ export default function () {
// 当前视频是否播放完毕
playEnd: true,
play: false,
show: false,
total: 0,
videoIndex: null,
ref: null,
},
]);
// 当前正在播放的主视频标签下标
const currentPlayMainIndex = ref(null);
// 获取当前页面的id
const getRouteId = () => {
if (typeof route.query.id === 'string' || typeof route.query.id === 'number') {
......@@ -115,8 +126,6 @@ export default function () {
return '';
};
// 当前正在播放的主视频标签下标
const currentPlayMainIndex = ref(null);
// 当前正在播放的主视频列表下标
const currentMainVideoIndex = computed(() => {
if (typeof currentPlayMainIndex.value === 'number') {
......@@ -131,15 +140,6 @@ export default function () {
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') {
......@@ -185,6 +185,47 @@ export default function () {
},
);
// 指定下标的audio开始播放
const audioStartPlay = (index: number, videoIndex: number | null = null) => {
let row = mainVideoList.value[index];
if (row.ref) {
row.play = true;
row.playEnd = false;
if (typeof videoIndex === 'number') {
row.videoIndex = videoIndex;
}
row.ref.play();
// 修改当前正在播放的下标
currentPlayMainIndex.value = index;
}
// 其他行改为暂停状态
for (let i = 0; i < mainVideoList.value.length; i++) {
let item = mainVideoList.value[i];
if (i != index) {
item.play = false;
item.playEnd = true;
item.ref.pause();
}
}
};
// 当前音频播放完毕
const onPlayEnd = (index: number) => {
console.log(index, '-播放完毕');
mainVideoList.value[index].play = false;
mainVideoList.value[index].playEnd = true;
mainVideoList.value[index].ref.pause();
// 找到下一个
let nextIndex = mainVideoList.value.findIndex((item: any, num: number) => index != num && !item.play);
if (nextIndex !== -1) {
audioStartPlay(nextIndex);
console.log(nextIndex, '-开始播放');
} else {
console.log('未找到下一个音频');
}
};
// 提交洗稿
const submitConfuse = async () => {
try {
......@@ -379,7 +420,7 @@ export default function () {
};
// 开启主视频任务定时器
const StartIntervalMainVideo = () => {
const startIntervalMainVideo = () => {
intervalMainVideo = window.setInterval(() => {
getDetail();
}, 10000);
......@@ -396,7 +437,7 @@ export default function () {
const openLocalMainVideoInterval = () => {
intervalLocalMainVideo = window.setInterval(() => {
takeMainVideoV2(false);
}, 5000);
}, 1000);
};
// 关闭本地主视频定时器
......@@ -406,6 +447,21 @@ export default function () {
intervalLocalMainVideo = null;
};
// 开启当前播放进度定时器
const openCurrentTimeInterval = () => {
window.setInterval(() => {
// console.log(currentPlayMainIndex.value);
// console.log(currentMainVideoIndex.value);
}, 1000);
};
// 关闭当前播放进度定时器
const closeCurrentTimeInterval = () => {
window.clearInterval(currentTimeInterval);
clearInterval(currentTimeInterval);
currentTimeInterval = null;
};
// 获取最新的要播放的互动内容
const openInterval = () => {
interval = window.setInterval(() => {
......@@ -591,54 +647,59 @@ 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';
// // 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 (isDev()) {
// 创建url
res.data = {};
let url =
'http://yunyi-live.oss-cn-hangzhou.aliyuncs.com/upload/1/2023-09-14528c29fe-2ef7-4e12-93d2-915b07792c6b.mp3';
// 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;
}
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');
// 计算每个音频的时长和,当前音频列表的总时长
let total = 0;
for (let i = 0; i < mainUrl.length; i++) {
let row = mainUrl[i];
row.total = await getDurationOfAudioFile(row.url);
total += row.total;
}
const actionUrl = res.data.url.filter((item: any) => {
if (item.type == actionVideoType) {
item.remove = false;
......@@ -659,9 +720,9 @@ export default function () {
uuid = lastRow.uuid;
}
realVideoList.value.push({
// 主频列表
// 主频列表
url: mainUrl,
// 过滤动作
// 过滤动作
actionUrl: actionUrl,
// 第一个视频是否是主视频
mainStart: res.data.url[0].type === mainVideoType ? true : false,
......@@ -684,28 +745,15 @@ export default function () {
submit: false,
// 下一个视频的状态(洗稿状态)
confuse: CONFUSE_STATUS.CONFUSE_STATUS_WAIT,
// 主音频总时长
total: total,
});
if (isDev()) {
if (isFirst.value) {
if (realVideoList.value[0].mainStart) {
// 首个视频是主视频的
mergeCallback({
video: mainUrl[0].url,
index: realVideoList.value.length - 1,
});
} else {
// 首个视频是互动视频的
mergeCallback({
video: mainUrl[0].url,
index: realVideoList.value.length - 1,
});
}
isFirst.value = false;
}
} else {
// 通知python合并
if (isFirst.value && isDev()) {
// 通知python返回音频
submitVideo();
isFirst.value = false;
} else if (!isDev()) {
submitVideo();
}
......@@ -714,8 +762,8 @@ export default function () {
callPyjsInWindow('reloadLiveTaskList');
// 开播成功
router.replace({
path: routerConfig.onlyVideoLive.path,
name: routerConfig.onlyVideoLive.name,
path: routerConfig.onlyAudioLive.path,
name: routerConfig.onlyAudioLive.name,
query: {
...route.query,
is_live: '1',
......@@ -738,26 +786,33 @@ export default function () {
// 视频列表提交到py
const submitVideo = () => {
try {
if (window.pyjs) {
if (window.pyjs.run) {
// 未取走且未提交过的视频
let index = realVideoList.value.findIndex((item: any) => !item.remove && !item.submit);
if (index !== -1) {
realVideoList.value[index].submit = true;
let list = realVideoList.value[index].url.map((item: any) => {
return item.url;
});
window.pyjs.run(list, routeQuery.id, route.query.window_index, index);
console.log(`本次提交-${index}`);
console.log(realVideoList.value);
} else {
console.log('没有要提交的任务');
}
// 有python方法的
if (window.pyjs && window.pyjs.run) {
// 未取走且未提交过的视频
let index = realVideoList.value.findIndex((item: any) => !item.remove && !item.submit);
if (index !== -1) {
realVideoList.value[index].submit = true;
let list = realVideoList.value[index].url.map((item: any) => {
return item.url;
});
window.pyjs.run(list, routeQuery.id, route.query.window_index, index);
console.log(`本次提交-${index}`);
} else {
console.log('没有run方法');
console.log('没有要提交的任务');
}
} else {
show_message('empty-1 py');
// 测试
// 没有python,直接播放
mergeCallback({
list: [
{
url: 'http://yunyi-live.oss-cn-hangzhou.aliyuncs.com/upload/1/2023-09-14528c29fe-2ef7-4e12-93d2-915b07792c6b.mp3',
result_url:
'http://yunyi-live.oss-cn-hangzhou.aliyuncs.com/upload/1/2023-09-14528c29fe-2ef7-4e12-93d2-915b07792c6b.mp3',
},
],
index: 0,
});
}
} catch (e) {
console.log(e);
......@@ -768,18 +823,22 @@ export default function () {
}
};
// 取主视频(v2)
// 音频首次可以播放
const audioCanplay = () => {
audioStartPlay(0);
};
// 取主音频
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);
let videoIndex = realVideoList.value.findIndex((item: any) => !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;
......@@ -796,55 +855,70 @@ export default function () {
endVideoIsMain.value = true;
}
// 存入视频
mainVideoList.value[index].url = realVideoRow.result;
// 获取视频总长度
realVideoRow.total = await getDurationOfAudioFile(realVideoRow.result);
// 更新状态
mainVideoList.value[index].playEnd = false;
mainVideoList.value[index].videoIndex = videoIndex;
// 视频已被取走
realVideoRow.remove = true;
console.log(mainVideoList.value[index], '取出下一条要播放的视频', index, videoIndex);
if (first) {
// 视频加载完毕
loading.value = false;
// 从当前行中找到第一个没有播放的音频
const audioUrlIndex = realVideoRow.url.findIndex((item: any) => !item.remove);
if (audioUrlIndex !== -1) {
let urlRow = realVideoRow.url[audioUrlIndex];
urlRow.remove = true;
// 当前行的url是否全部被取走
const newList = realVideoRow.url.filter((item: any) => item.remove);
if (newList.length === realVideoRow.url.length) {
// 当前行状态true
realVideoRow.status = true;
}
// 存入音频
mainVideoList.value[index].url = urlRow.url;
// 更新状态
mainVideoList.value[index].playEnd = false;
mainVideoList.value[index].videoIndex = videoIndex;
console.log(mainVideoList.value[index], '取出下一条要播放的视频', index, `${videoIndex}-${audioUrlIndex}`);
}
}
}
};
// python 回调
const mergeCallback = (params: any) => {
const mergeCallback = (params: {
list: {
url: string;
result_url: string;
}[];
index: number | string;
}) => {
try {
// console.log('python回调',params);
// 音频列表的下标
let index = params.index;
if (index) {
index = parseInt(index + '');
}
if (typeof index === 'number' && params.video) {
// 当前视频的返回结果
realVideoList.value[index].result = params.video;
// 首次播放
if (typeof index === 'number') {
// 先将有本地文件的替换
let currentRow = realVideoList.value[index].url;
currentRow.forEach((item: any) => {
params.list.forEach((it: any) => {
if (it.url == item.url) {
item.url = it.result_url;
}
});
});
// 首次回调后才开启主视频轮询
let list = realVideoList.value.filter((item: any) => item.remove === true);
if (!list.length) {
takeMainVideoV2();
// 首次回调后才开启主视频轮询
// 获取后台主视频
console.log('打开后台主视频轮询');
StartIntervalMainVideo();
startIntervalMainVideo();
}
} else {
writeLog({
name: 'mergeCallback 回调格式错误',
name: '音频直播py回调格式错误',
value: params,
});
console.log('回调格式错误');
console.log('音频直播py回调格式错误');
console.log(params);
}
} catch (e) {
writeLog({
name: 'only mergeCallback error',
name: '音频直播py回调报错了',
value: e,
});
console.log(e);
......@@ -892,6 +966,9 @@ export default function () {
getTone();
// 开启动作视频轮询
openLocalActionInterval();
// 播放进度定时器
openCurrentTimeInterval();
});
onBeforeUnmount(() => {
closeLiveInterval();
......@@ -899,10 +976,10 @@ export default function () {
closeIntervalMainVideo();
closeLocalMainVideoInterval();
closeLocalActionInterval();
closeCurrentTimeInterval();
});
return {
currentPlayMainIndex,
loading,
addVideoId,
liveDetail,
addVideo,
......@@ -919,5 +996,7 @@ export default function () {
currentTimeChange,
mainVideoListChange,
initActionVideo,
audioCanplay,
onPlayEnd,
};
}
......@@ -27,6 +27,11 @@ export default {
path: '/startLiveOnlyVideo',
name: 'startLiveOnlyVideo',
},
// 音频直播
onlyAudioLive: {
path: '/startLiveOnlyAudio',
name: 'startLiveOnlyAudio',
},
// 只有人工回复的页面
interactiveResponse: {
path: '/interactiveResponse',
......
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