Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
S
saas-lab
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
EzijingWeb
saas-lab
Commits
163b7c3d
提交
163b7c3d
authored
1月 09, 2024
作者:
王鹏飞
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
chore: 修改视频上传
上级
f3c48f1e
隐藏空白字符变更
内嵌
并排
正在显示
11 个修改的文件
包含
208 行增加
和
177 行删除
+208
-177
base.ts
src/api/base.ts
+9
-5
UploadVideo.vue
src/components/UploadVideo.vue
+13
-118
useUpload.ts
src/composables/useUpload.ts
+118
-0
ViewVideoFormDialog.vue
...es/admin/contest/items/components/ViewVideoFormDialog.vue
+4
-2
ViewVideoPreviewDialog.vue
...admin/contest/items/components/ViewVideoPreviewDialog.vue
+14
-12
types.ts
src/modules/admin/contest/items/types.ts
+1
-0
FormDialog.vue
src/modules/admin/lab/video/components/FormDialog.vue
+4
-2
types.ts
src/modules/admin/lab/video/types.ts
+1
-0
View.vue
src/modules/admin/lab/video/views/View.vue
+14
-12
VideoItem.vue
src/modules/student/contest/components/VideoItem.vue
+15
-13
VideoItem.vue
src/modules/student/lab/components/VideoItem.vue
+15
-13
没有找到文件。
src/api/base.ts
浏览文件 @
163b7c3d
...
...
@@ -87,9 +87,13 @@ export function checkLocalFile(params: { file_name: string }) {
}
// 上传文件
export
function
uploadLocalFile
(
data
:
{
file
:
File
;
file_name
:
string
;
is_continuingly
?:
number
;
now_package_num
:
number
;
total_package_num
:
number
})
{
return
httpRequest
.
post
(
'/api/lab/v1/common/file/upload'
,
data
,
{
withCredentials
:
false
,
headers
:
{
'Content-Type'
:
'multipart/form-data'
}
})
export
function
uploadLocalFile
(
data
:
{
file
:
File
|
Blob
;
file_name
:
string
;
is_continuingly
?:
number
;
now_package_num
:
number
;
total_package_num
:
number
},
options
=
{}
)
{
return
httpRequest
.
post
(
'/api/lab/v1/common/file/upload'
,
data
,
Object
.
assign
({
withCredentials
:
false
,
headers
:
{
'Content-Type'
:
'multipart/form-data'
}
},
options
)
)
}
src/components/UploadVideo.vue
浏览文件 @
163b7c3d
<
script
setup
lang=
"ts"
>
import
OSS
from
'ali-oss'
import
'@/lib/aliyun-upload-sdk/aliyun-upload-sdk-1.5.3.min.js'
import
{
VideoPlay
}
from
'@element-plus/icons-vue'
import
{
getUploadVideoAuth
,
updateUploadVideoAuth
}
from
'@/api/base'
;(
window
as
any
).
OSS
=
OSS
// uploadInfo 包含要上传的文件信息
interface
UploadInfo
{
bucket
:
string
checkpoint
:
{
file
:
File
;
name
:
string
;
fileSize
:
number
;
partSize
:
number
;
uploadId
:
string
}
endpoint
:
string
file
:
File
fileHash
:
string
isImage
:
boolean
loaded
:
number
object
:
string
region
:
string
retry
:
boolean
ri
:
string
state
:
string
userData
:
string
videoId
:
string
videoInfo
:
any
progress
:
number
}
import
{
useUpload
}
from
'@/composables/useUpload'
interface
Props
{
beforeUpload
?:
(
file
:
any
)
=>
void
}
...
...
@@ -31,12 +10,16 @@ const props = defineProps<Props>()
const
emit
=
defineEmits
([
'success'
])
const
uploader
=
createUploader
()
let
fileList
=
$ref
<
UploadInfo
[]
>
([])
const
{
files
,
addFile
,
stopUpload
}
=
useUpload
({
onUploadSucceed
(
file
)
{
emit
(
'success'
,
file
)
}
})
onUnmounted
(()
=>
{
uploader
&&
uploader
.
stopUpload
()
stopUpload
()
})
const
fileChange
=
async
(
event
:
Event
)
=>
{
const
element
=
event
.
currentTarget
as
HTMLInputElement
const
files
:
FileList
|
null
=
element
.
files
...
...
@@ -44,104 +27,16 @@ const fileChange = async (event: Event) => {
if
(
props
.
beforeUpload
)
{
try
{
await
props
.
beforeUpload
(
files
)
uploader
.
cleanList
()
}
catch
(
error
)
{
console
.
log
(
error
)
return
false
}
}
for
(
const
file
of
files
)
{
// 是否重复上传
const
hasRepeat
=
!!
fileList
.
find
(
item
=>
item
.
file
.
name
===
file
.
name
&&
item
.
file
.
size
===
file
.
size
&&
item
.
file
.
lastModified
===
file
.
lastModified
)
!
hasRepeat
&&
uploader
.
addFile
(
file
,
null
,
null
,
null
,
'{"Vod":{}}'
)
addFile
(
file
)
}
uploader
.
startUpload
()
fileList
=
uploader
.
_uploadList
}
function
updateFileList
(
uploadInfo
:
UploadInfo
)
{
if
(
!
uploadInfo
)
return
fileList
=
fileList
.
map
(
item
=>
{
if
(
item
.
ri
===
uploadInfo
.
ri
)
{
return
{
...
item
,
...
uploadInfo
}
}
return
item
})
}
function
createUploader
()
{
return
new
(
window
as
any
).
AliyunUpload
.
Vod
({
//userID,必填,您可以使用阿里云账号访问账号中心(https://account.console.aliyun.com/),即可查看账号ID
userId
:
'1303984639806000'
,
//上传到视频点播的地域,默认值为'cn-shanghai',
//eu-central-1,ap-southeast-1
region
:
'cn-shanghai'
,
//分片大小默认1 MB,不能小于100 KB(100*1024)
partSize
:
1048576
,
//并行上传分片个数,默认5
parallel
:
5
,
//网络原因失败时,重新上传次数,默认为3
retryCount
:
3
,
//网络原因失败时,重新上传间隔时间,默认为2秒
retryDuration
:
2
,
//开始上传
onUploadstarted
:
onUploadStarted
,
//文件上传成功
onUploadSucceed
:
onUploadSucceed
,
//文件上传失败
onUploadFailed
:
onUploadFailed
,
//文件上传进度,单位:字节
onUploadProgress
:
onUploadProgress
,
//上传凭证或STS token超时
onUploadTokenExpired
:
onUploadTokenExpired
,
//全部文件上传结束
onUploadEnd
:
onUploadEnd
})
}
// 开始上传
function
onUploadStarted
(
uploadInfo
:
UploadInfo
)
{
console
.
log
(
'onUploadStarted'
,
uploadInfo
)
getUploadVideoAuth
({
title
:
uploadInfo
.
file
.
name
,
file_name
:
uploadInfo
.
file
.
name
}).
then
(
res
=>
{
uploader
.
setUploadAuthAndAddress
(
uploadInfo
,
res
.
data
.
upload_auth
,
res
.
data
.
upload_address
,
res
.
data
.
source_id
)
})
updateFileList
(
uploadInfo
)
}
// 文件上传成功
function
onUploadSucceed
(
uploadInfo
:
UploadInfo
)
{
console
.
log
(
'onUploadSucceed'
,
uploadInfo
)
updateFileList
(
uploadInfo
)
emit
(
'success'
,
uploadInfo
)
}
//文件上传失败
function
onUploadFailed
(
uploadInfo
:
UploadInfo
,
code
:
number
,
message
:
string
)
{
console
.
log
(
'onUploadFailed'
,
uploadInfo
,
code
,
message
)
updateFileList
(
uploadInfo
)
}
//文件上传进度,单位:字节
function
onUploadProgress
(
uploadInfo
:
UploadInfo
,
totalSize
:
number
,
loadedPercent
:
number
)
{
console
.
log
(
'onUploadProgress'
,
uploadInfo
.
file
.
name
,
uploadInfo
,
totalSize
,
loadedPercent
)
updateFileList
(
uploadInfo
)
}
//上传凭证或STS token超时
function
onUploadTokenExpired
(
uploadInfo
:
UploadInfo
)
{
console
.
log
(
'onUploadTokenExpired'
,
uploadInfo
)
updateUploadVideoAuth
({
source_id
:
uploadInfo
.
videoId
}).
then
(
res
=>
{
uploader
.
resumeUploadWithAuth
(
res
.
data
.
UploadAuth
)
})
updateFileList
(
uploadInfo
)
}
// 全部文件上传结束
function
onUploadEnd
(
uploadInfo
:
UploadInfo
)
{
console
.
log
(
'onUploadEnd'
,
uploadInfo
)
updateFileList
(
uploadInfo
)
}
// 进度条
function
percentage
(
value
:
number
)
{
return
parseFloat
((
value
?
value
*
100
:
0
).
toFixed
(
2
))
}
defineExpose
({
uploader
,
fileList
:
$$
(
fileList
)
})
defineExpose
({
files
})
</
script
>
<
template
>
<div
class=
"upload-video"
>
...
...
@@ -151,13 +46,13 @@ defineExpose({ uploader, fileList: $$(fileList) })
</div>
<div
class=
"tips"
>
推荐视频格式:帧率为25fps\输出码率为4M\输出格式为mp4,建议采用格式工厂等工具处理后上传。
</div>
<ul
class=
"upload-video-list"
v-for=
"(item, index) in file
List
"
:key=
"index"
>
<ul
class=
"upload-video-list"
v-for=
"(item, index) in file
s
"
:key=
"index"
>
<li>
<div
class=
"upload-video-list__item-info"
>
<el-icon><VideoPlay
/></el-icon>
<p>
{{
item
.
file
?.
name
}}
</p>
</div>
<el-progress
:stroke-width=
"2"
:percentage=
"
percentage(item.loaded)"
v-if=
"item.loaded !== 1
"
/>
<el-progress
:stroke-width=
"2"
:percentage=
"
item.progress"
v-if=
"item.progress !== 100
"
/>
</li>
</ul>
</div>
...
...
src/composables/useUpload.ts
0 → 100644
浏览文件 @
163b7c3d
import
{
getLocalFileChunk
,
uploadLocalFile
}
from
'@/api/base'
interface
FileItem
{
file
:
File
url
:
string
name
:
string
progress
:
number
abortController
:
AbortController
}
interface
UploadOptions
{
multiple
?:
boolean
autoUpload
?:
boolean
onUploadStarted
?:
(
file
:
FileItem
)
=>
void
onUploadSucceed
?:
(
file
:
FileItem
)
=>
void
onUploadFailed
?:
(
file
:
FileItem
,
error
:
any
)
=>
void
onUploadProgress
?:
(
file
:
FileItem
,
progress
:
number
)
=>
void
onUploadEnd
?:
()
=>
void
}
export
function
useUpload
(
options
:
UploadOptions
=
{})
{
options
=
Object
.
assign
({
autoUpload
:
true
,
multiple
:
false
},
options
)
const
files
=
ref
<
FileItem
[]
>
([])
const
uploading
=
ref
(
false
)
function
addFile
(
file
:
File
)
{
// 检查文件是否已经在队列中
const
existingFileIndex
=
files
.
value
.
findIndex
(
f
=>
f
.
name
===
file
.
name
)
// 如果文件已经在队列中,并且上传已经开始,则直接返回
if
(
existingFileIndex
!==
-
1
&&
files
.
value
[
existingFileIndex
].
progress
>
0
)
return
if
(
!
options
.
multiple
)
stopUpload
()
const
abortController
=
new
AbortController
()
files
.
value
.
push
({
url
:
''
,
name
:
file
.
name
,
file
,
progress
:
0
,
abortController
})
if
(
options
.
autoUpload
&&
!
uploading
.
value
)
startUpload
()
}
async
function
startUpload
()
{
uploading
.
value
=
true
for
(
const
file
of
files
.
value
)
{
if
(
file
.
progress
===
0
)
{
// 只处理尚未开始上传的文件
try
{
options
?.
onUploadStarted
?.(
file
)
await
uploadFile
(
file
)
options
?.
onUploadSucceed
?.(
file
)
}
catch
(
error
)
{
options
?.
onUploadFailed
?.(
file
,
error
)
}
}
}
uploading
.
value
=
false
options
?.
onUploadEnd
?.()
}
async
function
uploadFile
(
file
:
FileItem
)
{
const
{
data
:
{
detail
}
}
=
await
getLocalFileChunk
({
file_name
:
file
.
file
.
name
,
file_size
:
file
.
file
.
size
})
const
fileName
=
detail
.
file_name
const
chunkSize
=
detail
.
chunk_size
const
totalChunks
=
Math
.
ceil
(
file
.
file
.
size
/
chunkSize
)
for
(
let
chunkIndex
=
0
;
chunkIndex
<
totalChunks
;
chunkIndex
++
)
{
const
chunk
=
file
.
file
.
slice
(
chunkIndex
*
chunkSize
,
(
chunkIndex
+
1
)
*
chunkSize
)
await
uploadChunk
({
file
,
chunk
,
chunkIndex
,
fileName
,
totalChunks
})
}
}
async
function
uploadChunk
({
file
,
chunk
,
chunkIndex
,
fileName
,
totalChunks
}:
{
file
:
FileItem
chunk
:
Blob
chunkIndex
:
number
fileName
:
string
totalChunks
:
number
})
{
const
{
data
:
{
detail
}
}
=
await
uploadLocalFile
(
{
file_name
:
fileName
,
file
:
chunk
,
now_package_num
:
chunkIndex
+
1
,
total_package_num
:
totalChunks
},
{
signal
:
file
.
abortController
.
signal
,
onUploadProgress
(
event
:
ProgressEvent
)
{
updateProgress
({
file
,
event
,
chunkIndex
,
totalChunks
})
}
}
)
file
.
url
=
detail
.
uri
}
function
updateProgress
({
event
,
chunkIndex
,
totalChunks
,
file
}:
{
file
:
FileItem
;
event
:
ProgressEvent
;
chunkIndex
:
number
;
totalChunks
:
number
})
{
const
totalSize
=
event
.
total
*
totalChunks
const
loadedSize
=
event
.
loaded
+
chunkIndex
*
event
.
total
const
progressPercent
=
(
loadedSize
/
totalSize
)
*
100
file
.
progress
=
parseFloat
(
progressPercent
.
toFixed
(
2
))
options
?.
onUploadProgress
?.(
file
,
file
.
progress
)
console
.
log
(
file
.
progress
)
}
function
cancelUpload
(
file
:
FileItem
)
{
file
.
abortController
.
abort
()
files
.
value
=
files
.
value
.
filter
(
item
=>
item
.
name
!==
file
.
name
)
}
function
stopUpload
()
{
files
.
value
.
forEach
(
cancelUpload
)
// 停止所有文件的上传
files
.
value
.
length
=
0
uploading
.
value
=
false
// 更新上传状态
}
return
{
files
,
uploading
,
addFile
,
startUpload
,
cancelUpload
,
stopUpload
}
}
src/modules/admin/contest/items/components/ViewVideoFormDialog.vue
浏览文件 @
163b7c3d
...
...
@@ -29,7 +29,8 @@ const form = reactive<any>({
source_id
:
''
,
duration
:
0
,
type
:
''
,
protocol
:
false
protocol
:
false
,
size
:
''
})
watchEffect
(()
=>
{
if
(
!
props
.
data
)
return
...
...
@@ -69,7 +70,8 @@ function handleBeforeUpload() {
function
handleUploadSuccess
(
uploadInfo
:
any
)
{
form
.
name
=
uploadInfo
.
file
.
name
.
split
(
'.'
).
shift
()
form
.
source_id
=
uploadInfo
.
videoId
form
.
source_id
=
uploadInfo
.
url
form
.
size
=
uploadInfo
.
file
.
size
}
// 提交
function
handleSubmit
()
{
...
...
src/modules/admin/contest/items/components/ViewVideoPreviewDialog.vue
浏览文件 @
163b7c3d
...
...
@@ -6,21 +6,25 @@ interface Props {
data
:
ContestVideoItem
}
const
props
=
defineProps
<
Props
>
()
let
playList
=
$ref
<
any
>
(
[]
)
let
playList
=
$ref
<
any
>
()
function
fetchInfo
()
{
getContestVideoPalyInfo
({
source_id
:
props
.
data
.
source_id
}).
then
(
res
=>
{
playList
=
res
.
data
.
replay_list
.
play_info_list
})
}
const
playUrl
=
$computed
(()
=>
{
const
definitionUrl
=
playList
.
reduce
(
(
result
:
any
,
item
:
any
)
=>
{
result
[
item
.
Definition
]
=
item
.
PlayURL
return
result
},
{
SD
:
''
,
LD
:
''
,
FD
:
''
}
)
return
definitionUrl
.
SD
||
definitionUrl
.
LD
||
definitionUrl
.
FD
if
(
Array
.
isArray
(
playList
))
{
const
definitionUrl
=
playList
.
reduce
(
(
result
:
any
,
item
:
any
)
=>
{
result
[
item
.
Definition
]
=
item
.
PlayURL
return
result
},
{
SD
:
''
,
LD
:
''
,
FD
:
''
}
)
return
definitionUrl
.
SD
||
definitionUrl
.
LD
||
definitionUrl
.
FD
}
else
{
return
playList
}
})
onMounted
(()
=>
{
fetchInfo
()
...
...
@@ -29,8 +33,6 @@ onMounted(() => {
<
template
>
<el-dialog
title=
"查阅操作视频"
>
<AppVideoPlayer
:options=
"
{ fluid: true, sources: [{ src: playUrl, type: 'application/x-mpegURL' }] }"
v-if="playUrl">
</AppVideoPlayer>
<AppVideoPlayer
:options=
"
{ fluid: true, sources: [{ src: playUrl }] }" v-if="playUrl">
</AppVideoPlayer>
</el-dialog>
</
template
>
src/modules/admin/contest/items/types.ts
浏览文件 @
163b7c3d
...
...
@@ -109,6 +109,7 @@ export interface ContestVideoCreateParams {
status
:
string
duration
:
number
source_id
:
string
size
:
string
}
export
type
ContestVideoUpdateParams
=
ContestVideoCreateParams
&
{
id
:
string
}
src/modules/admin/lab/video/components/FormDialog.vue
浏览文件 @
163b7c3d
...
...
@@ -33,7 +33,8 @@ const form = reactive<VideoCreateItem>({
experiment_id
:
''
,
status
:
'1'
,
source_id
:
''
,
protocol
:
false
protocol
:
false
,
size
:
''
})
watchEffect
(()
=>
{
if
(
!
props
.
data
)
return
...
...
@@ -75,7 +76,8 @@ function handleBeforeUpload() {
function
handleUploadSuccess
(
uploadInfo
:
any
)
{
form
.
name
=
uploadInfo
.
file
.
name
.
split
(
'.'
).
shift
()
form
.
source_id
=
uploadInfo
.
videoId
form
.
source_id
=
uploadInfo
.
url
form
.
size
=
uploadInfo
.
file
.
size
}
// 提交
function
handleSubmit
()
{
...
...
src/modules/admin/lab/video/types.ts
浏览文件 @
163b7c3d
...
...
@@ -29,4 +29,5 @@ export interface VideoCreateItem {
name
:
string
source_id
:
string
protocol
:
boolean
size
:
string
}
src/modules/admin/lab/video/views/View.vue
浏览文件 @
163b7c3d
...
...
@@ -9,7 +9,7 @@ interface Props {
const
props
=
defineProps
<
Props
>
()
let
detail
=
$ref
<
VideoItem
|
null
>
(
null
)
let
playList
=
$ref
<
any
>
(
[]
)
let
playList
=
$ref
<
any
>
()
function
fetchInfo
()
{
if
(
!
props
.
id
)
return
...
...
@@ -19,14 +19,18 @@ function fetchInfo() {
})
}
const
playUrl
=
$computed
(()
=>
{
const
definitionUrl
=
playList
.
reduce
(
(
result
:
any
,
item
:
any
)
=>
{
result
[
item
.
Definition
]
=
item
.
PlayURL
return
result
},
{
SD
:
''
,
LD
:
''
,
FD
:
''
}
)
return
definitionUrl
.
SD
||
definitionUrl
.
LD
||
definitionUrl
.
FD
if
(
Array
.
isArray
(
playList
))
{
const
definitionUrl
=
playList
.
reduce
(
(
result
:
any
,
item
:
any
)
=>
{
result
[
item
.
Definition
]
=
item
.
PlayURL
return
result
},
{
SD
:
''
,
LD
:
''
,
FD
:
''
}
)
return
definitionUrl
.
SD
||
definitionUrl
.
LD
||
definitionUrl
.
FD
}
else
{
return
playList
}
})
onMounted
(()
=>
{
fetchInfo
()
...
...
@@ -47,9 +51,7 @@ onMounted(() => {
<el-descriptions-item
label=
"创建时间:"
>
{{
detail
.
created_time
}}
</el-descriptions-item>
</el-descriptions>
<div
style=
"height: 600px"
v-if=
"playUrl"
>
<AppVideoPlayer
:options=
"
{ sources: [{ src: playUrl, type: 'application/x-mpegURL' }] }"
style="width: 100%; height: 100%">
</AppVideoPlayer>
<AppVideoPlayer
:options=
"
{ sources: [{ src: playUrl }] }" style="width: 100%; height: 100%">
</AppVideoPlayer>
</div>
</
template
>
</AppCard>
...
...
src/modules/student/contest/components/VideoItem.vue
浏览文件 @
163b7c3d
<
script
setup
lang=
"ts"
>
import
type
{
ExperimentVideoType
,
PlayInfo
}
from
'../types'
import
type
{
ExperimentVideoType
}
from
'../types'
import
AppVideoPlayer
from
'@/components/base/AppVideoPlayer.vue'
import
{
getExperimentVideoPlayInfo
}
from
'../api'
...
...
@@ -11,7 +11,7 @@ interface Props {
data
:
ExperimentVideoType
}
const
props
=
defineProps
<
Props
>
()
let
playList
=
$ref
<
PlayInfo
[]
>
([]
)
let
playList
=
$ref
<
any
>
(
)
function
fetchInfo
()
{
getExperimentVideoPlayInfo
({
source_id
:
props
.
data
.
source_id
}).
then
(
res
=>
{
playList
=
res
.
data
.
list
.
play_info_list
...
...
@@ -28,14 +28,18 @@ function fetchInfo() {
})
}
const
playUrl
=
$computed
(()
=>
{
const
definitionUrl
=
playList
.
reduce
(
(
result
:
any
,
item
:
any
)
=>
{
result
[
item
.
Definition
]
=
item
.
PlayURL
return
result
},
{
SD
:
''
,
LD
:
''
,
FD
:
''
}
)
return
definitionUrl
.
SD
||
definitionUrl
.
LD
||
definitionUrl
.
FD
if
(
Array
.
isArray
(
playList
))
{
const
definitionUrl
=
playList
.
reduce
(
(
result
:
any
,
item
:
any
)
=>
{
result
[
item
.
Definition
]
=
item
.
PlayURL
return
result
},
{
SD
:
''
,
LD
:
''
,
FD
:
''
}
)
return
definitionUrl
.
SD
||
definitionUrl
.
LD
||
definitionUrl
.
FD
}
else
{
return
playList
}
})
onMounted
(()
=>
{
fetchInfo
()
...
...
@@ -46,9 +50,7 @@ onMounted(() => {
<h2>
{{
data
.
name
}}
</h2>
<!--
<img
:src=
"data.cover"
/>
-->
<div
style=
"height: 200px"
v-if=
"playUrl"
>
<AppVideoPlayer
:options=
"
{ sources: [{ src: playUrl, type: 'application/x-mpegURL' }] }"
style="width: 100%; height: 100%">
</AppVideoPlayer>
<AppVideoPlayer
:options=
"
{ sources: [{ src: playUrl, type: 'application/x-mpegURL' }] }" style="width: 100%; height: 100%">
</AppVideoPlayer>
</div>
</div>
</
template
>
...
...
src/modules/student/lab/components/VideoItem.vue
浏览文件 @
163b7c3d
<
script
setup
lang=
"ts"
>
import
type
{
ExperimentVideoType
,
PlayInfo
}
from
'../types'
import
type
{
ExperimentVideoType
,
}
from
'../types'
import
AppVideoPlayer
from
'@/components/base/AppVideoPlayer.vue'
import
{
getExperimentVideoPlayInfo
}
from
'../api'
...
...
@@ -12,7 +12,7 @@ interface Props {
data
:
ExperimentVideoType
}
const
props
=
defineProps
<
Props
>
()
let
playList
=
$ref
<
PlayInfo
[]
>
([]
)
let
playList
=
$ref
<
any
>
(
)
function
fetchInfo
()
{
getExperimentVideoPlayInfo
({
source_id
:
props
.
data
.
source_id
}).
then
(
res
=>
{
playList
=
res
.
data
.
play_info_list
...
...
@@ -29,14 +29,18 @@ function fetchInfo() {
})
}
const
playUrl
=
$computed
(()
=>
{
const
definitionUrl
=
playList
.
reduce
(
(
result
:
any
,
item
:
any
)
=>
{
result
[
item
.
Definition
]
=
item
.
PlayURL
return
result
},
{
SD
:
''
,
LD
:
''
,
FD
:
''
}
)
return
definitionUrl
.
SD
||
definitionUrl
.
LD
||
definitionUrl
.
FD
if
(
Array
.
isArray
(
playList
))
{
const
definitionUrl
=
playList
.
reduce
(
(
result
:
any
,
item
:
any
)
=>
{
result
[
item
.
Definition
]
=
item
.
PlayURL
return
result
},
{
SD
:
''
,
LD
:
''
,
FD
:
''
}
)
return
definitionUrl
.
SD
||
definitionUrl
.
LD
||
definitionUrl
.
FD
}
else
{
return
playList
}
})
onMounted
(()
=>
{
fetchInfo
()
...
...
@@ -47,9 +51,7 @@ onMounted(() => {
<h2>
{{
data
.
name
}}
</h2>
<!--
<img
:src=
"data.cover"
/>
-->
<div
style=
"height: 200px"
v-if=
"playUrl"
>
<AppVideoPlayer
:options=
"
{ sources: [{ src: playUrl, type: 'application/x-mpegURL' }] }"
style="width: 100%; height: 100%">
</AppVideoPlayer>
<AppVideoPlayer
:options=
"
{ sources: [{ src: playUrl }] }" style="width: 100%; height: 100%">
</AppVideoPlayer>
</div>
</div>
</
template
>
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论