Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
live-management-web
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
haojie
live-management-web
Commits
a3d210c3
Commit
a3d210c3
authored
Sep 14, 2023
by
haojie
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
音频直播
parent
4e45bf47
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
1138 additions
and
733 deletions
+1138
-733
src/pages/OnlyVideoLive/useScript.ts
+43
-41
src/pages/home/components/myDigtalPeople.vue
+145
-55
src/pages/onlyAudioLive/index.vue
+72
-0
src/pages/onlyAudioLive/useScript.ts
+868
-636
src/service/Live.ts
+8
-0
src/utils/request.ts
+2
-1
No files found.
src/pages/OnlyVideoLive/useScript.ts
View file @
a3d210c3
...
...
@@ -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'
;
// 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 (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
.
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
;
...
...
src/pages/home/components/myDigtalPeople.vue
View file @
a3d210c3
...
...
@@ -2,47 +2,74 @@
<div
class=
"my-digtal-people"
>
<Grid
:length=
"myDigtalList.list.length"
:marginLeft=
"35"
>
<template
v-for=
"item in myDigtalList.list"
:key=
"item.id"
>
<CardTwo
:id=
"item.id"
:img=
"item.cover_url"
:created_at=
"item.updated_at"
:value=
"item.name"
@
nameChange=
"nameChange"
>
<template
#
hover
>
<template
v-if=
"item.status != 2"
>
<div
class=
"my-digtal-people-hover"
>
<template
v-if=
"item.is_live == 0"
>
<Button
class=
"digtal-people-start-end"
theme=
"danger"
height=
"40px"
@
click=
"startLive(item)"
>
开启直播
</Button
>
</
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
>
</
template
>
<div
class=
"digtal-people-hover-tool"
>
<!-- <Button size="13" theme="dark" @click="onEdit(item)">编辑</Button> -->
<Button
size=
"13"
theme=
"dark"
@
click=
"downLoadVideo(item)"
>
下载
</Button>
<Button
size=
"13"
theme=
"dark"
@
click=
"onDelete(item)"
>
删除
</Button>
<template
v-if=
"item.type == LIVE_TYPES.VIDEO_LIVE"
>
<CardTwo
:id=
"item.id"
:img=
"item.cover_url"
:created_at=
"item.updated_at"
:value=
"item.name"
@
nameChange=
"nameChange"
>
<template
#
hover
>
<template
v-if=
"item.status != 2"
>
<div
class=
"my-digtal-people-hover"
>
<template
v-if=
"item.is_live == 0"
>
<Button
class=
"digtal-people-start-end"
theme=
"danger"
height=
"40px"
@
click=
"startLive(item)"
>
开启直播
</Button
>
</
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
>
</
template
>
<div
class=
"digtal-people-hover-tool"
>
<!-- <Button size="13" theme="dark" @click="onEdit(item)">编辑</Button> -->
<Button
size=
"13"
theme=
"dark"
@
click=
"downLoadVideo(item)"
>
下载
</Button>
<Button
size=
"13"
theme=
"dark"
@
click=
"onDelete(item)"
>
删除
</Button>
</div>
</div>
</div>
</template>
</template>
<
template
#
live
>
<template
v-if=
"item.is_live"
>
<div
class=
"digtal-people-status liveing"
>
<div
class=
"dot"
></div>
<span>
LIVE
</span>
</div>
</template>
</template>
<
template
v-if=
"item.status == 2"
>
<div
class=
"digtal-people-status process"
><OtherLoading></OtherLoading>
生成中
</div>
<
template
#
live
>
<template
v-if=
"item.is_live"
>
<div
class=
"digtal-people-status liveing"
>
<div
class=
"dot"
></div>
<span>
LIVE
</span>
</div>
</
template
>
<
template
v-if=
"item.status == 2"
>
<div
class=
"digtal-people-status process"
><OtherLoading></OtherLoading>
生成中
</div>
</
template
>
</template>
</template>
</CardTwo>
</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>
...
...
@@ -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,19 +181,31 @@ const downLoadVideo = async (item: any) => {
};
const
startLive
=
(
item
:
any
)
=>
{
// 视频直播页
let
params
=
beforePageJump
(
item
);
if
(
params
)
{
if
(
isDev
())
{
// 新的播放页面
router
.
push
({
path
:
routerConfig
.
onlyVideoLive
.
path
,
name
:
routerConfig
.
onlyVideoLive
.
name
,
query
:
params
,
});
}
else
{
params
.
page_path
=
routerConfig
.
onlyVideoLive
.
path
;
// 打开只有视频播放的页面
callPyjsInWindow
(
'openLivePage'
,
params
);
if
(
item
.
type
==
LIVE_TYPES
.
VIDEO_LIVE
)
{
if
(
isDev
())
{
// 新的播放页面
router
.
push
({
path
:
routerConfig
.
onlyVideoLive
.
path
,
name
:
routerConfig
.
onlyVideoLive
.
name
,
query
:
params
,
});
}
else
{
params
.
page_path
=
routerConfig
.
onlyVideoLive
.
path
;
// 打开只有视频播放的页面
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
);
...
...
src/pages/onlyAudioLive/index.vue
0 → 100644
View file @
a3d210c3
<
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
>
src/pages/
OnlyVideoLive/index.vue
→
src/pages/
onlyAudioLive/useScript.ts
View file @
a3d210c3
<
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,659 +12,912 @@ 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
();
const
store
=
useStore
();
const
route
=
useRoute
();
const
router
=
useRouter
();
const
routeQuery
=
route
.
query
;
const
userInfo
=
computed
(()
=>
store
.
getters
[
'user/userInfo'
]);
// 视频加载loading
const
loading
=
ref
(
true
);
const
progress
=
ref
(
0
);
// 剩余多少时长时开始洗稿并获取下一个视频
const
esidueTime
=
60
*
10
;
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
mainVideoList
=
ref
([
{
name
:
'mainVideo1'
,
// 播放链接
url
:
''
,
// 当前视频是否播放完毕
playEnd
:
true
,
// 是否正在播放
play
:
false
,
show
:
true
,
total
:
0
,
videoIndex
:
null
,
},
{
name
:
'mainVideo2'
,
// 播放链接
url
:
''
,
// 当前视频是否播放完毕
playEnd
:
true
,
play
:
false
,
show
:
false
,
total
:
0
,
videoIndex
:
null
,
},
]);
// 主视频列表状态更新
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
;
import
{
getDurationOfAudioFile
}
from
'@/utils/audio'
;
export
default
function
()
{
const
{
currentConfuseId
,
confuseList
,
stopConfuse
,
openConfuseInterval
}
=
useConfuse
();
const
{
openInterval
:
confuseInterval
}
=
processTextCallback
();
const
mainVideoType
=
1
;
const
actionVideoType
=
3
;
const
store
=
useStore
();
const
route
=
useRoute
();
const
router
=
useRouter
();
const
routeQuery
=
route
.
query
;
const
userInfo
=
computed
(()
=>
store
.
getters
[
'user/userInfo'
]);
// 视频加载loading
const
loading
=
ref
(
true
);
// 剩余多少时长时开始洗稿并获取下一个视频
const
esidueTime
=
60
*
10
;
const
imgs
=
{
mp4
:
new
URL
(
'../../assets/img/1.mp4'
,
import
.
meta
.
url
).
href
,
};
// 本次测试用的变量
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
([
{
name
:
'mainVideo1'
,
// 播放链接
url
:
''
,
// 当前视频是否播放完毕
playEnd
:
true
,
// 是否正在播放
play
:
false
,
show
:
true
,
total
:
0
,
videoIndex
:
null
,
},
{
name
:
'mainVideo2'
,
// 播放链接
url
:
''
,
// 当前视频是否播放完毕
playEnd
:
true
,
play
:
false
,
show
:
false
,
total
:
0
,
videoIndex
:
null
,
},
]);
// 获取当前页面的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'
)
{
// 列表其他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
],
'更新主视频列表'
);
// 更新视频列表
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
[])
=>
{
for
(
let
i
=
0
;
i
<
list
.
length
;
i
++
)
{
let
params
=
{
// 音色
phonetic_timbres_id
:
liveDetail
.
value
.
phonetic_timbres_id
,
// 音调
tone_id
:
liveDetail
.
value
.
tone_id
,
content
:
list
[
i
].
content
,
uuid
:
v4
(),
parent_uuid
:
currentConfuseId
.
value
,
id
:
i
,
};
// 生成音频
await
liveTts
(
params
);
}
console
.
log
(
'等待音频生成完成'
);
// 开始轮询
confuseInterval
(
true
,
''
,
false
,
currentConfuseId
.
value
,
regenerate
,
list
.
length
);
};
// 洗稿列表变化
watch
(
()
=>
confuseList
.
value
,
(
v
)
=>
{
if
(
v
.
length
)
{
console
.
log
(
'洗稿列表变化'
);
// 提交生成音频任务
submitAudioTask
(
v
);
};
const
submitAudioTask
=
async
(
list
:
any
[])
=>
{
for
(
let
i
=
0
;
i
<
list
.
length
;
i
++
)
{
let
params
=
{
// 音色
phonetic_timbres_id
:
liveDetail
.
value
.
phonetic_timbres_id
,
// 音调
tone_id
:
liveDetail
.
value
.
tone_id
,
content
:
list
[
i
].
content
,
uuid
:
v4
(),
parent_uuid
:
currentConfuseId
.
value
,
id
:
i
,
};
// 生成音频
await
liveTts
(
params
);
}
},
);
// 提交洗稿
const
submitConfuse
=
async
()
=>
{
try
{
// currentConfuseId.value = v4();
// let content = '';
// let contentList = liveDetail.value.type_content;
// if (contentList.length) {
// contentList.forEach((item: any) => {
// content += item.content;
// });
// console.log('提交洗稿任务');
// // 提交洗稿任务
// currentStartConfuse({
// content: content,
// task_id: currentConfuseId.value,
// id: route.query.id,
// });
// }
// 生成一个uid
currentConfuseId
.
value
=
v4
();
openConfuseInterval
(
`
${
userInfo
.
value
.
id
}
-
${
liveDetail
.
value
.
id
}
`
);
}
catch
(
e
)
{
console
.
log
(
e
);
}
};
// 找一个已经播放完毕的视频,加入video标签中
const
findOneVideoInit
=
()
=>
{
// 是否需要执行
let
status
=
false
;
let
videoTagIndex
=
mainVideoList
.
value
.
findIndex
((
item
:
any
,
index
:
number
)
=>
index
!==
currentPlayMainIndex
.
value
);
if
(
videoTagIndex
!==
-
1
)
{
let
hideVideo
=
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
;
console
.
log
(
'等待音频生成完成'
);
// 开始轮询
confuseInterval
(
true
,
''
,
false
,
currentConfuseId
.
value
,
regenerate
,
list
.
length
);
};
// 洗稿列表变化
watch
(
()
=>
confuseList
.
value
,
(
v
)
=>
{
if
(
v
.
length
)
{
console
.
log
(
'洗稿列表变化'
);
// 提交生成音频任务
submitAudioTask
(
v
);
}
},
);
// 提交洗稿
const
submitConfuse
=
async
()
=>
{
try
{
// currentConfuseId.value = v4();
// let content = '';
// let contentList = liveDetail.value.type_content;
// if (contentList.length) {
// contentList.forEach((item: any) => {
// content += item.content;
// });
// console.log('提交洗稿任务');
// // 提交洗稿任务
// currentStartConfuse({
// content: content,
// task_id: currentConfuseId.value,
// id: route.query.id,
// });
// }
// 生成一个uid
currentConfuseId
.
value
=
v4
();
openConfuseInterval
(
`
${
userInfo
.
value
.
id
}
-
${
liveDetail
.
value
.
id
}
`
);
}
catch
(
e
)
{
console
.
log
(
e
);
}
};
// 找一个已经播放完毕的视频,加入video标签中
const
findOneVideoInit
=
()
=>
{
// 是否需要执行
let
status
=
false
;
let
videoTagIndex
=
mainVideoList
.
value
.
findIndex
(
(
item
:
any
,
index
:
number
)
=>
index
!==
currentPlayMainIndex
.
value
,
);
if
(
videoTagIndex
!==
-
1
)
{
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
if
(
status
)
{
// 当前显示的视频
let
item
=
mainVideoList
.
value
[
currentPlayMainIndex
.
value
];
const
changeVideo
=
(
url
:
string
,
index
:
number
|
boolean
=
false
)
=>
{
hideVideo
.
play
=
false
;
hideVideo
.
playEnd
=
false
;
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
;
}
});
if
(
playEndVideos
.
length
)
{
if
(
playEndVideos
.
length
===
1
)
{
console
.
log
(
'只有一条视频播放完毕,重新播放该视频'
);
changeVideo
(
item
.
url
,
item
.
videoIndex
);
}
else
{
// 多条视频
// 随机下标
let
num
=
randomIntFormList
(
playEndVideos
);
console
.
log
(
`初始化第
${
num
}
个视频`
);
// 链接是否一致
if
(
realVideoList
.
value
[
num
].
result
===
item
.
url
)
{
// 循环播放
// start
if
(
status
)
{
// 当前显示的视频
let
item
=
mainVideoList
.
value
[
currentPlayMainIndex
.
value
];
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
.
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
(
'只有一条视频播放完毕,重新播放该视频'
);
changeVideo
(
item
.
url
,
item
.
videoIndex
);
console
.
log
(
'链接一致,等待重新播放'
);
}
else
{
// 更新当前视频标签的链接和状态
changeVideo
(
realVideoList
.
value
[
num
].
result
,
num
);
console
.
log
(
'成功加入队列'
);
// 多条视频
// 随机下标
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
)
{
// 循环播放
changeVideo
(
item
.
url
,
item
.
videoIndex
);
console
.
log
(
'链接一致,等待重新播放'
);
}
else
{
// 更新当前视频标签的链接和状态
changeVideo
(
realVideoList
.
value
[
num
].
result
,
num
);
console
.
log
(
'成功加入队列'
);
}
}
}
else
{
// 将当前正在播放的视频放入video标签
changeVideo
(
item
.
url
,
item
.
videoIndex
);
console
.
log
(
'将当前视频传给hide的视频'
);
}
}
else
{
// 将当前正在播放的视频放入video标签
changeVideo
(
item
.
url
,
item
.
videoIndex
);
console
.
log
(
'将当前视频传给hide的视频'
);
}
}
}
};
// 当前播放进度变化
const
currentTimeChange
=
(
index
:
number
,
value
:
number
)
=>
{
let
row
=
mainVideoList
.
value
[
index
];
// 剩余多少没有播放
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
.
type
==
scriptTypeText
&&
!
stopConfuse
.
value
)
{
console
.
log
(
row
.
videoIndex
,
'当前videoIndex'
);
currentVideoRow
.
confuse
=
CONFUSE_STATUS
.
CONFUSE_STATUS_PROGRESS
;
console
.
log
(
'直播开始洗稿'
);
// 开始洗稿
submitConfuse
();
}
// 判断是否需要取之前的主视频
if
(
currentEsidueTime
<
20
&&
typeof
currentPlayMainIndex
.
value
===
'number'
)
{
findOneVideoInit
();
}
};
// 互动视频播放结束
const
playEnd
=
(
id
:
any
)
=>
{
if
(
id
)
{
//
let
index
=
addVideoList
.
value
.
findIndex
((
item
:
any
)
=>
item
.
id
==
id
);
if
(
index
!==
-
1
)
{
console
.
log
(
'播放结束并更新状态'
,
id
);
addVideoList
.
value
[
index
].
play_status
=
true
;
// 移出
addVideoList
.
value
.
splice
(
index
,
1
);
}
}
};
// 开启主视频任务定时器
const
StartIntervalMainVideo
=
()
=>
{
intervalMainVideo
=
window
.
setInterval
(()
=>
{
getDetail
();
},
10000
);
};
// 关闭主视频任务定时器
const
closeIntervalMainVideo
=
()
=>
{
window
.
clearInterval
(
intervalMainVideo
);
clearInterval
(
intervalMainVideo
);
intervalMainVideo
=
null
;
};
const
stopInterval
=
()
=>
{
window
.
clearInterval
(
interval
);
clearInterval
(
interval
);
interval
=
null
;
};
// 开启本地主视频定时器
const
openLocalMainVideoInterval
=
()
=>
{
intervalLocalMainVideo
=
window
.
setInterval
(()
=>
{
takeMainVideoV2
(
false
);
},
5000
);
};
// 关闭本地主视频定时器
const
closeLocalMainVideoInterval
=
()
=>
{
window
.
clearInterval
(
intervalLocalMainVideo
);
clearInterval
(
intervalLocalMainVideo
);
intervalLocalMainVideo
=
null
;
};
// 获取最新的要播放的互动内容
const
openInterval
=
()
=>
{
interval
=
window
.
setInterval
(()
=>
{
// 找到第一个没有播放的
for
(
let
i
=
0
;
i
<
addVideoList
.
value
.
length
;
i
++
)
{
let
item
=
addVideoList
.
value
[
i
];
if
(
item
.
play_status
===
false
&&
item
.
remove
)
{
// 已有取走的任务正在执行
// console.log('已有取走的任务正在执行');
break
;
};
// 当前播放进度变化
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'
&&
liveDetail
.
value
.
is_disorganize
&&
liveDetail
.
value
.
type
==
scriptTypeText
&&
!
stopConfuse
.
value
)
{
console
.
log
(
row
.
videoIndex
,
'当前videoIndex'
);
currentVideoRow
.
confuse
=
CONFUSE_STATUS
.
CONFUSE_STATUS_PROGRESS
;
console
.
log
(
'直播开始洗稿'
);
// 开始洗稿
submitConfuse
();
}
if
(
item
.
play_status
===
false
&&
item
.
remove
===
false
)
{
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
;
// 判断是否需要取之前的主视频
if
(
currentEsidueTime
<
20
&&
typeof
currentPlayMainIndex
.
value
===
'number'
)
{
findOneVideoInit
();
}
}
catch
(
e
)
{
console
.
log
(
e
);
}
},
100
);
};
// 获取直播互动内容
const
getLive
=
async
()
=>
{
try
{
let
res
:
any
=
await
getliveTaskReply
(
route
.
query
.
id
);
if
(
res
.
code
==
0
&&
res
.
data
&&
res
.
data
.
length
)
{
res
.
data
.
forEach
((
item
:
any
)
=>
{
item
.
play_status
=
false
;
item
.
remove
=
false
;
});
//id
// problem
// reply_content
addVideoList
.
value
=
addVideoList
.
value
.
concat
(
res
.
data
);
}
}
catch
(
e
)
{
writeLog
({
name
:
'getliveTaskReply 获取直播互动失败'
,
value
:
e
,
});
console
.
log
(
e
);
}
};
// 重新生成直播
const
regenerate
=
async
(
list
:
any
[])
=>
{
try
{
let
params
=
{
digital_man_id
:
liveDetail
.
value
.
digital_man_id
,
name
:
liveDetail
.
value
.
name
,
phonetic_timbres_id
:
liveDetail
.
value
.
phonetic_timbres_id
,
tone_id
:
liveDetail
.
value
.
tone_id
,
type
:
liveDetail
.
value
.
type
,
};
params
.
type_content
=
list
;
let
res
:
any
=
await
liveTaskRegenerate
(
liveDetail
.
value
.
id
,
params
);
if
(
res
.
code
==
0
)
{
};
// 互动视频播放结束
const
playEnd
=
(
id
:
any
)
=>
{
if
(
id
)
{
//
console
.
log
(
'重新生成直播,已提交'
);
let
index
=
addVideoList
.
value
.
findIndex
((
item
:
any
)
=>
item
.
id
==
id
);
if
(
index
!==
-
1
)
{
console
.
log
(
'播放结束并更新状态'
,
id
);
addVideoList
.
value
[
index
].
play_status
=
true
;
// 移出
addVideoList
.
value
.
splice
(
index
,
1
);
}
}
}
catch
(
e
)
{
writeLog
({
name
:
'only live regenerate error'
,
value
:
e
,
};
// 动作视频更新
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
;
});
console
.
log
(
e
);
}
};
// 开启
const
startLiveInterval
=
()
=>
{
closeLiveInterval
();
intervalLive
=
window
.
setInterval
(()
=>
{
getLive
();
},
3000
);
};
// 关闭
const
closeLiveInterval
=
()
=>
{
window
.
clearInterval
(
intervalLive
);
clearInterval
(
intervalLive
);
intervalLive
=
null
;
};
const
getDetail
=
async
(
type
:
string
=
''
)
=>
{
if
(
!
routeQuery
.
id
)
{
show_message
(
'禁止访问'
);
return
;
}
try
{
let
res
:
any
=
await
getLiveDetail
(
routeQuery
.
id
);
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
(
row
.
mainStart
)
{
// 是主视频--通知视频直接播放
playInfo
.
value
.
mainStart
=
true
;
playInfo
.
value
.
num
+=
1
;
}
};
// 开启主视频任务定时器
const
StartIntervalMainVideo
=
()
=>
{
intervalMainVideo
=
window
.
setInterval
(()
=>
{
getDetail
();
},
10000
);
};
// 关闭主视频任务定时器
const
closeIntervalMainVideo
=
()
=>
{
window
.
clearInterval
(
intervalMainVideo
);
clearInterval
(
intervalMainVideo
);
intervalMainVideo
=
null
;
};
// 开启本地主视频定时器
const
openLocalMainVideoInterval
=
()
=>
{
intervalLocalMainVideo
=
window
.
setInterval
(()
=>
{
takeMainVideoV2
(
false
);
},
5000
);
};
// 关闭本地主视频定时器
const
closeLocalMainVideoInterval
=
()
=>
{
window
.
clearInterval
(
intervalLocalMainVideo
);
clearInterval
(
intervalLocalMainVideo
);
intervalLocalMainVideo
=
null
;
};
// 获取最新的要播放的互动内容
const
openInterval
=
()
=>
{
interval
=
window
.
setInterval
(()
=>
{
try
{
// 找到第一个没有播放的
for
(
let
i
=
0
;
i
<
addVideoList
.
value
.
length
;
i
++
)
{
let
item
=
addVideoList
.
value
[
i
];
if
(
item
.
play_status
===
false
&&
item
.
remove
)
{
// 已有取走的任务正在执行
// console.log('已有取走的任务正在执行');
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'
);
// console.log('本次视频与上次一致');
}
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
);
};
// 关闭本地互动定时器
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
;
}
}
}
if
(
DataType
(
res
.
data
,
'object'
)
&&
res
.
data
.
url
&&
res
.
data
.
url
.
length
)
{
// 初始化视频列表的状态
res
.
data
.
url
.
forEach
((
item
:
any
)
=>
{
// 是否播放完毕
item
.
status
=
false
;
// 是否取走
}
};
// 打开本地动作视频定时器
const
openLocalActionInterval
=
()
=>
{
intervalAction
=
window
.
setInterval
(()
=>
{
retrieveLocalActionVideo
();
},
1000
);
};
// 关闭本地动作视频定时器
const
closeLocalActionInterval
=
()
=>
{
window
.
clearInterval
(
intervalAction
);
clearInterval
(
intervalAction
);
intervalAction
=
null
;
};
// 获取直播互动内容
const
getLive
=
async
()
=>
{
try
{
let
res
:
any
=
await
getliveTaskReply
(
route
.
query
.
id
);
if
(
res
.
code
==
0
&&
res
.
data
&&
res
.
data
.
length
)
{
res
.
data
.
forEach
((
item
:
any
)
=>
{
item
.
play_status
=
false
;
item
.
remove
=
false
;
// 是否正在播放
item
.
play
=
false
;
});
// 取出所有 type==1 的主视频,计算总时长
realVideoList
.
value
.
push
({
url
:
res
.
data
.
url
,
// 合并后的地址
result
:
''
,
// 是否播放完毕
status
:
false
,
// 是否取走
remove
:
false
,
// 是否正在播放
play
:
false
,
// 是否已经提交给python
submit
:
false
,
// 下一个视频的状态(洗稿状态)
confuse
:
CONFUSE_STATUS
.
CONFUSE_STATUS_WAIT
,
});
//id
// problem
// reply_content
addVideoList
.
value
=
addVideoList
.
value
.
concat
(
res
.
data
);
}
}
catch
(
e
)
{
writeLog
({
name
:
'getliveTaskReply 获取直播互动失败'
,
value
:
e
,
});
console
.
log
(
e
);
}
};
// 重新生成直播
const
regenerate
=
async
(
list
:
any
[])
=>
{
try
{
let
params
=
{
digital_man_id
:
liveDetail
.
value
.
digital_man_id
,
name
:
liveDetail
.
value
.
name
,
phonetic_timbres_id
:
liveDetail
.
value
.
phonetic_timbres_id
,
tone_id
:
liveDetail
.
value
.
tone_id
,
type
:
liveDetail
.
value
.
type
,
type_content
:
list
,
};
let
res
:
any
=
await
liveTaskRegenerate
(
liveDetail
.
value
.
id
,
params
);
if
(
res
.
code
==
0
)
{
//
console
.
log
(
'重新生成直播,已提交'
);
}
}
catch
(
e
)
{
writeLog
({
name
:
'only live regenerate error'
,
value
:
e
,
});
console
.
log
(
e
);
}
};
// 开启
const
startLiveInterval
=
()
=>
{
closeLiveInterval
();
intervalLive
=
window
.
setInterval
(()
=>
{
getLive
();
},
3000
);
};
// 关闭
const
closeLiveInterval
=
()
=>
{
window
.
clearInterval
(
intervalLive
);
clearInterval
(
intervalLive
);
intervalLive
=
null
;
};
const
getDetail
=
async
(
type
:
string
=
''
)
=>
{
if
(
!
getRouteId
())
{
show_message
(
'禁止访问'
);
return
;
}
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
(
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
;
item
.
play
=
false
;
item
.
status
=
false
;
return
item
;
}
});
// 最后一个视频是否是动作视频
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
:
mainUrl
,
// 过滤动作视频
actionUrl
:
actionUrl
,
// 第一个视频是否是主视频
mainStart
:
res
.
data
.
url
[
0
].
type
===
mainVideoType
?
true
:
false
,
// 最后一个视频是否是主视频
mainEnd
:
{
status
:
mainEnd
,
url
:
url
,
// 生成一个uid
uuid
:
uuid
,
},
// 合并后的地址
result
:
''
,
// 是否播放完毕
status
:
false
,
// 是否取走
remove
:
false
,
// 是否正在播放
play
:
false
,
// 是否已经提交给python
submit
:
false
,
// 下一个视频的状态(洗稿状态)
confuse
:
CONFUSE_STATUS
.
CONFUSE_STATUS_WAIT
,
});
if
(
isDev
())
{
if
(
isFirst
.
value
)
{
mergeCallback
({
video
:
res
.
data
.
url
[
0
].
url
,
index
:
realVideoList
.
value
.
length
-
1
,
childIndex
:
0
,
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合并
submitVideo
();
}
if
(
type
===
'init'
)
{
// 通知python刷新所有首页的直播列表
callPyjsInWindow
(
'reloadLiveTaskList'
);
// 开播成功
router
.
replace
({
path
:
routerConfig
.
onlyVideoLive
.
path
,
name
:
routerConfig
.
onlyVideoLive
.
name
,
query
:
{
...
route
.
query
,
is_live
:
'1'
,
},
});
isFirst
.
value
=
false
;
}
}
else
{
// 通知python合并
submitVideo
();
}
if
(
type
===
'init'
)
{
// 通知python刷新所有首页的直播列表
callPyjsInWindow
(
'reloadLiveTaskList'
);
// 开播成功
router
.
replace
({
path
:
routerConfig
.
onlyVideoLive
.
path
,
name
:
routerConfig
.
onlyVideoLive
.
name
,
query
:
{
...
route
.
query
,
is_live
:
'1'
,
},
});
console
.
log
(
'直播没有返回值'
);
}
}
else
{
console
.
log
(
'直播没有返回值'
);
}
}
catch
(
e
)
{
writeLog
({
name
:
'获取直播链接失败'
,
value
:
e
,
});
console
.
log
(
e
);
}
}
catch
(
e
)
{
writeLog
({
name
:
'获取直播链接失败'
,
value
:
e
,
});
console
.
log
(
e
);
}
};
// 视频列表提交到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
);
};
// 视频列表提交到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
(
'没有要提交的任务'
);
}
}
else
{
console
.
log
(
'没有
要提交的任务
'
);
console
.
log
(
'没有
run方法
'
);
}
}
else
{
console
.
log
(
'没有run方法
'
);
show_message
(
'empty-1 py
'
);
}
}
else
{
show_message
(
'empty-1 py'
);
}
catch
(
e
)
{
console
.
log
(
e
);
writeLog
({
name
:
'only submitVideo error'
,
value
:
e
,
});
}
}
catch
(
e
)
{
console
.
log
(
e
);
writeLog
({
name
:
'only submitVideo error'
,
value
:
e
,
});
}
};
// 取主视频(v2)
const
takeMainVideoV2
=
(
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
)
{
// 存入视频
mainVideoList
.
value
[
index
].
url
=
realVideoList
.
value
[
videoIndex
].
result
;
// 更新状态
mainVideoList
.
value
[
index
].
playEnd
=
false
;
mainVideoList
.
value
[
index
].
videoIndex
=
videoIndex
;
// 视频已被取走
realVideoList
.
value
[
videoIndex
].
remove
=
true
;
console
.
log
(
mainVideoList
.
value
[
index
],
'取出下一条要播放的视频'
,
index
,
videoIndex
);
if
(
first
)
{
// 视频加载完毕
loading
.
value
=
false
;
};
// 取主视频(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
=
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
;
}
}
}
}
};
// python 回调
const
mergeCallback
=
(
params
:
any
)
=>
{
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
;
// 首次播放
let
list
=
realVideoList
.
value
.
filter
((
item
:
any
)
=>
item
.
remove
===
true
);
if
(
!
list
.
length
)
{
takeMainVideoV2
();
// 首次回调后才开启主视频轮询
// 获取后台主视频
console
.
log
(
'打开后台主视频轮询'
);
StartIntervalMainVideo
();
};
// python 回调
const
mergeCallback
=
(
params
:
any
)
=>
{
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
;
// 首次播放
let
list
=
realVideoList
.
value
.
filter
((
item
:
any
)
=>
item
.
remove
===
true
);
if
(
!
list
.
length
)
{
takeMainVideoV2
();
// 首次回调后才开启主视频轮询
// 获取后台主视频
console
.
log
(
'打开后台主视频轮询'
);
StartIntervalMainVideo
();
}
}
else
{
writeLog
({
name
:
'mergeCallback 回调格式错误'
,
value
:
params
,
});
console
.
log
(
'回调格式错误'
);
console
.
log
(
params
);
}
}
else
{
console
.
log
(
'回调格式错误'
);
console
.
log
(
params
);
}
catch
(
e
)
{
writeLog
({
name
:
'only mergeCallback error'
,
value
:
e
,
});
console
.
log
(
e
);
}
}
catch
(
e
)
{
writeLog
({
name
:
'only mergeCallback error'
,
value
:
e
,
});
console
.
log
(
e
);
}
};
const
getTone
=
async
()
=>
{
try
{
let
res
=
await
getLiveTaskInfo
(
route
.
query
.
id
);
if
(
res
.
code
==
0
)
{
liveDetail
.
value
=
res
.
data
;
};
const
getTone
=
async
()
=>
{
try
{
let
res
:
any
=
await
getLiveTaskInfo
(
getRouteId
());
if
(
res
.
code
==
0
)
{
liveDetail
.
value
=
res
.
data
;
}
}
catch
(
e
)
{
console
.
log
(
e
);
}
}
catch
(
e
)
{
console
.
log
(
e
);
}
};
//
const
closeLive
=
async
()
=>
{
try
{
let
res
:
any
=
await
closeLiveTask
(
route
.
query
.
id
);
if
(
res
.
code
==
0
)
{
// 通知python刷新所有首页的直播列表
c
allPyjsInWindow
(
'reloadLiveTaskList'
);
}
;
//
const
closeLive
=
async
()
=>
{
try
{
let
res
:
any
=
await
closeLiveTask
(
route
.
query
.
id
);
if
(
res
.
code
==
0
)
{
// 通知python刷新所有首页的直播列表
callPyjsInWindow
(
'reloadLiveTaskList'
);
}
}
catch
(
e
)
{
c
onsole
.
log
(
e
);
}
}
catch
(
e
)
{
console
.
log
(
e
);
}
};
onMounted
(
async
()
=>
{
// 将通知方法注入window
injectWindow
(
'mergeCallback'
,
mergeCallback
);
injectWindow
(
'closeLive'
,
closeLive
);
// 获取后台互动
startLiveInterval
();
// 本地轮询获取要播放的互动视频
openInterval
();
// 本地轮询获取要播放的主视频
openLocalMainVideoInterval
();
// 可以开播
await
getDetail
(
'init'
);
// 获取音调和音色
getTone
(
);
});
onBeforeUnmount
(()
=>
{
closeLive
Interval
();
stopInterval
();
closeIntervalMainVideo
();
closeLocalMainVideo
Interval
();
});
</
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
;
}
}
;
onMounted
(
async
()
=>
{
// 将通知方法注入window
injectWindow
(
'mergeCallback'
,
mergeCallback
);
injectWindow
(
'closeLive'
,
closeLive
);
// 获取后台互动
startLiveInterval
(
);
// 本地轮询获取要播放的互动视频
openInterval
();
// 本地轮询获取要播放的主视频
openLocalMainVideoInterval
();
// 可以开播
await
getDetail
(
'init'
);
// 获取音调和音色
getTone
();
// 开启动作视频轮询
openLocalActionInterval
();
}
);
onBeforeUnmount
(()
=>
{
closeLiveInterval
();
stop
Interval
();
closeIntervalMainVideo
();
closeLocalMainVideoInterval
();
closeLocalAction
Interval
();
});
return
{
currentPlayMainIndex
,
loading
,
addVideoId
,
liveDetail
,
addVideo
,
actionVideo
,
currentMainVideoIndex
,
mainVideoList
,
playInfo
,
firstVideoIsMain
,
endVideoIsMain
,
showActionVideo
,
realVideoList
,
playEnd
,
actionPlayChange
,
currentTimeChange
,
mainVideoListChange
,
initActionVideo
,
}
;
}
</
style
>
src/service/Live.ts
View file @
a3d210c3
...
...
@@ -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
,
// 音频直播
};
src/utils/request.ts
View file @
a3d210c3
...
...
@@ -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
''
;
}
// 默认线上地址
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment