fix: 帧文件按帧号数值排序,修复超 9999 帧字典序错位
- frame-extract 新增 _sorted_frame_files:ffmpeg %04d 编号超过 9999 帧后扩为 5 位,sorted() 字典序会把 5 位编号排在 4 位之前,导致 frames.json 时间与 图像错位(真实发生于 run_339ec7ee437f 的 14236 帧任务) - subtitle-ocr 提取 _merge_kept 供重组装复用 - 回归测试用真实任务留存数据(testdata/frames_boundary/),并新增真实 OCR 数据按正确时间轴重组装为 SRT 的集成测试(test_integration_reassemble_ocr)
This commit is contained in:
+24
-13
@@ -63,6 +63,28 @@ def _assemble_srt(
|
||||
return lines
|
||||
|
||||
|
||||
def _merge_kept(
|
||||
manifest: list[dict], texts: list[str]
|
||||
) -> list[tuple[float, float, str]]:
|
||||
"""按 manifest 时间轴把逐帧 OCR 文本合并为字幕条目。
|
||||
|
||||
kept 元素为 (起始帧时间, 最后可见帧时间, 文本):空文本(无文字帧)跳过;
|
||||
连续帧相同字幕合并为一条(字幕停留多帧属正常现象),仅更新最后可见帧
|
||||
时间,起始时间保持首次出现。要求 texts 与 manifest 按帧顺序一一对应
|
||||
(调用方保证),重组装旧数据时也复用此逻辑保证行为一致。
|
||||
"""
|
||||
kept: list[tuple[float, float, str]] = []
|
||||
for index, text in enumerate(texts):
|
||||
if not text:
|
||||
continue
|
||||
time = float(manifest[index]["time"])
|
||||
if kept and kept[-1][2] == text:
|
||||
kept[-1] = (kept[-1][0], time, text)
|
||||
continue
|
||||
kept.append((time, time, text))
|
||||
return kept
|
||||
|
||||
|
||||
def invoke(request: InvokeRequest) -> InvokeResponse:
|
||||
"""逐帧 OCR 并汇总字幕,产物为 subtitle.srt。"""
|
||||
manifest_uri = request.inputs.get("frames_manifest")
|
||||
@@ -138,19 +160,8 @@ def invoke(request: InvokeRequest) -> InvokeResponse:
|
||||
)
|
||||
texts = pool.map(list(enumerate(manifest)))
|
||||
|
||||
# kept 元素为 (起始帧时间, 最后可见帧时间, 文本);按帧顺序合并连续相同字幕。
|
||||
kept: list[tuple[float, float, str]] = []
|
||||
for index, text in enumerate(texts):
|
||||
if not text:
|
||||
continue
|
||||
time = float(manifest[index]["time"])
|
||||
# 连续帧相同字幕合并为一条(字幕停留多帧属正常现象):
|
||||
# 仅更新最后可见帧时间,起始时间保持首次出现。
|
||||
if kept and kept[-1][2] == text:
|
||||
kept[-1] = (kept[-1][0], time, text)
|
||||
continue
|
||||
kept.append((time, time, text))
|
||||
|
||||
# 按帧顺序合并连续相同字幕(与重组装旧数据共用 _merge_kept)。
|
||||
kept = _merge_kept(manifest, texts)
|
||||
output_dir = Path(request.output_dir)
|
||||
output_dir.mkdir(parents=True, exist_ok=True)
|
||||
output_path = output_dir / "subtitle.srt"
|
||||
|
||||
Reference in New Issue
Block a user