a59e3cc155
CI/CD Pipeline / Check if frontend-only change (push) Has been cancelled
CI/CD Pipeline / Validate - Code Quality (push) Has been cancelled
CI/CD Pipeline / Validate - Type Check (mypy) (push) Has been cancelled
CI/CD Pipeline / Validate - Migration (alembic) (push) Has been cancelled
CI/CD Pipeline / Unit Tests (push) Has been cancelled
CI/CD Pipeline / Integration Tests (push) Has been cancelled
CI/CD Pipeline / Frontend Lint (push) Has been cancelled
CI/CD Pipeline / Frontend Unit Tests (push) Has been cancelled
CI/CD Pipeline / PR Build API Image (push) Has been cancelled
CI/CD Pipeline / PR Build Web Image (push) Has been cancelled
CI/CD Pipeline / PR Build Worker Image (push) Has been cancelled
CI/CD Pipeline / Build Staging API Image (push) Has been cancelled
CI/CD Pipeline / Build Staging Web Image (push) Has been cancelled
CI/CD Pipeline / Build Staging Worker Image (push) Has been cancelled
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Has been cancelled
CI/CD Pipeline / Staging E2E Tests (push) Has been cancelled
CI/CD Pipeline / Staging API Integration Tests (push) Has been cancelled
CI/CD Pipeline / Build Production API Image (push) Has been cancelled
CI/CD Pipeline / Build Production Web Image (push) Has been cancelled
CI/CD Pipeline / Build Production Worker Image (push) Has been cancelled
CI/CD Pipeline / Deploy Production (push) Has been cancelled
CI/CD Pipeline / Production Browser E2E (push) Has been cancelled
CI/CD Pipeline / ACR Image Cleanup (push) Has been cancelled
CI/CD Pipeline / Canary Release to Production (push) Has been cancelled
CI/CD Pipeline / CI Gate (push) Has been cancelled
31 lines
922 B
TypeScript
31 lines
922 B
TypeScript
/**
|
|
* 音色克隆工具函数
|
|
*/
|
|
import type { VoiceCloneProfile, VoiceClone } from "./types"
|
|
|
|
/**
|
|
* 将后端 VoiceCloneProfile 转换为前端 VoiceClone
|
|
* 后端 status "pending" 映射为前端 "processing"
|
|
*/
|
|
export const toVoiceClone = (profile: VoiceCloneProfile): VoiceClone => ({
|
|
id: profile.id,
|
|
name: profile.name,
|
|
description: profile.description || "",
|
|
duration_seconds: 0,
|
|
status: profile.status === "pending" ? "processing" : profile.status,
|
|
progress: 0,
|
|
sample_url: profile.source_audio_url || undefined,
|
|
language: profile.language || "",
|
|
gender: profile.gender || "",
|
|
error_message: profile.error_message || null,
|
|
created_at: profile.created_at,
|
|
updated_at: profile.updated_at,
|
|
})
|
|
|
|
/** 格式化时长 */
|
|
export const formatDuration = (seconds: number): string => {
|
|
const m = Math.floor(seconds / 60)
|
|
const s = seconds % 60
|
|
return `${m}:${String(s).padStart(2, "0")}`
|
|
}
|