diff --git a/src/api/video-synthesis.js b/src/api/video-synthesis.js index 066e5d6..6ca9b07 100644 --- a/src/api/video-synthesis.js +++ b/src/api/video-synthesis.js @@ -42,3 +42,12 @@ export function getVideoSynthesisStatus(taskId) { method: 'get' }) } + +// 播放视频 +export function playVideo(minioPath, expires = 900) { + return request({ + url: `/video-synthesis/play/${minioPath}`, + method: 'get', + params: { expires } + }) +} diff --git a/src/views/video/avatar-synthesis.vue b/src/views/video/avatar-synthesis.vue index 74e2308..a120742 100644 --- a/src/views/video/avatar-synthesis.vue +++ b/src/views/video/avatar-synthesis.vue @@ -114,8 +114,12 @@ - - + @@ -243,7 +247,28 @@ export default { ] }, imageOptions: [], - audioOptions: [] + audioOptions: [], + selectedImageModel: '' // 存储选中头像的模型名 + } + }, + computed: { + // 根据选中头像的模型名动态计算模型供应商选项 + modelProviderOptions() { + if (this.selectedImageModel === 'emo-detect-v1') { + return [ + { label: 'emo-v1', value: 'emo-v1' } + ] + } else if (this.selectedImageModel === 'liveportrait-detect') { + return [ + { label: 'liveportrait', value: 'liveportrait' } + ] + } else { + // 默认选项 + return [ + { label: 'dashscope', value: 'dashscope' }, + { label: '其他', value: 'other' } + ] + } } }, mounted() { @@ -272,7 +297,8 @@ export default { url: item.imageUrl, avatarName: item.avatarName, ownerName: item.ownerName, - ownerPhone: item.ownerPhone + ownerPhone: item.ownerPhone, + modelName: item.modelName || item.model || '' // 获取模型名信息 })) console.log('Image options set:', this.imageOptions) } else if (response && response.success === false) { @@ -280,18 +306,18 @@ export default { this.$message.error(`获取头像列表失败: ${response.message || '未知错误'}`) // 使用模拟数据 this.imageOptions = [ - { id: 'img-001', name: '头像1', url: 'http://example.com/images/avatar1.jpg', ownerName: '张三', ownerPhone: '13800138000' }, - { id: 'img-002', name: '头像2', url: 'http://example.com/images/avatar2.jpg', ownerName: '李四', ownerPhone: '13900139000' }, - { id: 'img-003', name: '头像3', url: 'http://example.com/images/avatar3.jpg', ownerName: '王五', ownerPhone: '13700137000' } + { id: 'img-001', name: '头像1', url: 'http://example.com/images/avatar1.jpg', ownerName: '张三', ownerPhone: '13800138000', modelName: 'emo-detect-v1' }, + { id: 'img-002', name: '头像2', url: 'http://example.com/images/avatar2.jpg', ownerName: '李四', ownerPhone: '13900139000', modelName: 'liveportrait-detect' }, + { id: 'img-003', name: '头像3', url: 'http://example.com/images/avatar3.jpg', ownerName: '王五', ownerPhone: '13700137000', modelName: 'other-model' } ] } else { console.error('Unexpected face detect response format:', response) this.$message.error('获取头像列表失败: 响应数据格式不正确') // 使用模拟数据 this.imageOptions = [ - { id: 'img-001', name: '头像1', url: 'http://example.com/images/avatar1.jpg', ownerName: '张三', ownerPhone: '13800138000' }, - { id: 'img-002', name: '头像2', url: 'http://example.com/images/avatar2.jpg', ownerName: '李四', ownerPhone: '13900139000' }, - { id: 'img-003', name: '头像3', url: 'http://example.com/images/avatar3.jpg', ownerName: '王五', ownerPhone: '13700137000' } + { id: 'img-001', name: '头像1', url: 'http://example.com/images/avatar1.jpg', ownerName: '张三', ownerPhone: '13800138000', modelName: 'emo-detect-v1' }, + { id: 'img-002', name: '头像2', url: 'http://example.com/images/avatar2.jpg', ownerName: '李四', ownerPhone: '13900139000', modelName: 'liveportrait-detect' }, + { id: 'img-003', name: '头像3', url: 'http://example.com/images/avatar3.jpg', ownerName: '王五', ownerPhone: '13700137000', modelName: 'other-model' } ] } }).catch(error => { @@ -300,9 +326,9 @@ export default { this.$message.error(`网络请求失败: ${error.message || '请检查网络连接'}`) // 开发环境使用模拟数据 this.imageOptions = [ - { id: 'img-001', name: '头像1', url: 'http://example.com/images/avatar1.jpg', ownerName: '张三', ownerPhone: '13800138000' }, - { id: 'img-002', name: '头像2', url: 'http://example.com/images/avatar2.jpg', ownerName: '李四', ownerPhone: '13900139000' }, - { id: 'img-003', name: '头像3', url: 'http://example.com/images/avatar3.jpg', ownerName: '王五', ownerPhone: '13700137000' } + { id: 'img-001', name: '头像1', url: 'http://example.com/images/avatar1.jpg', ownerName: '张三', ownerPhone: '13800138000', modelName: 'emo-detect-v1' }, + { id: 'img-002', name: '头像2', url: 'http://example.com/images/avatar2.jpg', ownerName: '李四', ownerPhone: '13900139000', modelName: 'liveportrait-detect' }, + { id: 'img-003', name: '头像3', url: 'http://example.com/images/avatar3.jpg', ownerName: '王五', ownerPhone: '13700137000', modelName: 'other-model' } ] }) }, @@ -374,6 +400,19 @@ export default { if (selectedImage.ownerPhone) { this.form.ownerPhone = selectedImage.ownerPhone } + + // 获取头像的模型名信息 + this.selectedImageModel = selectedImage.modelName || '' + + // 根据模型名自动设置模型供应商 + if (this.selectedImageModel === 'emo-detect-v1') { + this.form.modelProvider = 'emo-v1' + } else if (this.selectedImageModel === 'liveportrait-detect') { + this.form.modelProvider = 'liveportrait' + } else { + // 默认设置 + this.form.modelProvider = 'dashscope' + } } }, @@ -442,6 +481,8 @@ export default { pasteBack: true, headMoveStrength: 0.7 } + // 重置选中的头像模型 + this.selectedImageModel = '' }, // 返回 diff --git a/src/views/video/face-detect.vue b/src/views/video/face-detect.vue index a087e05..90fa560 100644 --- a/src/views/video/face-detect.vue +++ b/src/views/video/face-detect.vue @@ -441,6 +441,7 @@ export default { const formData = new FormData() formData.append('file', file) formData.append('type', 'avatar') + formData.append('model', this.uploadForm.model || 'liveportrait-detect') formData.append('avatarName', this.uploadForm.avatarName || '') formData.append('ownerName', this.uploadForm.ownerName || '') formData.append('ownerPhone', this.uploadForm.ownerPhone || '') @@ -448,6 +449,7 @@ export default { console.log('FormData内容:', { file: file.name, type: 'avatar', + model: this.uploadForm.model, avatarName: this.uploadForm.avatarName, ownerName: this.uploadForm.ownerName, ownerPhone: this.uploadForm.ownerPhone @@ -465,6 +467,7 @@ export default { // 调用检测API const requestData = { imageUrl: imageUrl, + model: this.uploadForm.model || 'liveportrait-detect', ownerName: this.uploadForm.ownerName || '', ownerPhone: this.uploadForm.ownerPhone || '', avatarName: this.uploadForm.avatarName || '' @@ -601,6 +604,7 @@ export default { // 调用检测API const requestData = { imageUrl: imageUrl, + model: this.uploadForm.model || 'liveportrait-detect', ownerName: this.uploadForm.ownerName || '', ownerPhone: this.uploadForm.ownerPhone || '', avatarName: this.uploadForm.avatarName || '' @@ -625,6 +629,7 @@ export default { // 使用文件URL调用检测API const requestData = { imageUrl: fileUrl, + model: this.uploadForm.model || 'liveportrait-detect', ownerName: this.uploadForm.ownerName || '', ownerPhone: this.uploadForm.ownerPhone || '', avatarName: this.uploadForm.avatarName || '' @@ -944,15 +949,18 @@ export default { this.detectLoading = true const requestData = { imageUrl: this.detectForm.imageUrl, + model: this.detectForm.model || 'liveportrait-detect', ownerName: this.detectForm.ownerName, ownerPhone: this.detectForm.ownerPhone, avatarName: this.detectForm.avatarName } console.log('头像检测请求参数:', requestData) console.log('头像检测参数验证:', { + hasModel: !!requestData.model, hasOwnerName: !!requestData.ownerName, hasOwnerPhone: !!requestData.ownerPhone, hasAvatarName: !!requestData.avatarName, + modelValue: requestData.model, ownerNameValue: requestData.ownerName, ownerPhoneValue: requestData.ownerPhone, avatarNameValue: requestData.avatarName diff --git a/src/views/video/video-synthesis.vue b/src/views/video/video-synthesis.vue index 86d9a1f..8baf8c0 100644 --- a/src/views/video/video-synthesis.vue +++ b/src/views/video/video-synthesis.vue @@ -97,9 +97,17 @@ - + @@ -243,6 +251,40 @@ 关闭 + + + +
+
+

视频名称: {{ currentRecord.videoName }}

+

视频时长: {{ currentRecord.videoDuration }}秒

+

视频比例: {{ currentRecord.videoRatio }}

+
+
+ +
+ +

正在加载视频...

+
+
+
+ +
@@ -259,6 +301,9 @@ export default { selectedIds: [], detailVisible: false, currentRecord: null, + playVisible: false, + currentVideoUrl: '', + playLoading: false, // 查询参数 queryParams: { pageNum: 1, @@ -409,6 +454,32 @@ export default { // 头像合成视频 handleAvatarSynthesis() { this.$router.push('/video/avatar-synthesis') + }, + + // 播放视频 + handlePlay(row) { + // 直接使用videoTempUrl,无需调用后端接口 + const videoUrl = row.videoTempUrl || row.videoUrl + + if (!videoUrl) { + this.$message.warning('视频链接不存在,无法播放') + return + } + + this.playLoading = true + this.currentRecord = row + this.currentVideoUrl = videoUrl + this.playVisible = true + this.playLoading = false + this.$message.success('视频加载成功') + }, + + // 关闭播放对话框 + handlePlayClose() { + this.playVisible = false + this.currentVideoUrl = '' + this.currentRecord = null + this.playLoading = false } } } @@ -449,4 +520,43 @@ export default { color: #303133; flex: 1; } + +.play-content { + padding: 20px 0; +} + +.video-info { + margin-bottom: 20px; + padding: 15px; + background-color: #f5f7fa; + border-radius: 4px; +} + +.video-info p { + margin: 8px 0; + font-size: 14px; + color: #606266; +} + +.video-player { + text-align: center; + min-height: 200px; + display: flex; + align-items: center; + justify-content: center; +} + +.loading-placeholder { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + color: #909399; + font-size: 14px; +} + +.loading-placeholder i { + font-size: 24px; + margin-bottom: 10px; +}