feat: #1970 hflip 按 atom_clip ai_tags.has_text 放开 + 清理重复 081 migration
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 2m44s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m37s
AI Code Review / AI Code Review (pull_request) Has been cancelled
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 2m34s
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 2s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 2s
CI/CD Pipeline / Check push changed paths (pull_request) Has been skipped
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / PR Build Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 26s
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 1m39s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 4m7s
CI/CD Pipeline / Validate - Style (pull_request) Failing after 4m43s
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Successful in 4m58s
CI/CD Pipeline / Validate - Security (pull_request) Successful in 11m18s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 11m37s
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / CI Gate (pull_request) Failing after 1s
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped

- render_adapter 按非 audio 源片段顺序批量查 atom_clip.ai_tags,
  仅 has_text 显式 false 标记无文字,其余(未打标签/true/null/查询失败)保守不翻转
- UnifiedRenderService 新增 clip_has_text 注入,None 维持 P1 全保守语义
- 删除残留 081_atom_clip_ai_tags.py(与 GPU PR 的 081 撞号,内容已由 082 承载),
  develop alembic 恢复单 head:080→081_add_gpu_lipsync→082_atom_clip_ai_tags
- 新增 19 个测试(纯函数混合标记/服务门控/适配器解析/失败回退),全量 15819 passed
This commit is contained in:
xiaoxia
2026-09-19 01:06:46 +08:00
parent 9af73dcd86
commit fbd89b4089
5 changed files with 235 additions and 28 deletions
@@ -155,6 +155,7 @@ class UnifiedRenderService:
asr_service: Any = None, # ASRService 实例,用于自动生成字幕
bgm_path: str | None = None, # BGM 本地文件路径
voiceover_audio_path: str | None = None, # 配音素材库音频本地路径
clip_has_text: list[bool] | None = None, # 源视频片段是否有文字(来自 atom_clip.ai_tags.has_text)
):
self.plan = plan
self.clips = clips
@@ -167,6 +168,8 @@ class UnifiedRenderService:
self.asr_service = asr_service
self.bgm_path = bgm_path
self.voiceover_audio_path = voiceover_audio_path
# #1970:片段级文字检测(顺序与非 audio 的源视频片段一致);None 表示无可靠检测,保守不翻转
self._clip_has_text = clip_has_text
self._transition_engine = TransitionEngine(default_duration=transition_duration)
self._speed_engine = SpeedEngine()
self._asr_timeline_cache: Any = None # ASR 字幕结果缓存,避免重复调用
@@ -186,7 +189,9 @@ class UnifiedRenderService:
种子 hash(generation_task_id + video_index)%10000,同一任务重渲结果一致。
dedup_enabled=False 时返回 None,调用方不注入任何微变换。
P1 字幕检测:无可靠的片段文字轨道信息,hflip 一律关闭(宁可不翻转)。
hflip 放开(#1970):clip_has_text 来自 atom_clip.ai_tags.has_text,
仅 AI 明确判定无文字的片段可参与 50% 翻转;未打标签 / has_text 为
true/null 或缺位时一律视为有文字,保持保守不翻转。
"""
if self._micro_plan_loaded:
return self._micro_plan_cache
@@ -200,11 +205,14 @@ class UnifiedRenderService:
cfg = self.plan.config or {}
task_id = str(cfg.get("generation_task_id", "") or "")
video_index = int(cfg.get("video_index", 0) or 0)
# self._clip_has_text 顺序与非 audio 源片段一致;
# None(未提供检测,如内存直渲/旧任务)→ 纯函数层按全有文字保守处理;
# 列表短于片段数时缺位片段同样按有文字处理
self._micro_plan_cache = build_micro_transform_plan(
task_id,
video_index,
clip_count,
clip_has_text=None, # P1 保守策略:全部按有文字处理,不翻转
clip_has_text=self._clip_has_text,
enable_bgm_offset=bool(cfg.get("bgm")),
)
except Exception as e: