feat: 日语转写(翻译前归档)也作为产物放到视频旁
翻译前的日语转写只有中间态,重跑字幕或回看译文时无据可查;把它按语言归档到 视频旁,与中文译文、双目字幕并列。 - `learn-translate` 的 `final_outputs` 增加 `ja_srt: asr.srt_uri`(清洗后的转写)。 - `_sidecar_product_name` 改为**按 final_outputs 别名**映射语言后缀 (`ja_srt`→`.JA.srt`、`cn_srt`→`.CN.srt`、`ass`→`.CN_dual_eye.ass`),未登记别名 时按扩展名兜底。此前两份 `.srt` 都映射成 `.CN.srt` 会互相覆盖(真实日志: "产物已放视频旁: movie.CN.srt, movie.CN.srt")。 - 任务管理的产物列补"日语 SRT"下载链接。 - 测试:按别名区分语言变体 + 端到端验证两份产物都落地且不覆盖。
This commit is contained in:
@@ -247,6 +247,17 @@ def test_sidecar_product_name_maps_srt_and_ass() -> None:
|
||||
assert _sidecar_product_name(video, Path("/tmp/x.ass")) == "movie.CN_dual_eye.ass"
|
||||
|
||||
|
||||
def test_sidecar_product_name_maps_language_variants_by_alias() -> None:
|
||||
"""日语转写与中文译文都是 .srt:按 final_outputs 别名区分,互不覆盖。"""
|
||||
# 数据:同一个视频的两份 .srt 产物(日语转写、中文译文)。
|
||||
video = Path("/videos/movie.mp4")
|
||||
|
||||
# 测试过程与验证结果:按别名映射成不同语言后缀。
|
||||
assert _sidecar_product_name(video, Path("/tmp/transcript.srt"), "ja_srt") == "movie.JA.srt"
|
||||
assert _sidecar_product_name(video, Path("/tmp/cn.srt"), "cn_srt") == "movie.CN.srt"
|
||||
assert _sidecar_product_name(video, Path("/tmp/x.ass"), "ass") == "movie.CN_dual_eye.ass"
|
||||
|
||||
|
||||
def test_sidecar_product_name_keeps_other_extensions() -> None:
|
||||
"""其他扩展名产物保留原文件名(不误改语义)。"""
|
||||
# 数据:vtt 产物。
|
||||
@@ -432,6 +443,34 @@ def test_worker_processes_pending_video_end_to_end(tmp_path: Path, monkeypatch)
|
||||
assert list(folder.glob("movie.*")), "应在视频旁放置最终产物"
|
||||
|
||||
|
||||
def test_final_outputs_place_japanese_transcript_by_language(tmp_path: Path, monkeypatch) -> None:
|
||||
"""日语转写(过滤后待翻译)与中文译文都放到视频旁,文件名按语言区分。"""
|
||||
# 数据:prep 阶段产出日语转写、translate 阶段产出中文译文,两者都是 .srt。
|
||||
folder = tmp_path / "videos"
|
||||
_make_video(folder / "movie.mp4")
|
||||
db = Database(tmp_path / "wov.db")
|
||||
db.upsert_workflow({
|
||||
"id": "wf", "name": "两产物流程", "description": "", "published": 1,
|
||||
"latest_version": 1,
|
||||
})
|
||||
definition = _staged_definition().to_dict()
|
||||
definition["final_outputs"] = {"ja_srt": "prep.file_uri", "cn_srt": "translate.file_uri"}
|
||||
db.create_workflow_version("wf", 1, WorkflowDefinition.from_dict(definition).to_dict())
|
||||
monkeypatch.setattr("wov_app.batch.BATCH_WORK_ROOT", tmp_path / "storage" / "batch")
|
||||
|
||||
# 测试过程:驱动一轮批量处理。
|
||||
with _recording_nodes([]):
|
||||
job_id = create_job(db, str(folder), "wf")
|
||||
BatchWorker(db, interval_seconds=999)._process_job(db.get_batch_job(job_id))
|
||||
|
||||
# 验证结果:两份产物都在视频旁且不互相覆盖。
|
||||
placed = sorted(
|
||||
p.name for p in folder.iterdir()
|
||||
if p.name.startswith("movie.") and p.suffix.lower() in (".srt", ".ass")
|
||||
)
|
||||
assert placed == ["movie.CN.srt", "movie.JA.srt"]
|
||||
|
||||
|
||||
def test_worker_skips_video_with_sidecar_subtitle(tmp_path: Path, monkeypatch) -> None:
|
||||
"""已有旁挂字幕的视频不触发流水线(SKIPPED 不产生 run)。"""
|
||||
# 数据:一个已带字幕的视频。
|
||||
|
||||
Reference in New Issue
Block a user