Files
sionrui/frontend/app/web-gold/src/api/kling.js

124 lines
3.0 KiB
JavaScript
Raw Normal View History

2025-12-01 22:27:50 +08:00
/**
* 可灵数字人 API
*/
import request from './http'
import { MaterialService } from './material'
2026-02-04 01:18:16 +08:00
// ========== 辅助函数 ==========
2025-12-01 22:27:50 +08:00
/**
2026-02-04 01:18:16 +08:00
* 从视频中提取封面可选操作
2025-12-01 22:27:50 +08:00
*/
2026-02-04 01:18:16 +08:00
async function extractVideoCoverOptional(file) {
try {
const { extractVideoCover } = await import('@/utils/video-cover')
const cover = await extractVideoCover(file, {
maxWidth: 800,
quality: 0.8
})
return cover.base64
} catch {
return null
}
}
/**
2026-02-04 01:18:16 +08:00
* 执行人脸识别并返回结果
*/
2026-02-04 01:18:16 +08:00
async function performFaceIdentification(videoUrl) {
const identifyRes = await identifyFace({ video_url: videoUrl })
if (identifyRes.code !== 0) {
throw new Error(identifyRes.msg || '识别失败')
}
const faceData = identifyRes.data.data?.face_data?.[0]
return {
sessionId: identifyRes.data.sessionId,
faceId: faceData?.face_id || null,
startTime: faceData?.start_time || 0,
endTime: faceData?.end_time || 0
}
}
/**
* 构建标准响应格式
*/
function buildIdentifyResponse(fileId, videoUrl, identifyData, isUploadedFile = false) {
return {
success: true,
data: {
fileId,
videoUrl,
sessionId: identifyData.sessionId,
faceId: identifyData.faceId,
startTime: isUploadedFile
? Math.round(identifyData.startTime * 1000)
: identifyData.startTime,
endTime: isUploadedFile
? Math.round(identifyData.endTime * 1000)
: identifyData.endTime
}
}
}
// ========== API 方法 ==========
2025-12-01 22:27:50 +08:00
export function identifyFace(data) {
return request({
url: '/webApi/api/tik/kling/identify-face',
method: 'post',
data
})
}
export function createLipSyncTask(data) {
return request({
2025-12-02 01:55:57 +08:00
url: '/webApi/api/tik/kling/task/create',
2025-12-01 22:27:50 +08:00
method: 'post',
data
})
}
export function getLipSyncTask(taskId) {
return request({
url: `/webApi/api/tik/kling/lip-sync/${taskId}`,
method: 'get'
})
}
2026-02-04 01:18:16 +08:00
/**
* 识别已上传的视频
*/
export async function identifyUploadedVideo(videoFile) {
2026-02-24 23:58:17 +08:00
const urlRes = await MaterialService.getVideoPlayUrl(videoFile.fileId)
if (urlRes.code !== 0 || !urlRes.data) {
throw new Error(urlRes.msg || '获取播放链接失败')
}
2026-02-24 23:58:17 +08:00
const identifyData = await performFaceIdentification(urlRes.data)
return buildIdentifyResponse(videoFile.id, urlRes.data, identifyData, false)
}
2026-02-04 01:18:16 +08:00
/**
* 上传视频并识别
*/
export async function uploadAndIdentifyVideo(file) {
2026-02-04 01:18:16 +08:00
const coverBase64 = await extractVideoCoverOptional(file)
2025-12-01 22:27:50 +08:00
2026-02-24 23:58:17 +08:00
const uploadRes = await MaterialService.uploadFile(file, 'digital_human', coverBase64, null, null)
if (uploadRes.code !== 0) {
throw new Error(uploadRes.msg || '上传失败')
}
2025-12-01 22:27:50 +08:00
2026-02-24 23:58:17 +08:00
const fileId = uploadRes.data
2026-02-24 23:58:17 +08:00
const urlRes = await MaterialService.getVideoPlayUrl(fileId)
if (urlRes.code !== 0) {
throw new Error(urlRes.msg || '获取播放链接失败')
2025-12-01 22:27:50 +08:00
}
2026-02-24 23:58:17 +08:00
const identifyData = await performFaceIdentification(urlRes.data)
return buildIdentifyResponse(fileId, urlRes.data, identifyData, true)
2025-12-01 22:27:50 +08:00
}
2026-02-04 01:18:16 +08:00