Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
C
center-resource
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
EzijingWeb
center-resource
Commits
b074c5fd
提交
b074c5fd
authored
1月 09, 2024
作者:
王鹏飞
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
chore: 修改视频上传
上级
a567b70d
隐藏空白字符变更
内嵌
并排
正在显示
8 个修改的文件
包含
197 行增加
和
315 行删除
+197
-315
base.ts
src/api/base.ts
+15
-5
useUpload.ts
src/composables/useUpload.ts
+119
-0
UploadMultipleVideo.vue
...modules/resource/video/components/UploadMultipleVideo.vue
+21
-127
UploadVideo.vue
src/modules/resource/video/components/UploadVideo.vue
+24
-144
VideoDetail.vue
src/modules/resource/video/components/VideoDetail.vue
+3
-24
ViewCenter.vue
src/modules/resource/video/components/ViewCenter.vue
+7
-8
BatchUpload.vue
src/modules/resource/video/views/BatchUpload.vue
+4
-4
Update.vue
src/modules/resource/video/views/Update.vue
+4
-3
没有找到文件。
src/api/base.ts
浏览文件 @
b074c5fd
...
@@ -75,9 +75,19 @@ export function checkLocalFile(params: { file_name: string }) {
...
@@ -75,9 +75,19 @@ 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
})
{
export
function
uploadLocalFile
(
return
httpRequest
.
post
(
'/api/lab/v1/common/file/upload'
,
data
,
{
data
:
{
file
:
File
|
Blob
;
file_name
:
string
;
is_continuingly
?:
number
;
now_package_num
:
number
;
total_package_num
:
number
},
withCredentials
:
false
,
options
=
{}
headers
:
{
'Content-Type'
:
'multipart/form-data'
}
)
{
})
return
httpRequest
.
post
(
'/api/lab/v1/common/file/upload'
,
data
,
Object
.
assign
(
{
withCredentials
:
false
,
headers
:
{
'Content-Type'
:
'multipart/form-data'
}
},
options
)
)
}
}
src/composables/useUpload.ts
0 → 100644
浏览文件 @
b074c5fd
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
})
{
if
(
event
.
lengthComputable
)
{
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
)
}
}
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/resource/video/components/UploadMultipleVideo.vue
浏览文件 @
b074c5fd
<
script
setup
lang=
"ts"
>
<
script
setup
lang=
"ts"
>
import
VideoDetail
from
'./VideoDetail.vue'
import
VideoDetail
from
'./VideoDetail.vue'
import
{
getCreateAuth
,
updateAuth
}
from
'@/api/base'
import
{
CircleClose
}
from
'@element-plus/icons-vue'
import
{
CircleClose
}
from
'@element-plus/icons-vue'
const
idShowMore
=
ref
(
false
)
import
{
useUpload
}
from
'@/composables/useUpload'
// uploadInfo 包含要上传的文件信息
const
idShowMore
=
ref
(
false
)
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
}
const
emit
=
defineEmits
([
'upload'
,
'canClose'
])
const
emit
=
defineEmits
([
'upload'
,
'canClose'
])
let
uploader
=
createUploader
()
const
{
files
,
addFile
,
cancelUpload
}
=
useUpload
({
let
fileList
=
$ref
<
UploadInfo
[]
>
([])
multiple
:
true
,
onUploadSucceed
(
file
)
{
emit
(
'upload'
,
file
)
}
})
const
fileChange
=
(
event
:
Event
)
=>
{
const
fileChange
=
(
event
:
Event
)
=>
{
const
element
=
event
.
currentTarget
as
HTMLInputElement
const
element
=
event
.
currentTarget
as
HTMLInputElement
let
files
:
FileList
|
null
=
element
.
files
let
files
:
FileList
|
null
=
element
.
files
if
(
!
files
)
return
if
(
!
files
)
return
for
(
const
file
of
files
)
{
for
(
const
file
of
files
)
{
// 是否重复上传
addFile
(
file
)
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":{}}'
)
}
}
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
[
'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
)
getCreateAuth
({
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
)
emit
(
'canClose'
,
{
closeStatus
:
false
})
}
// 文件上传成功
function
onUploadSucceed
(
uploadInfo
:
UploadInfo
)
{
console
.
log
(
'onUploadSucceed'
,
uploadInfo
)
updateFileList
(
uploadInfo
)
emit
(
'upload'
,
uploadInfo
)
}
//文件上传失败
function
onUploadFailed
(
uploadInfo
:
UploadInfo
,
code
:
number
,
message
:
string
)
{
console
.
log
(
uploadInfo
,
'111111'
)
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
)
updateAuth
({
source_id
:
uploadInfo
.
videoId
}).
then
(
res
=>
{
uploader
.
resumeUploadWithAuth
(
res
.
data
.
UploadAuth
)
})
updateFileList
(
uploadInfo
)
}
// 全部文件上传结束
function
onUploadEnd
(
uploadInfo
:
UploadInfo
)
{
console
.
log
(
'onUploadEnd'
,
uploadInfo
)
updateFileList
(
uploadInfo
)
emit
(
'canClose'
,
{
closeStatus
:
true
})
}
}
const
handleView
=
()
=>
{
const
handleView
=
()
=>
{
idShowMore
.
value
=
true
idShowMore
.
value
=
true
}
}
// 进度条
function
percentage
(
value
:
number
)
{
return
parseFloat
((
value
?
value
*
100
:
0
).
toFixed
(
2
))
}
// 删除上传文件
// 删除上传文件
const
deleteFile
=
function
(
index
:
number
)
{
const
deleteFile
=
function
(
index
:
number
,
item
:
any
)
{
console
.
log
(
index
,
'deleteFile'
,
fileList
)
console
.
log
(
index
,
'deleteFile'
,
files
)
fileList
.
splice
(
index
,
1
)
cancelUpload
(
item
)
uploader
.
deleteFile
(
index
)
}
}
defineExpose
({
uploader
,
fileList
:
$$
(
fileList
)
})
defineExpose
({
files
:
$$
(
files
)
})
</
script
>
</
script
>
<
template
>
<
template
>
<div
class=
"upload-video"
style=
"display: flex; flex-direction: column; align-items: flex-start"
>
<div
class=
"upload-video"
style=
"display: flex; flex-direction: column; align-items: flex-start"
>
...
@@ -146,19 +40,19 @@ defineExpose({ uploader, fileList: $$(fileList) })
...
@@ -146,19 +40,19 @@ defineExpose({ uploader, fileList: $$(fileList) })
<input
accept=
".mp4"
type=
"file"
id=
"fileUpload"
multiple
@
change=
"fileChange"
/>
<input
accept=
".mp4"
type=
"file"
id=
"fileUpload"
multiple
@
change=
"fileChange"
/>
</div>
</div>
<div
class=
"tips"
>
推荐视频格式:帧率为25fps\输出码率为4M\输出格式为mp4,建议采用格式工厂等工具处理后上传。
</div>
<div
class=
"tips"
>
推荐视频格式:帧率为25fps\输出码率为4M\输出格式为mp4,建议采用格式工厂等工具处理后上传。
</div>
<div
v-for=
"(item, index) in file
List
.slice(0, 3)"
:key=
"index"
>
<div
v-for=
"(item, index) in file
s
.slice(0, 3)"
:key=
"index"
>
<div
class=
"video-info"
>
<div
class=
"video-info"
>
<span
class=
"name"
>
{{
item
.
file
?.
name
}}
</span>
<span
class=
"name"
>
{{
item
.
name
}}
</span>
<el-progress
style=
"width: 200px"
:percentage=
"
percentage(item.loaded)
"
class=
"view"
/>
<el-progress
style=
"width: 200px"
:percentage=
"
item.progress
"
class=
"view"
/>
<div
v-if=
"
percentage(item.loaded)
== 100"
>
上传成功
</div>
<div
v-if=
"
item.progress
== 100"
>
上传成功
</div>
<el-icon
v-else
@
click=
"deleteFile(index)"
><CircleClose
/></el-icon>
<el-icon
v-else
@
click=
"deleteFile(index
, item
)"
><CircleClose
/></el-icon>
</div>
</div>
</div>
</div>
<el-link
style=
"padding-top: 3px"
:underline=
"false"
type=
"primary"
v-if=
"file
List
.length > 3"
@
click=
"handleView"
<el-link
style=
"padding-top: 3px"
:underline=
"false"
type=
"primary"
v-if=
"file
s
.length > 3"
@
click=
"handleView"
>
共
{{
file
List
.
length
}}
个文件,查看更多
</el-link
>
共
{{
file
s
.
length
}}
个文件,查看更多
</el-link
>
>
</div>
</div>
<VideoDetail
:videoList=
"file
List
"
v-model:modelValue=
"idShowMore"
v-if=
"idShowMore === true"
/>
<VideoDetail
:videoList=
"file
s
"
v-model:modelValue=
"idShowMore"
v-if=
"idShowMore === true"
/>
</
template
>
</
template
>
<
style
lang=
"scss"
>
<
style
lang=
"scss"
>
.demo-progress
{
.demo-progress
{
...
...
src/modules/resource/video/components/UploadVideo.vue
浏览文件 @
b074c5fd
<
script
setup
lang=
"ts"
>
<
script
setup
lang=
"ts"
>
import
{
getCreateAuth
,
updateAuth
}
from
'@/api/base'
import
{
ElMessage
}
from
'element-plus'
import
{
ElMessage
}
from
'element-plus'
/**
import
{
useUpload
}
from
'@/composables/useUpload'
* upload 上传状态 {code: -1(待上传)0(成功) 1(开始上传) 2(上传失败), msg: '上传信息'}
* progress 上传进度
**/
interface
IUpload
{
code
:
number
name
?:
string
msg
?:
string
progress
?:
number
videoId
?:
string
}
let
uploadData
=
$ref
<
IUpload
>
({
code
:
-
1
})
const
emit
=
defineEmits
([
'upload'
])
const
emit
=
defineEmits
([
'upload'
])
const
form
:
any
=
reactive
({
timeout
:
''
,
const
{
files
,
uploading
,
addFile
}
=
useUpload
({
partSize
:
''
,
onUploadSucceed
(
file
)
{
parallel
:
''
,
emit
(
'upload'
,
file
)
retryCount
:
''
,
}
retryDuration
:
''
,
region
:
'cn-shanghai'
,
userId
:
'1303984639806000'
,
file
:
null
,
authProgress
:
0
,
uploader
:
null
,
statusText
:
''
})
})
const
fileChange
=
(
e
:
any
)
=>
{
const
file
=
computed
(()
=>
{
form
.
file
=
e
.
target
.
files
[
0
]
return
files
.
value
[
0
]
if
(
form
.
file
.
name
.
indexOf
(
'.mp4'
)
===
-
1
)
{
})
const
fileChange
=
async
(
event
:
Event
)
=>
{
const
element
=
event
.
currentTarget
as
HTMLInputElement
const
files
=
element
.
files
if
(
!
files
)
return
const
[
file
]
=
files
if
(
file
.
name
.
indexOf
(
'.mp4'
)
===
-
1
)
{
ElMessage
(
'请上传mp4格式视频'
)
ElMessage
(
'请上传mp4格式视频'
)
return
return
}
}
var
userData
=
'{"Vod":{}}'
addFile
(
file
)
if
(
form
.
uploader
)
{
form
.
uploader
.
stopUpload
()
form
.
authProgress
=
0
form
.
statusText
=
''
}
form
.
uploader
=
createUploader
()
form
.
uploader
.
addFile
(
form
.
file
,
null
,
null
,
null
,
userData
)
form
.
uploader
.
startUpload
()
}
const
createUploader
:
any
=
()
=>
{
const
w
=
window
as
any
const
uploader
=
new
w
.
AliyunUpload
.
Vod
({
timeout
:
form
.
timeout
||
60000
,
partSize
:
form
.
partSize
||
1048576
,
parallel
:
form
.
parallel
||
5
,
retryCount
:
form
.
retryCount
||
3
,
retryDuration
:
form
.
retryDuration
||
2
,
region
:
form
.
region
,
userId
:
form
.
userId
,
// 开始上传
onUploadstarted
:
function
(
uploadInfo
:
any
)
{
const
fileData
=
JSON
.
parse
(
window
.
localStorage
.
fileData
||
'{}'
)
// 判断有没有上传过
const
isFile
=
!!
fileData
.
sourceId
if
(
!
isFile
)
{
// 没上传过请求凭证上传
getCreateAuth
({
title
:
uploadInfo
.
file
.
name
,
file_name
:
uploadInfo
.
file
.
name
}).
then
((
data
:
any
)
=>
{
window
.
localStorage
.
fileData
=
JSON
.
stringify
({
uploadAuth
:
data
.
data
.
upload_auth
,
uploadAddress
:
data
.
data
.
upload_address
,
videoId
:
data
.
data
.
source_id
,
fileName
:
uploadInfo
.
file
.
name
,
fileSize
:
uploadInfo
.
file
.
size
})
uploader
.
setUploadAuthAndAddress
(
uploadInfo
,
data
.
data
.
upload_auth
,
data
.
data
.
upload_address
,
data
.
data
.
source_id
)
})
}
else
{
// 上传过判断一下上次上传的文件和本次上传的文件一不一样,一样的话继续上传
if
(
fileData
.
fileName
===
uploadInfo
.
file
.
name
&&
fileData
.
fileSize
===
uploadInfo
.
file
.
size
)
{
uploader
.
setUploadAuthAndAddress
(
uploadInfo
,
fileData
.
uploadAuth
,
fileData
.
uploadAddress
,
fileData
.
videoId
)
}
else
{
getCreateAuth
({
title
:
uploadInfo
.
file
.
name
,
file_name
:
uploadInfo
.
file
.
name
}).
then
((
data
:
any
)
=>
{
uploader
.
setUploadAuthAndAddress
(
uploadInfo
,
data
.
data
.
upload_auth
,
data
.
data
.
upload_address
,
data
.
data
.
source_id
)
})
}
}
uploadData
=
{
code
:
1
,
name
:
uploadInfo
.
file
.
name
,
msg
:
'开始上传'
}
},
// 文件上传成功
onUploadSucceed
:
function
(
uploadInfo
:
any
)
{
const
fileData
=
window
.
localStorage
.
fileData
?
JSON
.
parse
(
window
.
localStorage
.
fileData
)
:
{}
uploadData
=
{
code
:
0
,
name
:
uploadInfo
.
file
.
name
,
videoId
:
fileData
.
videoId
,
msg
:
'上传成功'
}
emit
(
'upload'
,
{
videoId
:
fileData
.
videoId
,
name
:
uploadInfo
.
file
.
name
})
},
// 文件上传失败
// code:any, message:any
onUploadFailed
:
function
(
uploadInfo
:
any
)
{
uploadData
=
{
code
:
2
,
name
:
uploadInfo
.
file
.
name
,
msg
:
'文件上传失败'
}
},
// 文件上传进度,单位:字节, 可以在这个函数中拿到上传进度并显示在页面上
onUploadProgress
:
function
(
uploadInfo
:
any
,
totalSize
:
any
,
progress
:
any
)
{
let
progressPercent
=
Math
.
ceil
(
progress
*
100
)
form
.
authProgress
=
progressPercent
uploadData
.
progress
=
progressPercent
},
// 上传凭证超时
onUploadTokenExpired
:
function
(
uploadInfo
:
any
)
{
const
fileData
=
JSON
.
parse
(
window
.
localStorage
.
fileData
||
'{}'
)
updateAuth
({
source_id
:
fileData
.
videoId
}).
then
(({
data
})
=>
{
let
uploadAuth
=
data
.
UploadAuth
window
.
localStorage
.
fileData
=
JSON
.
stringify
({
uploadAuth
:
data
.
data
.
upload_auth
,
uploadAddress
:
data
.
data
.
upload_address
,
videoId
:
data
.
data
.
source_id
,
fileName
:
uploadInfo
.
file
.
name
,
fileSize
:
uploadInfo
.
file
.
size
})
uploader
.
resumeUploadWithAuth
(
uploadAuth
)
})
}
})
return
uploader
}
}
</
script
>
</
script
>
<
template
>
<
template
>
...
@@ -148,18 +30,16 @@ const createUploader: any = () => {
...
@@ -148,18 +30,16 @@ const createUploader: any = () => {
<div
class=
"upload-video"
>
<div
class=
"upload-video"
>
<div
class=
"upload-btn"
>
<div
class=
"upload-btn"
>
本地文件
本地文件
<!-- accept=".mp4" -->
<input
accept=
".mp4"
type=
"file"
id=
"fileUpload"
@
change=
"fileChange"
/>
<input
accept=
".mp4"
type=
"file"
id=
"fileUpload"
@
change=
"fileChange($event)"
/>
</div>
</div>
<div
class=
"demo-progress"
v-if=
"uploadData.code === 1"
>
<div
class=
"demo-progress"
v-if=
"uploading"
>
<el-progress
style=
"width: 340px"
:percentage=
"uploadData.progress"
/>
<el-progress
style=
"width: 340px"
:percentage=
"file.progress"
/>
<!--
<span>
{{
uploadData
.
progress
}}
%
</span>
-->
</div>
</div>
<div
class=
"error video-info"
v-if=
"uploadData.code === 2"
>
<
!--
<
div
class=
"error video-info"
v-if=
"uploadData.code === 2"
>
<div
class=
"name"
>
上传失败(请重新选择文件进行上传)
</div>
<div
class=
"name"
>
上传失败(请重新选择文件进行上传)
</div>
</div>
</div>
-->
<div
class=
"video-info"
v-
if=
"uploadData.code === 0"
>
<div
class=
"video-info"
v-
else
>
<div
class=
"name"
>
{{
uploadData
.
name
}}
</div>
<div
class=
"name"
>
{{
file
?
.
name
}}
</div>
</div>
</div>
</div>
</div>
<div
class=
"tips"
>
推荐视频格式:帧率为25fps\输出码率为4M\输出格式为mp4,建议采用格式工厂等工具处理后上传。
</div>
<div
class=
"tips"
>
推荐视频格式:帧率为25fps\输出码率为4M\输出格式为mp4,建议采用格式工厂等工具处理后上传。
</div>
...
...
src/modules/resource/video/components/VideoDetail.vue
浏览文件 @
b074c5fd
<
script
lang=
"ts"
setup
>
<
script
lang=
"ts"
setup
>
interface
UploadInfo
{
interface
UploadInfo
{
bucket
:
string
checkpoint
:
{
file
:
File
;
name
:
string
;
fileSize
:
number
;
partSize
:
number
;
uploadId
:
string
}
endpoint
:
string
file
:
File
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
progress
:
number
}
}
interface
Props
{
interface
Props
{
...
@@ -40,19 +26,13 @@ const handleSizeChange = (val: any) => {
...
@@ -40,19 +26,13 @@ const handleSizeChange = (val: any) => {
const
handleCurrentChange
=
(
val
:
any
)
=>
{
const
handleCurrentChange
=
(
val
:
any
)
=>
{
page
.
currentPage
=
val
page
.
currentPage
=
val
}
}
function
percentage
(
value
:
number
)
{
return
parseFloat
((
value
?
value
*
100
:
0
).
toFixed
(
2
))
}
</
script
>
</
script
>
<
template
>
<
template
>
<el-dialog
:model-value=
"props.modelValue"
title=
"更多视频文件"
:before-close=
"handleCancel"
width=
"30vw"
>
<el-dialog
:model-value=
"props.modelValue"
title=
"更多视频文件"
:before-close=
"handleCancel"
width=
"30vw"
>
<div
<div
v-for=
"(item, index) in props.videoList.slice((page.currentPage - 1) * page.size, page.currentPage * page.size)"
:key=
"index"
>
v-for=
"(item, index) in props.videoList.slice((page.currentPage - 1) * page.size, page.currentPage * page.size)"
:key=
"index"
>
<div
class=
"video-info"
>
<div
class=
"video-info"
>
<span
class=
"name"
>
{{
item
.
file
?.
name
}}
</span>
<span
class=
"name"
>
{{
item
.
file
?.
name
}}
</span>
<el-progress
style=
"width: 200px"
:percentage=
"
percentage(item.loaded)
"
class=
"view"
/>
<el-progress
style=
"width: 200px"
:percentage=
"
item.progress
"
class=
"view"
/>
</div>
</div>
</div>
</div>
<el-pagination
<el-pagination
...
@@ -62,8 +42,7 @@ function percentage(value: number) {
...
@@ -62,8 +42,7 @@ function percentage(value: number) {
:page-sizes=
"[5, 10, 20, 30, 50]"
:page-sizes=
"[5, 10, 20, 30, 50]"
:total=
"props.videoList.length"
:total=
"props.videoList.length"
@
size-change=
"handleSizeChange"
@
size-change=
"handleSizeChange"
@
current-change=
"handleCurrentChange"
@
current-change=
"handleCurrentChange"
>
>
</el-pagination>
</el-pagination>
</el-dialog>
</el-dialog>
</
template
>
</
template
>
...
...
src/modules/resource/video/components/ViewCenter.vue
浏览文件 @
b074c5fd
...
@@ -2,15 +2,14 @@
...
@@ -2,15 +2,14 @@
import
AppVideoPlayer
from
'@/components/base/AppVideoPlayer.vue'
import
AppVideoPlayer
from
'@/components/base/AppVideoPlayer.vue'
const
props
=
defineProps
([
'data'
])
const
props
=
defineProps
([
'data'
])
const
videoOptions
=
$computed
(()
=>
{
const
videoOptions
=
$computed
(()
=>
{
return
{
const
playInfoList
=
props
.
data
.
play_auth
.
play_info_list
sources
:
[
let
src
=
''
{
if
(
Array
.
isArray
(
playInfoList
))
{
src
:
props
.
data
.
play_auth
.
play_info_list
.
find
((
item
:
any
)
=>
{
src
=
playInfoList
.
find
((
item
:
any
)
=>
item
.
Definition
===
'SD'
)?.
PlayURL
return
item
.
Definition
===
'SD'
}
else
{
}).
PlayURL
src
=
playInfoList
}
]
}
}
return
{
sources
:
[{
src
}]
}
})
})
</
script
>
</
script
>
<
template
>
<
template
>
...
...
src/modules/resource/video/views/BatchUpload.vue
浏览文件 @
b074c5fd
...
@@ -39,13 +39,14 @@ const uploadMultipleVideoRef = $ref<InstanceType<typeof UploadMultipleVideo> | n
...
@@ -39,13 +39,14 @@ const uploadMultipleVideoRef = $ref<InstanceType<typeof UploadMultipleVideo> | n
// }
// }
// 上传视频成功
// 上传视频成功
const
uploadVideo
=
(
data
:
any
)
=>
{
const
uploadVideo
=
(
data
:
any
)
=>
{
const
{
file
,
videoId
}
=
data
const
{
file
}
=
data
const
params
=
{
const
params
=
{
name
:
file
.
name
.
slice
(
0
,
file
.
name
.
lastIndexOf
(
'.'
)),
name
:
file
.
name
.
slice
(
0
,
file
.
name
.
lastIndexOf
(
'.'
)),
source
:
'2'
,
source
:
'2'
,
classification
:
form
.
classification
,
classification
:
form
.
classification
,
knowledge_points
:
''
,
knowledge_points
:
''
,
source_id
:
videoId
,
source_id
:
data
.
url
,
size
:
file
.
size
,
cover
:
''
cover
:
''
}
}
createVideo
(
params
).
then
(()
=>
{
createVideo
(
params
).
then
(()
=>
{
...
@@ -71,8 +72,7 @@ const goBack = function () {
...
@@ -71,8 +72,7 @@ const goBack = function () {
:data=
"selectTree"
:data=
"selectTree"
clearable
clearable
placeholder=
"视频分类"
placeholder=
"视频分类"
:default-expanded-keys=
"selectTree.length ? [selectTree[0]?.id] : []"
:default-expanded-keys=
"selectTree.length ? [selectTree[0]?.id] : []"
/>
/>
</el-form-item>
</el-form-item>
<el-form-item
label=
"视频文件"
prop=
"source_id"
v-if=
"form.classification !== ''"
>
<el-form-item
label=
"视频文件"
prop=
"source_id"
v-if=
"form.classification !== ''"
>
<UploadMultipleVideo
@
upload=
"uploadVideo"
@
canClose=
"handleClose"
ref=
"uploadMultipleVideoRef"
/>
<UploadMultipleVideo
@
upload=
"uploadVideo"
@
canClose=
"handleClose"
ref=
"uploadMultipleVideoRef"
/>
...
...
src/modules/resource/video/views/Update.vue
浏览文件 @
b074c5fd
...
@@ -60,7 +60,7 @@ const swiperItemHandle = (url: string) => {
...
@@ -60,7 +60,7 @@ const swiperItemHandle = (url: string) => {
// form表单
// form表单
let
form
=
reactive
({
let
form
=
reactive
({
data
:
{
name
:
''
,
source
:
'2'
,
classification
:
''
,
knowledge_points
:
''
,
cover
:
''
,
source_id
:
''
}
data
:
{
name
:
''
,
source
:
'2'
,
classification
:
''
,
knowledge_points
:
''
,
cover
:
''
,
source_id
:
''
,
size
:
''
}
})
})
// 表单验证
// 表单验证
const
rules
=
{
const
rules
=
{
...
@@ -139,7 +139,8 @@ const protocol = ref(false)
...
@@ -139,7 +139,8 @@ const protocol = ref(false)
// 上传视频成功
// 上传视频成功
const
uploadVideo
=
(
data
:
any
)
=>
{
const
uploadVideo
=
(
data
:
any
)
=>
{
form
.
data
.
source_id
=
data
.
videoId
form
.
data
.
source_id
=
data
.
url
form
.
data
.
size
=
data
.
file
.
size
const
name
=
data
.
name
const
name
=
data
.
name
form
.
data
.
name
=
name
.
slice
(
0
,
name
.
lastIndexOf
(
'.'
))
form
.
data
.
name
=
name
.
slice
(
0
,
name
.
lastIndexOf
(
'.'
))
}
}
...
@@ -192,7 +193,7 @@ const changeProtocol = (data: any) => {
...
@@ -192,7 +193,7 @@ const changeProtocol = (data: any) => {
<el-icon
:size=
"50"
color=
"#ccc"
v-if=
"form.data.cover == ''"
>
<el-icon
:size=
"50"
color=
"#ccc"
v-if=
"form.data.cover == ''"
>
<PictureFilled></PictureFilled>
<PictureFilled></PictureFilled>
</el-icon>
</el-icon>
<div
v-else
class=
"cover-img"
:style=
"`background-image:url(
$
{form.data.cover}
)`">
</div>
<div
v-else
class=
"cover-img"
:style=
"`background-image:url(
'$
{form.data.cover}'
)`">
</div>
</div>
</div>
<div
class=
"video-cover_right"
>
<div
class=
"video-cover_right"
>
<UploadImg
accept=
".jpg,.jpeg,.gif,.png"
v-model=
"form.data.cover"
></UploadImg>
<UploadImg
accept=
".jpg,.jpeg,.gif,.png"
v-model=
"form.data.cover"
></UploadImg>
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论