|
|
@@ -246,7 +246,7 @@
|
|
|
</el-select>
|
|
|
</el-form-item>
|
|
|
|
|
|
- <el-form-item label="上传视频" prop="videoUrl" required>
|
|
|
+ <el-form-item :label="currentCateType === 'audio' ? '上传音频' : '上传视频'" prop="videoUrl" required>
|
|
|
<el-upload
|
|
|
ref="videoUpload"
|
|
|
action="#"
|
|
|
@@ -254,14 +254,14 @@
|
|
|
:http-request="videoUpload"
|
|
|
:file-list="fileList"
|
|
|
:on-change="handleFileChange"
|
|
|
- accept=".mp4">
|
|
|
+ :accept="currentCateType === 'audio' ? '.mp3,.m4a,audio/*' : '.mp4'">
|
|
|
<i slot="default" class="el-icon-plus"></i>
|
|
|
<div slot="file" slot-scope="{file}">
|
|
|
<div
|
|
|
class="el-upload-list__item-thumbnail"
|
|
|
style="display: flex; justify-content: center; align-items: center; background-color: #f5f7fa; height: 146px;"
|
|
|
>
|
|
|
- <i class="el-icon-video-camera" style="font-size: 48px;" />
|
|
|
+ <i :class="currentCateType === 'audio' ? 'el-icon-microphone' : 'el-icon-video-camera'" style="font-size: 48px;" />
|
|
|
</div>
|
|
|
|
|
|
<span v-if="file.status === 'success'" class="el-upload-list__item-status-label">
|
|
|
@@ -326,6 +326,10 @@
|
|
|
</el-upload>
|
|
|
</el-form-item>
|
|
|
|
|
|
+ <el-form-item label="封面" prop="thumbnail" v-if="currentCateType === 'audio'">
|
|
|
+ <ImageUpload v-model="form.thumbnail" :limit="1" />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
<el-form-item label="时长">
|
|
|
<span>{{ formatDuration(form.duration) }}</span>
|
|
|
</el-form-item>
|
|
|
@@ -578,7 +582,7 @@
|
|
|
</el-select>
|
|
|
</el-form-item>
|
|
|
|
|
|
- <el-form-item label="上传视频" prop="files">
|
|
|
+ <el-form-item :label="currentCateType === 'audio' ? '上传音频' : '上传视频'" prop="files">
|
|
|
<el-upload
|
|
|
ref="batchVideoUpload"
|
|
|
action="#"
|
|
|
@@ -586,7 +590,7 @@
|
|
|
:file-list="batchFileList"
|
|
|
:on-change="handleBatchFileChange"
|
|
|
multiple
|
|
|
- accept=".mp4">
|
|
|
+ :accept="currentCateType === 'audio' ? '.mp3,.m4a,audio/*' : '.mp4'">
|
|
|
<el-button type="primary" :disabled="batchUploadForm.typeSubId === null">选择文件</el-button>
|
|
|
<div slot="tip" class="el-upload__tip">选择分类后才可以上传视频</div>
|
|
|
</el-upload>
|
|
|
@@ -866,6 +870,8 @@ export default {
|
|
|
typeList: [],
|
|
|
rootTypeList: [],
|
|
|
subTypeList: [],
|
|
|
+ // 当前选中一级分类类型:audio / video
|
|
|
+ currentCateType: 'video',
|
|
|
// 视频上传
|
|
|
videoDisabled: false,
|
|
|
videoPreviewVisible: false,
|
|
|
@@ -1163,6 +1169,9 @@ export default {
|
|
|
this.batchUploadForm.typeSubId = null
|
|
|
}
|
|
|
this.subTypeList = []
|
|
|
+ // 记录当前一级分类类型(1=音频 → audio,其余 → video)
|
|
|
+ const cur = this.rootTypeList.find(i => String(i.dictValue) === String(val))
|
|
|
+ this.currentCateType = cur && Number(cur.type) === 1 ? 'audio' : 'video'
|
|
|
if (!val) {
|
|
|
return
|
|
|
}
|
|
|
@@ -1422,7 +1431,9 @@ export default {
|
|
|
this.currentUploadProgress = { total: 0, line1: 0, line2: 0, line1Status: 'pending', line2Status: 'pending' };
|
|
|
|
|
|
try {
|
|
|
- await this.getFirstThumbnail(file, this.form);
|
|
|
+ if (this.currentCateType !== 'audio') {
|
|
|
+ await this.getFirstThumbnail(file, this.form);
|
|
|
+ }
|
|
|
const [line1Result, line2Result] = await Promise.allSettled([
|
|
|
this.uploadVideoToTxPcdn(file, this.form, options.onProgress),
|
|
|
// this.uploadVideoToHwObs(file, this.form, options.onProgress)
|
|
|
@@ -1465,13 +1476,14 @@ export default {
|
|
|
},
|
|
|
// 获取媒体文件时长
|
|
|
getMediaDuration(file) {
|
|
|
- // 处理视频
|
|
|
- const video = document.createElement('video');
|
|
|
- video.preload = 'metadata';
|
|
|
- video.onloadedmetadata = () => {
|
|
|
- this.form.duration = Math.round(video.duration);
|
|
|
+ // 处理媒体(音频/视频)
|
|
|
+ const isAudio = this.currentCateType === 'audio'
|
|
|
+ const media = document.createElement(isAudio ? 'audio' : 'video');
|
|
|
+ media.preload = 'metadata';
|
|
|
+ media.onloadedmetadata = () => {
|
|
|
+ this.form.duration = Math.round(media.duration);
|
|
|
};
|
|
|
- video.src = URL.createObjectURL(file);
|
|
|
+ media.src = URL.createObjectURL(file);
|
|
|
},
|
|
|
handleFileChange(file, files) {
|
|
|
// 保留最后一个文件
|
|
|
@@ -1767,16 +1779,16 @@ export default {
|
|
|
this.uploadQueue.push(tempVideo);
|
|
|
this.videoList.unshift(tempVideo);
|
|
|
|
|
|
- // 获取视频时长
|
|
|
- const video = document.createElement('video');
|
|
|
- video.preload = 'metadata';
|
|
|
- video.onloadedmetadata = () => {
|
|
|
+ // 获取媒体时长
|
|
|
+ const media = document.createElement(this.currentCateType === 'audio' ? 'audio' : 'video');
|
|
|
+ media.preload = 'metadata';
|
|
|
+ media.onloadedmetadata = () => {
|
|
|
const index = this.videoList.findIndex(item => item.tempId === tempVideo.tempId);
|
|
|
if (index !== -1) {
|
|
|
- tempVideo.duration = Math.round(video.duration);
|
|
|
+ tempVideo.duration = Math.round(media.duration);
|
|
|
}
|
|
|
};
|
|
|
- video.src = URL.createObjectURL(file);
|
|
|
+ media.src = URL.createObjectURL(file);
|
|
|
|
|
|
// 关闭上传弹窗
|
|
|
this.showUpload = false;
|
|
|
@@ -1836,8 +1848,10 @@ export default {
|
|
|
|
|
|
async uploadSingleVideo(tempVideo) {
|
|
|
try {
|
|
|
- // 获取封面
|
|
|
- await this.getFirstThumbnail(tempVideo.file, tempVideo);
|
|
|
+ // 获取封面(音频无首帧,跳过)
|
|
|
+ if (this.currentCateType !== 'audio') {
|
|
|
+ await this.getFirstThumbnail(tempVideo.file, tempVideo);
|
|
|
+ }
|
|
|
|
|
|
// 并行上传到两个服务器
|
|
|
const [line1Result, line2Result] = await Promise.allSettled([
|
|
|
@@ -2124,93 +2138,6 @@ export default {
|
|
|
});
|
|
|
},
|
|
|
|
|
|
- /** 删除视频 */
|
|
|
- handleDeleteVideo(row) {
|
|
|
- if (row.uploadStatus === 'uploading') {
|
|
|
- this.$confirm('该视频正在上传中,确认要取消上传并删除吗?', '取消上传', {
|
|
|
- confirmButtonText: '确定取消',
|
|
|
- cancelButtonText: '继续上传',
|
|
|
- type: 'warning'
|
|
|
- }).then(() => {
|
|
|
- // Cancel the upload and remove from list
|
|
|
- this.cancelVideoUpload(row);
|
|
|
- }).catch(() => {
|
|
|
- // User chose to continue uploading
|
|
|
- this.$message.info('继续上传该视频');
|
|
|
- });
|
|
|
- } else {
|
|
|
- // Original confirmation for non-uploading videos
|
|
|
- this.$confirm('确认要从列表中删除该视频吗?', '提示', {
|
|
|
- confirmButtonText: '确定',
|
|
|
- cancelButtonText: '取消',
|
|
|
- type: 'warning'
|
|
|
- }).then(() => {
|
|
|
- this.removeVideoFromList(row);
|
|
|
- }).catch(() => {
|
|
|
- // 取消删除
|
|
|
- });
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- cancelVideoUpload(row) {
|
|
|
- const cancellationTokens = this.uploadCancellationTokens.get(row.tempId);
|
|
|
- if (cancellationTokens) {
|
|
|
- // Cancel COS upload if exists
|
|
|
- if (cancellationTokens.cos) {
|
|
|
- try {
|
|
|
- cancellationTokens.cos();
|
|
|
- console.log('COS upload cancelled for video:', row.tempId);
|
|
|
- } catch (error) {
|
|
|
- console.error('Error cancelling COS upload:', error);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // Cancel OBS upload if exists
|
|
|
- if (cancellationTokens.obs) {
|
|
|
- try {
|
|
|
- cancellationTokens.obs();
|
|
|
- console.log('OBS upload cancelled for video:', row.tempId);
|
|
|
- } catch (error) {
|
|
|
- console.error('Error cancelling OBS upload:', error);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // Remove cancellation tokens
|
|
|
- this.uploadCancellationTokens.delete(row.tempId);
|
|
|
- }
|
|
|
-
|
|
|
- const videoIndex = this.videoList.findIndex(item => item.tempId === row.tempId);
|
|
|
- if (videoIndex !== -1) {
|
|
|
- this.videoList[videoIndex].uploadStatus = 'cancelled';
|
|
|
- this.videoList.splice(videoIndex, 1);
|
|
|
- }
|
|
|
-
|
|
|
- const queueIndex = this.uploadQueue.findIndex(item => item.tempId === row.tempId);
|
|
|
- if (queueIndex !== -1) {
|
|
|
- this.uploadQueue.splice(queueIndex, 1);
|
|
|
- this.updateQueuePositions();
|
|
|
- }
|
|
|
-
|
|
|
- this.$message.success('已取消视频上传并从列表中移除');
|
|
|
- },
|
|
|
-
|
|
|
- removeVideoFromList(row) {
|
|
|
- const videoIndex = this.videoList.findIndex(item => item.tempId === row.tempId);
|
|
|
- if (videoIndex !== -1) {
|
|
|
- this.videoList.splice(videoIndex, 1);
|
|
|
- }
|
|
|
-
|
|
|
- // Remove from upload queue if it's still queued
|
|
|
- const queueIndex = this.uploadQueue.findIndex(item => item.tempId === row.tempId);
|
|
|
- if (queueIndex !== -1) {
|
|
|
- this.uploadQueue.splice(queueIndex, 1);
|
|
|
- this.updateQueuePositions();
|
|
|
- this.$message.success('已从上传队列中移除该视频');
|
|
|
- } else {
|
|
|
- this.$message.success('已从列表中移除该视频');
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
getUploadStatusText(status, queuePosition) {
|
|
|
switch (status) {
|
|
|
case 'success':
|
|
|
@@ -2538,21 +2465,6 @@ export default {
|
|
|
default: return '#909399';
|
|
|
}
|
|
|
},
|
|
|
- // 获取上传状态文本
|
|
|
- getUploadStatusText(status, queuePosition) {
|
|
|
- switch (status) {
|
|
|
- case 'success':
|
|
|
- return '上传成功';
|
|
|
- case 'failed':
|
|
|
- return '上传失败';
|
|
|
- case 'uploading':
|
|
|
- return '上传中';
|
|
|
- case 'queued':
|
|
|
- return `队列中 (第${queuePosition}位)`;
|
|
|
- default:
|
|
|
- return '待上传';
|
|
|
- }
|
|
|
- },
|
|
|
// 获取线路状态图标
|
|
|
getLineStatusIcon(status) {
|
|
|
switch (status) {
|