# -*- coding: utf-8 -*- """ 从已有 数据.jsonl 里把【超长视频】的 COS 路径提取到一个 txt,供以后补跑。 用途:本次改动之前,被"视频过长"过滤掉的视频没有单独留列表,源 txt 又已删除。 但 数据.jsonl 每条都存了 duration,可据此把它们捞回来。 判定为"待补跑的超长视频": - 该视频最新一条记录 reason == "视频过长"(新版记录有此字段);或 - duration > 阈值 且 status != success(旧记录没有 reason,靠时长兜底) 成功处理过的(status=success)不导出。 用法: python tools/拆分超长.py # 读 ./数据.jsonl,阈值取 config 的 max_duration_seconds python tools/拆分超长.py 数据.jsonl --min 2400 # 指定文件和阈值(秒) python tools/拆分超长.py a.jsonl b.jsonl -o 超长待重跑.txt """ import argparse import json import os import sys sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) def _default_threshold(): try: from config.config_utils import config return float(config.get_subtitle_config().get('max_duration_seconds', 5400) or 5400) except Exception: return 5400.0 def main(): ap = argparse.ArgumentParser() ap.add_argument('jsonl', nargs='*', default=['数据.jsonl'], help='一个或多个 数据.jsonl(默认 ./数据.jsonl)') ap.add_argument('--min', type=float, default=None, help='超长阈值(秒),默认取 config.max_duration_seconds') ap.add_argument('-o', '--out', default='超长待重跑.txt', help='输出 txt') args = ap.parse_args() thr = args.min if args.min is not None else _default_threshold() files = args.jsonl or ['数据.jsonl'] # 多文件合并,按 video_cos_path 取最新一条 latest = {} for path in files: if not os.path.exists(path): print(f"[跳过] 不存在: {path}") continue with open(path, encoding='utf-8') as f: for line in f: line = line.strip() if not line: continue try: r = json.loads(line) except Exception: continue v = r.get('video_cos_path') if v: latest[v] = r out_paths, seen = [], set() n_reason, n_dur = 0, 0 for v, r in latest.items(): if r.get('status') == 'success': continue reason = r.get('reason') dur = r.get('duration') hit = False if reason == '视频过长': hit = True; n_reason += 1 elif dur is not None and dur > thr: hit = True; n_dur += 1 if hit and v not in seen: seen.add(v); out_paths.append(v) with open(args.out, 'w', encoding='utf-8') as f: for p in out_paths: f.write(p + '\n') print(f"阈值 {thr:.0f}s | 扫描 {len(latest)} 个唯一视频") print(f"导出 {len(out_paths)} 个超长视频 → {args.out} (reason命中 {n_reason}, 时长兜底 {n_dur})") print("\n补跑提示: 放进 text2/ 并【换一个 数据.jsonl】(否则会被当已处理跳过):") print(f" mv {args.out} text2/long_rerun.txt") print(" # 建议在 GPU 机器上跑(长视频GPU硬解快); 放大 config.max_duration_seconds 让它们不再被过滤") if __name__ == '__main__': main()