124 lines
3.0 KiB
JavaScript
124 lines
3.0 KiB
JavaScript
/**
|
|
* 可灵数字人 API
|
|
*/
|
|
import request from './http'
|
|
import { MaterialService } from './material'
|
|
|
|
// ========== 辅助函数 ==========
|
|
|
|
/**
|
|
* 从视频中提取封面(可选操作)
|
|
*/
|
|
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
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 执行人脸识别并返回结果
|
|
*/
|
|
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 方法 ==========
|
|
|
|
export function identifyFace(data) {
|
|
return request({
|
|
url: '/webApi/api/tik/kling/identify-face',
|
|
method: 'post',
|
|
data
|
|
})
|
|
}
|
|
|
|
export function createLipSyncTask(data) {
|
|
return request({
|
|
url: '/webApi/api/tik/kling/task/create',
|
|
method: 'post',
|
|
data
|
|
})
|
|
}
|
|
|
|
export function getLipSyncTask(taskId) {
|
|
return request({
|
|
url: `/webApi/api/tik/kling/lip-sync/${taskId}`,
|
|
method: 'get'
|
|
})
|
|
}
|
|
|
|
/**
|
|
* 识别已上传的视频
|
|
*/
|
|
export async function identifyUploadedVideo(videoFile) {
|
|
const urlRes = await MaterialService.getVideoPlayUrl(videoFile.fileId)
|
|
if (urlRes.code !== 0 || !urlRes.data) {
|
|
throw new Error(urlRes.msg || '获取播放链接失败')
|
|
}
|
|
|
|
const identifyData = await performFaceIdentification(urlRes.data)
|
|
return buildIdentifyResponse(videoFile.id, urlRes.data, identifyData, false)
|
|
}
|
|
|
|
/**
|
|
* 上传视频并识别
|
|
*/
|
|
export async function uploadAndIdentifyVideo(file) {
|
|
const coverBase64 = await extractVideoCoverOptional(file)
|
|
|
|
const uploadRes = await MaterialService.uploadFile(file, 'digital_human', coverBase64, null, null)
|
|
if (uploadRes.code !== 0) {
|
|
throw new Error(uploadRes.msg || '上传失败')
|
|
}
|
|
|
|
const fileId = uploadRes.data
|
|
|
|
const urlRes = await MaterialService.getVideoPlayUrl(fileId)
|
|
if (urlRes.code !== 0) {
|
|
throw new Error(urlRes.msg || '获取播放链接失败')
|
|
}
|
|
|
|
const identifyData = await performFaceIdentification(urlRes.data)
|
|
return buildIdentifyResponse(fileId, urlRes.data, identifyData, true)
|
|
}
|
|
|