diff --git a/apps/api/app/services/ai_avatar_render_service.py b/apps/api/app/services/ai_avatar_render_service.py index 21266333b..0688e05d8 100644 --- a/apps/api/app/services/ai_avatar_render_service.py +++ b/apps/api/app/services/ai_avatar_render_service.py @@ -322,6 +322,37 @@ class AiAvatarRenderService: self.db.commit() logger.info("渲染任务完成: %s", job_id) + # 7. 自动保存成片记录到成片库 + if job.output_video_url: + try: + from packages.domain.generated_video import GeneratedVideo + from packages.adapters.sqlalchemy_impl.generated_video_repository import ( + SQLAlchemyGeneratedVideoRepository, + ) + + clip_name = f"AI数字人_{job_id[:8]}" + clip = GeneratedVideo.create( + project_id=job.project_id, + generation_task_id=job.lipsync_job_id, + name=clip_name, + file_url=job.output_video_url, + user_id=job.user_id, + duration=job.output_duration or 0.0, + thumbnail_url=job.output_cover_url or None, + generation_params={ + "source": "ai_avatar_render", + "render_job_id": job.id, + }, + ) + video_repo = SQLAlchemyGeneratedVideoRepository(self.db) + video_repo.create(clip) + logger.info("成片记录已保存到成片库: clip_id=%s, render_job=%s", clip.id, job_id) + except Exception as clip_err: + logger.warning( + "自动保存成片记录失败(不影响渲染任务状态): render_job=%s, error=%s", + job_id, clip_err, + ) + except AiAvatarRenderError as exc: job.status = "failed" job.error_message = str(exc) @@ -376,7 +407,7 @@ class AiAvatarRenderService: else: filter_arg = "" - return f"ffmpeg {inputs} {filter_arg} -c:v libx264 -preset fast -crf 23 -y {output_path}" + return f"ffmpeg {inputs} {filter_arg} -c:v libx264 -preset veryfast -crf 23 -y {output_path}" def _upload_to_oss(self, local_path: str, oss_key: str) -> str: """上传文件到 OSS,返回 URL.