Communitygithub.com

subtitle-translate — 雙語 ASS + 術語表

SRT / 詞級 ASR JSON / 影片 → 簡中 + 原文雙語 ASS。術語表、雙遍校對、註解字幕。

subtitle-translate — 雙語 ASS + 術語表 是什麼?

Video Localization 步驟2:ywwzwb 雙語 ASS + 術語 QA。新鮮於 9/26、9/24 中段。

相容平台✓Claude Code~Codex CLI~Cursor✓OpenCode
npx skills add ywwzwb/subtitle-translate-skill

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件


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 步, 必須按順序全部執行, 不得跳過或改變順序:

  1. 輸入歸一化 + ASR 轉錄(影片/音訊; SRT 跳過; ASR 自動辨識語種)
  2. 時間戳 → YAML(腳本 + 模型複核, 含分句合適性檢查)
  3. 校對原文 + 時間戳二次核對(第二遍聽寫交叉驗證; 錯誤/漂移直接修正到 YAML, 含分段重轉修復)
  4. 分批翻譯(術語表 + 註解字幕)
  5. 校對譯文
  6. 合併為 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)即可, 不用改本檔案。

工作目錄(臨時隔離)

每次翻譯任務獨立一個臨時工作目錄, 所有中間產物集中在一處, 完成後一鍵清理:

  1. 建目錄: mkdir -p "$TEMP/opencode/<輸入檔案基名>"($TEMP 即系統臨時目錄, Windows 為 %TEMP%, 如 C:\Users\zwb\AppData\Local\Temp; 基名取輸入檔案名去副檔名)。
  2. 把輸入檔案(影片/音訊/SRT)複製進該目錄, 之後所有操作都在這個目錄內完成。
  3. 所有中間產物(mp3、txt、srt、json、main.yaml、seg*.yaml 等)都生成在這裡, 不污染輸入檔案所在目錄。
  4. 完成後, 把最終 .ass 複製到輸入檔案所在目錄(或用戶指定位置)。
  5. 用戶要清理時, 直接刪除整個工作目錄即可。

術語表不受影響: 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 時間重疊)時:

  1. 選視窗: 壞區域起點往前 ~3s、終點往後 ~3s, 得 X 與 D = end - X。
  2. 重轉該段(必須帶 --out, 否則覆蓋全片 <audio>.json): python3 <skill_dir>/scripts/run_transcribe.py <audio>.mp3 --seek-start X --duration D --out seg1 -y(時間戳相對切片起點, 產物為 seg1.json)。
  3. 重轉段自檢: python3 <skill_dir>/scripts/check_collapse.py seg1.yaml --strict。大視窗重轉常自身塌縮(多條 cue 擠在同一秒), 有 zero/cluster 就先縮小視窗重轉, 不要繼續拼。
  4. 還原絕對時間: python3 <skill_dir>/scripts/timestamp_to_yaml.py seg1.json seg.yaml --offset X(腳本自動合併懸空分句, 見第 2 步)。
  5. 核對覆蓋: 用 --offset 後 seg.yaml 最後一條的 to 應 ≈ X + D。若明顯早於 X + D(重轉輸出被截斷), 擴大視窗重轉, 不要繼續拼。
  6. 拼回(必須傳視窗參數): python3 <skill_dir>/scripts/splice_yaml.py main.yaml seg.yaml main.new.yaml --seek-start X --duration D。腳本會用請求視窗而非段內容範圍做刪除, 並校驗覆蓋——若重轉段被截斷, 腳本會報錯拒絕拼回(必要時可 --force, 但先擴大視窗重轉為宜)。
  7. 複核: 檢查 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 時間交叉核對:

  1. 複製音訊再轉第二遍(不要覆蓋第一遍 JSON): cp <audio>.mp3 <audio>.pass2.mp3, 然後 python3 <skill_dir>/scripts/run_transcribe.py <audio>.pass2.mp3 -y, 產出 <audio>.pass2.json(也可用 --out pass2 省去手動 cp, 效果相同)。
  2. 逐條核對: 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 假陽性太多)。
  3. 對 <<< 或 NOT FOUND 的 cue 精確校對: 第二遍聽寫只是探測器, 不是權威——它自己也會漂移(整段整體偏移), 絕不能直接以第二遍時間戳為準改 from/to。一律按上文"分段重轉修復"流程對該視窗重轉: 取該 cue 前後 ~3s 視窗重轉 → --offset 還原絕對時間 → splice_yaml.py 拼回, 以視窗重轉結果為準。若視窗重轉與第二遍一致, 則主 yaml 時間確實錯了, 修; 若一致確認主 yaml 對, 不改。
  4. 交叉複核譯文側: compare_timestamps.py 可對任意 yaml 用 --full 輸出全部 cue 的 delta, 便於整體看漂移趨勢。
  5. 反覆執行直到無 <<< 且無 NOT FOUND(或已人工確認)。

說明: 第二遍聽寫也偶有自身漂移或文字不同(hence NOT FOUND), 所以最終以分段視窗重轉 + 人工聽音為準, compare_timestamps.py 只是快速發現可疑 cue 的探測器。

第 4 步: 分批翻譯

開始翻譯前, 先讀取 <skill_dir>/terminology.yaml(不存在則建立空檔案)。 術語表存放在本 skill 的目錄裡(全域安裝時即機器級), 跨影片、跨專案、跨工作階段持久共享, 保證不同影片裡同一人名/地名/專有名詞譯法一致。翻譯中遇到新術語, 先把它加進 <skill_dir>/terminology.yaml 再使用; 比對不區分大小寫。

說明: 若 <skill_dir> 與目前專案不同(全域安裝), 術語表就是全域唯一的一份; 專案裡不再單獨維護 terminology.yaml。

翻譯採用結構化批次輸出 + 腳本寫入, 不用逐句 edit:

  1. 分批翻譯(每批 ≤50 句): 在回覆中輸出結構化譯文區塊——start 是該批第一句在 main.yaml 中的 cue 序號(0-based), translation 列表逐句對應, 順序與 main.yaml 的 cue 完全一致。禁止一次性輸出全部字幕的翻譯, 一批寫完確認後(腳本寫入 + 抽查)再處理下一批。
start: 0            # 本批第一句的 cue 序號(0-based)
translation:
  - 第1句譯文
  - 第2句譯文
  - |
    多行譯文第一行
    多行譯文第二行
  - 第4句譯文
  1. 腳本寫入: 把上面的結構化區塊儲存為 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
  2. 翻譯不落地前先自查: 每條譯文遵守下方翻譯規則(句尾無句號/逗號、數字阿拉伯化、術語表一致、行邊界鏡像英文 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: |
      旁白:
      今天的《造物小百科》……

翻譯規則

  1. 意譯優先, 不逐字逐句。 按漢語語序和句式長度調整詞序、位置, 可合併或拆分句子, 確保中文通順自然。
  2. 專有名詞統一走術語表。 人名、地名、作品名、品牌名等, 在 terminology.yaml 中統一翻譯, 並每次翻譯前先讀取。術語比對不區分大小寫。遇到新術語時先加入術語表再使用:
terminology:
  Susan: 蘇珊
  Texas: 德州
  HOW IT'S MADE: 造物小百科
  1. 句尾標點。 譯文正文句末若最後一個字元是句號 。 或逗號(全形 , 或半形 ,), 直接去掉。例: "歡迎收看本期節目。" → "歡迎收看本期節目"。句號/逗號只允許出現在句中, 不得作為譯文句尾。
  2. 數字用阿拉伯數字。 譯文中的數字盡量用阿拉伯數字書寫: 三到八小時 → 3-8 小時、二十年前 → 20 年前、六千克麵粉 → 6000 克麵粉、百分之九十五 → 95%、四點四米 → 4.4 米、750 攝氏度 → 750 攝氏度。用於專有名詞/標題裡的數字(如 "How It's Made"、年份、型號)除外。
  3. 註解字幕。 字幕中出現中文語境少見的當地習俗、節日、專業名詞、英制單位等, 新增 ≤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/剪輯軟體中分開編輯):

LayerStyle內容字型大小/位置
0Translation簡體中文譯文fs56, 底欄主行
1Original原語言文字fs36, 緊貼譯文下方
2Annotation註解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 字/秒 計算
同一句多個註解未並列腳本自動合併為上下兩……

相關技能