name: translating-subtitles description: Use when translating subtitle files (SRT字幕) or word-timestamped ASR JSON (timestamp.json, 词级时间戳) or 视频/音频文件 into bilingual Simplified Chinese + original-language ASS字幕, or when asked to 翻译字幕/校对字幕/生成双语字幕/添加注解字幕/srt转ass/听写json转字幕/视频转字幕/音频转字幕/用ASR转字幕. Triggers on keywords: subtitle, SRT, ASS, timestamp.json, mkv, mp4, mp3, 字幕翻译, 双语字幕, 注解字幕, srt to ass, translate subtitles.
字幕翻譯 (Translating Subtitles)
Overview
將字幕檔案(SRT、帶詞級時間戳的 ASR JSON、或影片/音訊)翻譯為雙語(簡體中文 + 原語言) ASS 字幕。流程固定為 6 步, 必須按順序全部執行, 不得跳過或改變順序:
- 輸入歸一化 + ASR 轉錄(影片/音訊; SRT 跳過; ASR 自動辨識語種)
- 時間戳 → YAML(腳本 + 模型複核, 含分句合適性檢查)
- 校對原文 + 時間戳二次核對(第二遍聽寫交叉驗證; 錯誤/漂移直接修正到 YAML, 含分段重轉修復)
- 分批翻譯(術語表 + 註解字幕)
- 校對譯文
- 合併為 ASS(腳本)
腳本位於本 skill 的 scripts/ 目錄(與 SKILL.md 同級)。運行腳本時, <skill_dir> 指本 SKILL.md 所在目錄。
環境與配置
- 需要
ffmpeg、python(含pyyaml)、以及本地 ASR 工具 q3asr(Qwen3-ASR GGUF 跨平台 CLI)。 - 執行時期解析優先級:
run_transcribe.py --exe> 環境變數TRANSCRIBE_EXE> 自動下載。預設自動下載: 按os/arch/後端從ywwzwb/qwen3-asr-universal發行版取 q3asr 二進位快取到~/.cache/opencode-translate/asr/(首次連網, 之後復用)。手動指定時設TRANSCRIBE_EXE(linux/macos 指向q3asr, Windows 指向q3asr.exe)即可, 不用改本檔案。
工作目錄(臨時隔離)
每次翻譯任務獨立一個臨時工作目錄, 所有中間產物集中在一處, 完成後一鍵清理:
- 建目錄:
mkdir -p "$TEMP/opencode/<輸入檔案基名>"($TEMP即系統臨時目錄, Windows 為%TEMP%, 如C:\Users\zwb\AppData\Local\Temp; 基名取輸入檔案名去副檔名)。 - 把輸入檔案(影片/音訊/SRT)複製進該目錄, 之後所有操作都在這個目錄內完成。
- 所有中間產物(mp3、txt、srt、json、
main.yaml、seg*.yaml等)都生成在這裡, 不污染輸入檔案所在目錄。 - 完成後, 把最終
.ass複製到輸入檔案所在目錄(或用戶指定位置)。 - 用戶要清理時, 直接刪除整個工作目錄即可。
術語表不受影響:
terminology.yaml在 skill 目錄裡全域共享(見第 4 步), 不放進工作目錄。
第 1 步: 輸入歸一化 + ASR 轉錄
按輸入類型準備音訊:
- 影片(mkv/mp4/mov 等): 先轉單聲道 16kHz MP3:
ffmpeg -y -i <input>.mkv -vn -map 0:a:0 -ac 1 -ar 16000 -c:a libmp3lame <input>.mp3 - 音訊(mp3/wav/m4a 等): 同樣轉成統一單聲道 16kHz mp3, 輸出命名為
<basename>.mono.mp3(如demo.mp3→demo.mono.mp3), 與影片路徑的<input>.mp3區分, 避免與同名原檔案衝突。 - SRT: 跳過本步(無需歸一化與 ASR), 直接進入第 2 步(時間戳 → YAML)。
若輸入是音訊/影片, 執行 ASR 轉錄(一律作用於上面歸一化後的 mp3: 影片為 <input>.mp3, 音訊為 <basename>.mono.mp3):
python3 <skill_dir>/scripts/run_transcribe.py <audio>.mp3 -y
若 ASR 執行時期缺失, 自動從
ywwzwb/qwen3-asr-universal最新 release 下載匹配os/arch/後端的 zip 到~/.cache/opencode-translate/asr/並快取。後端自動探測: 首次執行時探測本機最佳方案(cuda→vulkan→metal→cpu, 依據nvidia-smi/vulkaninfo是否存在), 結果儲存到本 skill 目錄的config.yaml(像 terminology.yaml 一樣持久共享), 後續直接復用不再探測; 跨機器時做輕量複核, 失效則重新探測。模型預設 1.7B, 與後端一起存入config.yaml, 首次由 q3asr 自動下載到~/.cache/q3asr/models/(已有快取則復用)。可用環境變數覆蓋:TRANSCRIBE_BACKEND(cuda/vulkan/metal/cpu)、TRANSCRIBE_MODEL(如 1.7b/0.6b)、TRANSCRIBE_ASR_VER(預設 latest)。手動指定TRANSCRIBE_EXE仍為最高優先級。
- 產出同名
<audio>.txt、<audio>.srt、<audio>.json(詞級時間戳[{text,start,end}], 秒)。 - 分段重轉用
--out防止覆蓋全片產物:run_transcribe.py會把.txt/.srt/.json以輸入音訊名命名。對同一 mp3 做視窗重轉(--seek-start)時, 若不加--out會覆蓋全片<audio>.json。加--out <名字>(如--out seg1)會把音訊複製為<名字>.mp3再轉錄, 產物落到<名字>.json等, 全片 JSON 原樣保留。 - ASR 自動辨識語種(Qwen3-ASR 支援多語言); 如需強制指定語種再傳
-l <Language>。 - 長音訊: 先
ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 <audio>.mp3得知時長, 給 bash 指令設定足夠大的逾時(本地 1.7B 模型約 0.05×時長 秒, 另加模型初始化)。
故障排查
- ASR 失敗(退出碼非 0):
run_transcribe.py失敗時已自動列印logs/latest.log尾部, 按日誌尾部定位; 若是本地 GPU/圖形棧相關報錯, 加--no-dml --no-vulkan重試。 - 自動下載的執行時期無法啟動(如凍結二進位缺
libllama.so報Failed to load dynlib/dll): 換用本機可用的 q3asr 原始碼安裝/已解壓執行時期, 設TRANSCRIBE_EXE指向它即可, 不必改本檔案。 - 亂碼
!!!/ 花屏: 設定環境變數GGML_VK_DISABLE_F16=1後重新轉錄(Vulkan 禁用 fp16, 規避部分驅動不相容)。 - ffmpeg 不存在: 立即停止, 先安裝 ffmpeg 並確保在 PATH 中, 再繼續第 1 步。
第 2 步: 時間戳 → YAML
按來源選擇腳本:
- 音訊/影片來源(
<audio>.json): 執行python3 <skill_dir>/scripts/timestamp_to_yaml.py <audio>.json main.yaml(可選--max-width每行寬度上限預設 30,--gap分句停頓閾值秒預設 1.5) - SRT 來源: 執行
python3 <skill_dir>/scripts/srt_to_yaml.py <input>.srt main.yaml
生成中間檔案 main.yaml:
main:
- from: 00:00:02,003
to: 00:00:05,069
en: |
Narrator:
TODAY ON "HOW IT'S MADE"...
- from: 00:00:26,227
to: 00:00:28,026
en: |
ALUMINUM FOIL...
轉換後立即跑塌縮檢測(腳本, 必須先於人工複核): ASR 時間戳經常整塊塌縮——多條 cue 擠在同一秒(甚至零時長)、文字亂碼。機械複核前先用腳本掃一遍:
python3 <skill_dir>/scripts/check_collapse.py main.yaml
- 檢測:
zero(零時長 from==to)、cluster(3+ 條共享同一開始時間 = 整塊塌縮)、order(亂序)、overlap(時間重疊)。 - 退出碼: 乾淨為 0, 有問題為 1。出現
zero/cluster即按第 3 步"分段重轉修復"處理該區域。 - 視窗重轉出的
seg*.yaml用--strict再掃一遍(2 條同秒即報警):python3 <skill_dir>/scripts/check_collapse.py seg.yaml --strict——大視窗重轉自身也常在末尾塌縮, 轉完先自查再拼回。
轉換後必須複核(模型判斷): 腳本按句號/嘆號/問號/長停頓自動分句, 並按寬度自動拆分過長句子, 已自動合併過短片語(句內孤片併入相鄰、無句末標點的單字孤兒併入下句)。轉換腳本已內建"懸空分句自動合併": ASR/寬度切分常把句子攔腰截斷在功能詞處(以 the/a/to/any/each/boil/known 等結尾), 或幻覺句號後小寫續寫(plasters./is applied.), 或留下單字頭(Plasters/are made of...)。timestamp_to_yaml.py 會自動把這些殘片併入下句, 減少人工合併工作量。複核時:- 檢查分句是否自然; 過長或切分不自然的句子重新確定拆分點(優先在頓號、逗號等軟分隔處)。
- 極短片語必須合併: 若某條 cue 只有 1-2 個詞或明顯是從完整句中拆出的殘片(如單獨的
mercury,、The), 用 edit 併入上一句或下一句, 使每條字幕都是完整語塊。標題性短句(Cheese.、Tights.)除外。 - 音訊/影片來源: 重新拆分時必須讀取原始 JSON, 按拆分後每個子片段的詞 token 起止時間更新
from/to(SRT 無詞級時間戳, 不適用此條)。
分句合適性檢查(逐條 cue 判斷, 必須執行): 腳本按寬度/停頓機械切分, 常把句子攔腰截斷。對照以下標準逐條檢查, 不合適就用 edit 合併或移動拆分點:
- 每條 cue 必須是完整語塊: 不能以懸空介詞/連詞結尾。行尾出現
and、or、as、where、which、before、to、of、into等時, 說明切分點錯了, 應把該詞併入下一行或整體合併。 - 拆分點放在從句/並列連接詞之前, 而不是之後。例:
assure quantity distribution/before they're carried...(而非...distribution before/they're carried...);come down 2,000 times per minute/to cut a total of 8,000...(而非...to cut a/total of 8,000...)。 - 同一語塊的介詞短語不要拆開:
5 hours of work保持完整, 不要拆成5 hours/of work;the brush and roller area不要拆成the brush and/roller area。 - 殘片合併後若讀起來才是一句完整的話, 就合併: 如
...cuts the billet strips into+small, equal-sized pieces.應合併為一條;...responsible for the+cloudiness of the beer.應合併。 - 中文分句鏡像英文: 中文譯文的行邊界應與英文 cue 一致, 行尾同樣不能懸空(如
按量分配,後接隨後被送往..., 應把隨後移到下一行;落下2000次,切割出應改為落下2000次/短短60秒內總計切割出8000根)。 - 合併/移動拆分點後, 必須讀取原始 JSON 按新分片的詞 token 起止時間更新
from/to。
第 3 步: 校對原文
逐句閱讀 en 欄位, 找出拼寫錯誤、聽譯錯誤、漏字, 直接用 edit 工具修正 main.yaml 中的 en, 並在回覆中列出修改點。禁止只在註解中提示而不改原文。
保持 main.yaml 的標準格式( - from: + en: | 區塊, 見第2步範例): 只做局部 edit, 禁止用腳本重排整個檔案(如 yaml.safe_dump 重寫), 以免破壞縮排與區塊標量格式。
分段重轉修復(幻覺/錯誤時間戳)
發現壞區域(單條字幕時長異常長、文字亂碼、cue 時間重疊)時:
- 選視窗: 壞區域起點往前 ~3s、終點往後 ~3s, 得
X與D = end - X。 - 重轉該段(必須帶
--out, 否則覆蓋全片<audio>.json):python3 <skill_dir>/scripts/run_transcribe.py <audio>.mp3 --seek-start X --duration D --out seg1 -y(時間戳相對切片起點, 產物為seg1.json)。 - 重轉段自檢:
python3 <skill_dir>/scripts/check_collapse.py seg1.yaml --strict。大視窗重轉常自身塌縮(多條 cue 擠在同一秒), 有zero/cluster就先縮小視窗重轉, 不要繼續拼。 - 還原絕對時間:
python3 <skill_dir>/scripts/timestamp_to_yaml.py seg1.json seg.yaml --offset X(腳本自動合併懸空分句, 見第 2 步)。 - 核對覆蓋: 用
--offset後 seg.yaml 最後一條的to應 ≈X + D。若明顯早於X + D(重轉輸出被截斷), 擴大視窗重轉, 不要繼續拼。 - 拼回(必須傳視窗參數):
python3 <skill_dir>/scripts/splice_yaml.py main.yaml seg.yaml main.new.yaml --seek-start X --duration D。腳本會用請求視窗而非段內容範圍做刪除, 並校驗覆蓋——若重轉段被截斷, 腳本會報錯拒絕拼回(必要時可--force, 但先擴大視窗重轉為宜)。 - 複核: 檢查 splice 輸出(刪除清單 + 字數警告 + LOSS 行)。每次 splice 都會預設列印被刪 cue 清單; 若出現
LOSS:行, 說明有條被刪 cue 的文字沒在重轉內容裡出現——若是完好句子, 擴大視窗重轉。若出現BOUNDARY:行, 說明有條被刪 cue 跨視窗邊界(起點在視窗前或終點在視窗後), 其內容可能被攔腰截斷——確認該視窗真覆蓋了它, 否則擴大視窗重轉。確認無漏詞後, 用 edit 以main.new.yaml內容替換main.yaml; 若丟詞, 擴大視窗重轉或手工 edit 修正。
必須用 splice_yaml.py 拼回, 禁止手工拼接重轉片段: 手動把新 cue 貼進 main.yaml 極易產生重複/重疊 cue(同一 from 出現兩次), 用腳本按時間視窗替換可避免。替換後若發現重複 from, 說明拼接過當, 用 splice 重做。
時間戳二次核對(第二遍聽寫交叉驗證)
同一音訊連轉兩遍, 詞級時間戳會明顯漂移(實測: 兩遍之間 max delta 可達數十秒, 部分 cue 相差 12-40s)。因此聽寫一遍出的時間戳不可全信。整理完 YAML 後, 必須再完整聽寫一遍, 與當前 cue 時間交叉核對:
- 複製音訊再轉第二遍(不要覆蓋第一遍 JSON):
cp <audio>.mp3 <audio>.pass2.mp3, 然後python3 <skill_dir>/scripts/run_transcribe.py <audio>.pass2.mp3 -y, 產出<audio>.pass2.json(也可用--out pass2省去手動 cp, 效果相同)。 - 逐條核對:
python3 <skill_dir>/scripts/compare_timestamps.py main.yaml <audio>.pass2.json --threshold 1.0。腳本按標準化文字把每條 cue 的en定位到第二遍的詞 token, 輸出delta start/end(當前 cue 時間 − 第二遍詞級時間)與<<<標記。閾值預設 1.0s(第二遍自身會漂移, 0.5s 假陽性太多)。 - 對
<<<或NOT FOUND的 cue 精確校對: 第二遍聽寫只是探測器, 不是權威——它自己也會漂移(整段整體偏移), 絕不能直接以第二遍時間戳為準改from/to。一律按上文"分段重轉修復"流程對該視窗重轉: 取該 cue 前後 ~3s 視窗重轉 →--offset還原絕對時間 →splice_yaml.py拼回, 以視窗重轉結果為準。若視窗重轉與第二遍一致, 則主 yaml 時間確實錯了, 修; 若一致確認主 yaml 對, 不改。 - 交叉複核譯文側:
compare_timestamps.py可對任意 yaml 用--full輸出全部 cue 的 delta, 便於整體看漂移趨勢。 - 反覆執行直到無
<<<且無NOT FOUND(或已人工確認)。
說明: 第二遍聽寫也偶有自身漂移或文字不同(hence
NOT FOUND), 所以最終以分段視窗重轉 + 人工聽音為準,compare_timestamps.py只是快速發現可疑 cue 的探測器。
第 4 步: 分批翻譯
開始翻譯前, 先讀取 <skill_dir>/terminology.yaml(不存在則建立空檔案)。 術語表存放在本 skill 的目錄裡(全域安裝時即機器級), 跨影片、跨專案、跨工作階段持久共享, 保證不同影片裡同一人名/地名/專有名詞譯法一致。翻譯中遇到新術語, 先把它加進 <skill_dir>/terminology.yaml 再使用; 比對不區分大小寫。
說明: 若
<skill_dir>與目前專案不同(全域安裝), 術語表就是全域唯一的一份; 專案裡不再單獨維護terminology.yaml。
翻譯採用結構化批次輸出 + 腳本寫入, 不用逐句 edit:
- 分批翻譯(每批 ≤50 句): 在回覆中輸出結構化譯文區塊——
start是該批第一句在main.yaml中的 cue 序號(0-based),translation列表逐句對應, 順序與 main.yaml 的 cue 完全一致。禁止一次性輸出全部字幕的翻譯, 一批寫完確認後(腳本寫入 + 抽查)再處理下一批。
start: 0 # 本批第一句的 cue 序號(0-based)
translation:
- 第1句譯文
- 第2句譯文
- |
多行譯文第一行
多行譯文第二行
- 第4句譯文
-
腳本寫入: 把上面的結構化區塊儲存為
batch.yaml(工作目錄內), 執行python3 <skill_dir>/scripts/apply_translations.py main.yaml batch.yaml main.new.yaml腳本按 cue 序號把chs欄位精確插入每條en區塊之後, 不重排檔案(非 safe_dump), 註解與其他行原樣保留。核對後cp main.new.yaml main.yaml。--overwrite: 替換已有 chs(預設遇已有 chs 報錯, 防止錯位批次靜默覆蓋)--dry-run: 只列印將寫多少條, 不落盤- 腳本會校驗
start + 條數不越界; 越界即報錯, 停下核對start
-
翻譯不落地前先自查: 每條譯文遵守下方翻譯規則(句尾無句號/逗號、數字阿拉伯化、術語表一致、行邊界鏡像英文 cue)。寫完一批後人工抽查該批首尾幾條, 確認 cue 序號與內容對齊(尤其檢查翻譯區塊裡的
start是否等於上一批的start + 上一批條數)。
最終審閱仍用 edit 工具逐條修正——批次寫入負責"灌入", 人工 edit 負責"精修"。
main:
- from: 00:00:02,003
to: 00:00:05,069
en: |
Narrator:
TODAY ON "HOW IT'S MADE"...
chs: |
旁白:
今天的《造物小百科》……
翻譯規則
- 意譯優先, 不逐字逐句。 按漢語語序和句式長度調整詞序、位置, 可合併或拆分句子, 確保中文通順自然。
- 專有名詞統一走術語表。 人名、地名、作品名、品牌名等, 在
terminology.yaml中統一翻譯, 並每次翻譯前先讀取。術語比對不區分大小寫。遇到新術語時先加入術語表再使用:
terminology:
Susan: 蘇珊
Texas: 德州
HOW IT'S MADE: 造物小百科
- 句尾標點。 譯文正文句末若最後一個字元是句號
。或逗號(全形,或半形,), 直接去掉。例: "歡迎收看本期節目。" → "歡迎收看本期節目"。句號/逗號只允許出現在句中, 不得作為譯文句尾。 - 數字用阿拉伯數字。 譯文中的數字盡量用阿拉伯數字書寫: 三到八小時 → 3-8 小時、二十年前 → 20 年前、六千克麵粉 → 6000 克麵粉、百分之九十五 → 95%、四點四米 → 4.4 米、750 攝氏度 → 750 攝氏度。用於專有名詞/標題裡的數字(如 "How It's Made"、年份、型號)除外。
- 註解字幕。 字幕中出現中文語境少見的當地習俗、節日、專業名詞、英制單位等, 新增 ≤20 字(約 4 字/秒)的簡短註解, 寫入
main.yaml的annotations列表。同一術語只在第一次出現時註解。
annotations:
- from: 00:00:02,003
text: 造物小百科:科普紀錄片欄目
註解規則:
- 每個註解 ≤20 字, 盡量簡潔。
from與對應字幕的開始時間對齊。to不必填寫,yaml_to_ass.py按 4 字/秒 自動計算結束時間。- 同一句(開始時間相同)若出現多個註解, 腳本會合併為一條事件, 上下並列展示。
- 連續註解若前一條結束時間晚於後一條開始時間, 腳本會將前一條結束時間鉗制到後一條開始之前, 避免時間重疊。
- 英制單位: 註解直接給出該句具體數值的標準國際單位換算, 如 "500磅≈227公斤"、"60英里≈96.6公里/時"、"62°F≈17°C", 不解釋單位本身的含義(如"英制重量單位")。單位換算用 ≈ 表示近似; 數值不同時每次出現都需換算, 不受"首次出現"限制。
第 5 步: 校對譯文
通讀全部 chs, 檢查錯譯、漏譯、術語不一致、時間軸錯位, 用 edit 工具修正。
校對完成後, 再通掃一遍 main.yaml, 把適合阿拉伯數字表示的數字直接用 edit 改成阿拉伯數字:
en(聽寫)裡的英文詞形數字:three to eight hours→3 to 8 hours、six thousand kilos→6,000 kilos、twenty years ago→20 years ago、half a centimeter→0.5 centimeter、seventy-five→75、first/second→1st/2nd。chs(譯文)裡的中文數字: 二十年前 → 20 年前、三到八小時 → 3-8 小時、六千公斤 → 6000 公斤、百分之九十五 → 95%、四點四米 → 4.4 米。- 用於專有名詞/標題/年份/型號的數字保持不變(如 "How It's Made"、
Narrator:裡的年份)。 - 只改明確無疑的; 拿不準的就保持原文。
第 6 步: 合併 ASS
執行: python3 <skill_dir>/scripts/yaml_to_ass.py main.yaml output.ass --check
--check 會校驗 cue 完整性(重疊 / 零時長 / 亂序), 有錯則報錯並退出, 防止帶病出片。合併完成後, 把成品 .ass 複製到輸入檔案所在目錄(如影片旁邊), 便於使用者直接使用; 工作目錄裡的中間產物留給使用者按需清理。
生成格式(範本內嵌於腳本, 要點如下):
[Script Info]
ScriptType: v4.00+
PlayResX: 1920
PlayResY: 1080
WrapStyle: 2
[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Translation,Noto Sans CJK SC,56,&H00FFFFFF,&H000000FF,&H00141414,&H80000000,-1,0,0,0,100,100,0,0,1,3,1,2,80,80,81,1
Style: Original,Noto Sans CJK SC,36,&H00FFFFFF,&H000000FF,&H00141414,&H80000000,-1,0,0,0,100,100,0,0,1,2,1,2,80,80,45,1
Style: Annotation,Noto Sans CJK SC,26,&H00FFE066,&H000000FF,&H00141414,&H80000000,-1,0,0,0,100,100,0,0,1,1,1,7,40,40,20,1
[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
輸出為三條獨立軌道, 便於後期逐軌調整樣式(各軌道用獨立的 Layer 與 Style, 可在 Aegisub/剪輯軟體中分開編輯):
| Layer | Style | 內容 | 字型大小/位置 |
|---|---|---|---|
| 0 | Translation | 簡體中文譯文 | fs56, 底欄主行 |
| 1 | Original | 原語言文字 | fs36, 緊貼譯文下方 |
| 2 | Annotation | 註解 | fs26, 左上角 |
佈局要求:
- 譯文為主: 底欄大寫字型(Layer 0)。
- 原文為輔: 譯文下方小寫字型(Layer 1)。
- 註解在左上角(Layer 2, Alignment 7)。
範例事件:
Dialogue: 0,0:00:02.00,0:00:05.06,Translation,,0,0,0,,今天的《造物小百科》……
Dialogue: 1,0:00:02.00,0:00:05.06,Original,,0,0,0,,Narrator: TODAY ON "HOW IT'S MADE"...
Dialogue: 2,0:00:02.00,0:00:03.62,Annotation,,0,0,0,,造物小百科:科普紀錄片欄目
常見錯誤 (Common Mistakes)
| 錯誤 | 正確做法 |
|---|---|
| 跳過 YAML 直接輸出 ASS | 必須先轉 main.yaml, 翻譯再合併 |
| 手寫 ASS 代替腳本 | 用 yaml_to_ass.py 合併, 註解時間由腳本計算 |
| 出 ASS 前不校驗完整性 | 用 yaml_to_ass.py --check 查重疊/零時長/亂序 |
| 一次性翻譯全部字幕 | 每批 ≤50 句, 分批輸出結構化譯文, 腳本寫入 |
| 逐句 edit 寫 chs | 用 apply_translations.py 批次寫入, edit 只用於最終審閱 |
批次 start 序號錯位 | start 必須 = 上一批 start + 上一批條數; 腳本越界會報錯 |
| 批次覆蓋已有譯文 | 預設遇已有 chs 報錯; 確需替換才加 --overwrite |
| 人名地名前後譯法不一致 | 寫入 terminology.yaml, 每次先讀取 |
| 註解超過 20 字 | 壓縮, 只保留必要資訊 |
| 註解結束時間隨手填 | 交給腳本按 4 字/秒 計算 |
| 同一句多個註解未並列 | 腳本自動合併為上下兩…… |