Files
xiaoxia-saas/apps/api/app/schemas/lipsync.py
xiaoxia c954e334e6
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (push) Successful in 1s
CI/CD Pipeline / Check push changed paths (push) Successful in 5s
CI/CD Pipeline / Build Staging API Image (push) Successful in 16s
CI/CD Pipeline / Build Staging Worker Image (push) Successful in 1m12s
CI/CD Pipeline / Build Staging Web Image (push) Successful in 2m7s
CI/CD Pipeline / Integration Tests (push) Successful in 2m14s
CI/CD Pipeline / Validate - Python (mypy + alembic) (push) Successful in 2m48s
CI/CD Pipeline / Validate - Style (push) Successful in 2m49s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Successful in 1m43s
CI/CD Pipeline / Staging E2E Tests (push) Failing after 1m29s
CI/CD Pipeline / Validate - Security (push) Successful in 6m50s
CI/CD Pipeline / ACR Image Cleanup (push) Successful in 2m15s
CI/CD Pipeline / Frontend Unit Tests (push) Successful in 8m18s
CI/CD Pipeline / Staging API Integration Tests (push) Successful in 4m30s
CI/CD Pipeline / Unit Tests (push) Successful in 10m41s
CI/CD Pipeline / Production Browser E2E (push) Has been skipped
CI/CD Pipeline / Canary Release to Production (push) Failing after 173h1m45s
CI/CD Pipeline / Build Production Web Image (push) Failing after 173h1m47s
CI/CD Pipeline / Deploy Production (push) Failing after 173h1m45s
CI/CD Pipeline / Build Production API Image (push) Failing after 173h1m47s
CI/CD Pipeline / CI Gate (push) Failing after 173h1m47s
CI/CD Pipeline / Retag skipped Staging Worker Image (push) Failing after 173h10m15s
CI/CD Pipeline / Retag skipped Staging API Image (push) Failing after 173h10m16s
CI/CD Pipeline / Frontend Lint (push) Failing after 173h12m30s
CI/CD Pipeline / PR Build Web Image (push) Failing after 173h12m34s
CI/CD Pipeline / PR Build API Image (push) Failing after 173h12m35s
CI/CD Pipeline / Check if frontend-only change (push) Failing after 173h12m36s
CI/CD Pipeline / Build Production Worker Image (push) Failing after 173h36m33s
CI/CD Pipeline / Retag skipped Staging Web Image (push) Failing after 173h45m2s
CI/CD Pipeline / PR Build Worker Image (push) Failing after 173h47m20s
fix: #1809 对口型接口参数调整,后端内部调TTS合成音频 (#1814)
Co-authored-by: xiaoxia <dev@xiaoxiajianji.com>
Co-committed-by: xiaoxia <dev@xiaoxiajianji.com>
2026-09-09 10:11:27 +08:00

78 lines
2.3 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""对口型 API Schema 定义 — #1796, #1809 参数调整."""
from __future__ import annotations
from datetime import datetime
from typing import Optional
from pydantic import BaseModel, Field, field_validator
class LipsyncJobResponse(BaseModel):
"""对口型任务响应."""
id: str
user_id: str
project_id: str
video_url: str
audio_url: str
enable_video_loop: bool
mediakit_task_id: str
status: str
output_video_url: str
output_duration: float
error_message: str
error_code: str
submitted_at: Optional[datetime] = None
completed_at: Optional[datetime] = None
created_at: datetime
updated_at: datetime
class Config:
from_attributes = True
class CreateLipsyncJobRequest(BaseModel):
"""创建对口型任务请求 — #1809.
前端传 {voice_id, script_text, video_url},
后端内部调 TTS 生成 audio_url 再提交 MediaKit。
"""
video_url: str = Field(..., description="人物视频 URL(MP4,≤30min,单人真人)")
voice_id: str = Field(..., description="音色 ID(预设音色或克隆音色 profile ID)")
script_text: str = Field(..., description="要合成的脚本文本")
enable_video_loop: bool = Field(False, description="音频长于视频时是否循环画面")
project_id: str = Field("", description="项目 ID(可选)")
@field_validator("video_url")
@classmethod
def validate_video_url(cls, v: str) -> str:
v = v.strip()
if not v:
raise ValueError("video_url 不能为空")
if not v.startswith(("http://", "https://")):
raise ValueError("video_url 必须是 HTTP/HTTPS URL")
lower = v.lower().split("?")[0]
if not lower.endswith(".mp4"):
raise ValueError("video_url 仅支持 MP4 格式")
return v
@field_validator("voice_id")
@classmethod
def validate_voice_id(cls, v: str) -> str:
v = v.strip()
if not v:
raise ValueError("voice_id 不能为空")
return v
@field_validator("script_text")
@classmethod
def validate_script_text(cls, v: str) -> str:
v = v.strip()
if not v:
raise ValueError("script_text 不能为空")
if len(v) > 5000:
raise ValueError("script_text 最长 5000 字符")
return v