refactor: 清理未使用IPC命令、修正point_service注释与扣费逻辑、修复camelToSnake正则、优化vidu import
- 删除8个未使用IPC命令,保留validate_media_path - file.rs返回类型优化为ApiResponse<()> - point_service.consume()注释与签名一致 - VideoGeneration改为拼接成功后扣费 - 添加漏扣费风险注释 - 删除过时测试文件 - 修复camelToSnake连续大写字母问题 - vidu.py import移至模块顶层 Refs: P1-1~P1-6 技术债务清理
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
火山引擎音视频字幕 API 路由
|
||||
============================
|
||||
|
||||
提供字幕生成、自动打轴等功能。
|
||||
提供自动字幕打轴功能。
|
||||
"""
|
||||
|
||||
import logging
|
||||
@@ -11,12 +11,7 @@ from fastapi import APIRouter, HTTPException, Request
|
||||
|
||||
from app.core.exceptions import PlatformError
|
||||
from app.schemas.caption import (
|
||||
AutoAlignResult,
|
||||
AutoAlignSubmitRequest,
|
||||
CaptionResult,
|
||||
CaptionSubmitRequest,
|
||||
CaptionTaskResponse,
|
||||
SrtSubtitleResponse,
|
||||
)
|
||||
from app.schemas.common import ApiResponse, success_response
|
||||
from app.services.volcengine_caption_service import (
|
||||
@@ -28,229 +23,17 @@ logger = logging.getLogger(__name__)
|
||||
router = APIRouter(prefix="/caption", tags=["Caption"])
|
||||
|
||||
|
||||
@router.post("/submit", response_model=ApiResponse[CaptionTaskResponse])
|
||||
async def submit_caption_task(request_body: CaptionSubmitRequest, request: Request):
|
||||
"""
|
||||
提交字幕生成任务
|
||||
|
||||
提交音频/视频文件URL,生成带时间轴的字幕。
|
||||
"""
|
||||
try:
|
||||
service = await get_caption_service(request)
|
||||
task_id = await service.submit_caption_task(
|
||||
audio_url=request_body.audio_url,
|
||||
language=request_body.language,
|
||||
caption_type=request_body.caption_type,
|
||||
use_punc=request_body.use_punc,
|
||||
use_itn=request_body.use_itn,
|
||||
words_per_line=request_body.words_per_line,
|
||||
max_lines=request_body.max_lines,
|
||||
)
|
||||
|
||||
return success_response(
|
||||
data=CaptionTaskResponse(
|
||||
task_id=task_id,
|
||||
status="pending",
|
||||
),
|
||||
message="字幕任务已提交",
|
||||
)
|
||||
|
||||
except PlatformError as e:
|
||||
logger.error(f"提交字幕任务失败: {e}")
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error(f"提交字幕任务异常: {e}")
|
||||
raise HTTPException(status_code=500, detail="字幕任务提交失败,请稍后重试")
|
||||
|
||||
|
||||
@router.get("/query/{task_id}", response_model=ApiResponse[CaptionResult])
|
||||
async def query_caption_task(task_id: str, request: Request, blocking: bool = True):
|
||||
"""
|
||||
查询字幕任务结果
|
||||
|
||||
Args:
|
||||
task_id: 任务ID
|
||||
blocking: 是否阻塞等待结果 (默认True)
|
||||
"""
|
||||
try:
|
||||
service = await get_caption_service(request)
|
||||
result = await service.query_caption_task(task_id, blocking=blocking)
|
||||
|
||||
return success_response(data=result)
|
||||
|
||||
except PlatformError as e:
|
||||
logger.error(f"查询字幕任务失败: {e}")
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error(f"查询字幕任务异常: {e}")
|
||||
raise HTTPException(status_code=500, detail="查询字幕任务失败,请稍后重试")
|
||||
|
||||
|
||||
@router.post("/generate", response_model=ApiResponse[CaptionResult])
|
||||
async def generate_caption(request_body: CaptionSubmitRequest, request: Request, max_wait_time: int = 120):
|
||||
"""
|
||||
生成字幕(完整流程)
|
||||
|
||||
提交任务并轮询结果,直接返回最终字幕数据。
|
||||
适用于不需要异步处理的场景。
|
||||
"""
|
||||
try:
|
||||
service = await get_caption_service(request)
|
||||
result = await service.generate_caption(
|
||||
audio_url=request_body.audio_url,
|
||||
language=request_body.language,
|
||||
caption_type=request_body.caption_type,
|
||||
use_punc=request_body.use_punc,
|
||||
use_itn=request_body.use_itn,
|
||||
words_per_line=request_body.words_per_line,
|
||||
max_lines=request_body.max_lines,
|
||||
max_wait_time=max_wait_time,
|
||||
)
|
||||
|
||||
return success_response(data=result)
|
||||
|
||||
except PlatformError as e:
|
||||
logger.error(f"生成字幕失败: {e}")
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error(f"生成字幕异常: {e}")
|
||||
raise HTTPException(status_code=500, detail="字幕生成失败,请稍后重试")
|
||||
|
||||
|
||||
@router.post("/generate-ass", response_model=ApiResponse[dict])
|
||||
async def generate_ass(
|
||||
request_body: CaptionSubmitRequest,
|
||||
request: Request,
|
||||
video_width: int = 1080,
|
||||
video_height: int = 1920,
|
||||
max_wait_time: int = 120,
|
||||
):
|
||||
"""
|
||||
生成 ASS 格式字幕(完整流程,使用抖音美好体)
|
||||
|
||||
Args:
|
||||
video_width: 视频宽度(默认 1080)
|
||||
video_height: 视频高度(默认 1920)
|
||||
"""
|
||||
try:
|
||||
service = await get_caption_service(request)
|
||||
result = await service.generate_caption(
|
||||
audio_url=request_body.audio_url,
|
||||
language=request_body.language,
|
||||
caption_type=request_body.caption_type,
|
||||
use_punc=request_body.use_punc,
|
||||
use_itn=request_body.use_itn,
|
||||
words_per_line=request_body.words_per_line,
|
||||
max_lines=request_body.max_lines,
|
||||
max_wait_time=max_wait_time,
|
||||
)
|
||||
|
||||
ass_content = service.to_ass(
|
||||
result.utterances,
|
||||
video_width=video_width,
|
||||
video_height=video_height,
|
||||
)
|
||||
|
||||
return success_response(
|
||||
data={
|
||||
"ass_content": ass_content,
|
||||
"utterances": result.utterances,
|
||||
"duration": result.duration,
|
||||
"font": "DouyinSansBold",
|
||||
}
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"生成ASS字幕失败: {e}")
|
||||
raise HTTPException(status_code=500, detail="字幕生成失败,请稍后重试")
|
||||
|
||||
|
||||
@router.post("/generate-srt", response_model=ApiResponse[SrtSubtitleResponse])
|
||||
async def generate_srt(request_body: CaptionSubmitRequest, request: Request, max_wait_time: int = 120):
|
||||
"""
|
||||
生成 SRT 格式字幕(完整流程)
|
||||
|
||||
直接返回 SRT 格式字幕文件内容。
|
||||
"""
|
||||
try:
|
||||
service = await get_caption_service(request)
|
||||
result = await service.generate_caption(
|
||||
audio_url=request_body.audio_url,
|
||||
language=request_body.language,
|
||||
caption_type=request_body.caption_type,
|
||||
use_punc=request_body.use_punc,
|
||||
use_itn=request_body.use_itn,
|
||||
words_per_line=request_body.words_per_line,
|
||||
max_lines=request_body.max_lines,
|
||||
max_wait_time=max_wait_time,
|
||||
)
|
||||
|
||||
srt_content = service.to_srt(result.utterances)
|
||||
|
||||
return success_response(
|
||||
data=SrtSubtitleResponse(
|
||||
srt_content=srt_content,
|
||||
utterances=result.utterances,
|
||||
)
|
||||
)
|
||||
|
||||
except PlatformError as e:
|
||||
logger.error(f"生成SRT字幕失败: {e}")
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error(f"生成SRT字幕异常: {e}")
|
||||
raise HTTPException(status_code=500, detail="字幕生成失败,请稍后重试")
|
||||
|
||||
|
||||
@router.post("/ata/submit", response_model=ApiResponse[CaptionTaskResponse])
|
||||
async def submit_auto_align_task(request_body: AutoAlignSubmitRequest, request: Request):
|
||||
"""
|
||||
提交自动字幕打轴任务
|
||||
|
||||
为已有字幕文本自动配上时间轴。
|
||||
"""
|
||||
try:
|
||||
service = await get_caption_service(request)
|
||||
task_id = await service.submit_auto_align_task(
|
||||
audio_url=request_body.audio_url,
|
||||
audio_text=request_body.audio_text,
|
||||
caption_type=request_body.caption_type,
|
||||
sta_punc_mode=request_body.sta_punc_mode,
|
||||
)
|
||||
|
||||
return success_response(
|
||||
data=CaptionTaskResponse(
|
||||
task_id=task_id,
|
||||
status="pending",
|
||||
),
|
||||
message="打轴任务已提交",
|
||||
)
|
||||
|
||||
except PlatformError as e:
|
||||
logger.error(f"提交打轴任务失败: {e}")
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error(f"提交打轴任务异常: {e}")
|
||||
raise HTTPException(status_code=500, detail="打轴任务提交失败,请稍后重试")
|
||||
|
||||
|
||||
@router.get("/ata/query/{task_id}", response_model=ApiResponse[AutoAlignResult])
|
||||
async def query_auto_align_task(task_id: str, request: Request, blocking: bool = True):
|
||||
"""
|
||||
查询打轴任务结果
|
||||
"""
|
||||
try:
|
||||
service = await get_caption_service(request)
|
||||
result = await service.query_auto_align_task(task_id, blocking=blocking)
|
||||
|
||||
return success_response(data=result)
|
||||
|
||||
except PlatformError as e:
|
||||
logger.error(f"查询打轴任务失败: {e}")
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error(f"查询打轴任务异常: {e}")
|
||||
raise HTTPException(status_code=500, detail="查询打轴任务失败,请稍后重试")
|
||||
|
||||
|
||||
@router.post("/ata/align")
|
||||
@@ -301,72 +84,7 @@ async def auto_align_caption(request_body: AutoAlignSubmitRequest, request: Requ
|
||||
raise HTTPException(status_code=500, detail="字幕打轴失败,请稍后重试")
|
||||
|
||||
|
||||
@router.post("/convert/ass", response_model=ApiResponse[dict])
|
||||
async def convert_to_ass(
|
||||
result: CaptionResult,
|
||||
video_width: int = 1080,
|
||||
video_height: int = 1920,
|
||||
):
|
||||
"""
|
||||
将字幕结果转换为 ASS 格式(使用抖音美好体)
|
||||
"""
|
||||
try:
|
||||
ass_content = VolcengineCaptionService.to_ass(
|
||||
result.utterances,
|
||||
video_width=video_width,
|
||||
video_height=video_height,
|
||||
)
|
||||
|
||||
return success_response(
|
||||
data={
|
||||
"ass_content": ass_content,
|
||||
"font": "DouyinSansBold",
|
||||
"utterances_count": len(result.utterances),
|
||||
}
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"转换ASS失败: {e}")
|
||||
raise HTTPException(status_code=500, detail="字幕格式转换失败,请稍后重试")
|
||||
|
||||
|
||||
@router.post("/convert/srt", response_model=ApiResponse[dict])
|
||||
async def convert_to_srt(result: CaptionResult):
|
||||
"""
|
||||
将字幕结果转换为 SRT 格式
|
||||
|
||||
用于将 /generate 返回的原始数据转换为 SRT 格式。
|
||||
"""
|
||||
try:
|
||||
srt_content = VolcengineCaptionService.to_srt(result.utterances)
|
||||
|
||||
return success_response(
|
||||
data={
|
||||
"srt_content": srt_content,
|
||||
"utterances_count": len(result.utterances),
|
||||
}
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"转换SRT失败: {e}")
|
||||
raise HTTPException(status_code=500, detail="字幕格式转换失败,请稍后重试")
|
||||
|
||||
|
||||
@router.post("/convert/vtt", response_model=ApiResponse[dict])
|
||||
async def convert_to_vtt(result: CaptionResult):
|
||||
"""
|
||||
将字幕结果转换为 WebVTT 格式
|
||||
"""
|
||||
try:
|
||||
vtt_content = VolcengineCaptionService.to_vtt(result.utterances)
|
||||
|
||||
return success_response(
|
||||
data={
|
||||
"vtt_content": vtt_content,
|
||||
"utterances_count": len(result.utterances),
|
||||
}
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"转换VTT失败: {e}")
|
||||
raise HTTPException(status_code=500, detail="字幕格式转换失败,请稍后重试")
|
||||
|
||||
Reference in New Issue
Block a user