旁白
npm run tts 將 src/timeline.ts 中的每一行朗讀為 public/audio/<lang>/<key>.wav,
並在 <key>.words.json 中記錄 Cartesia 的詞彙時間戳記,同時根據實際行長度重新寫入 src/audio.generated.ts。
系統會根據引擎、語音、模型、速度與文字進行快取:僅有新增或編輯過的行才會重新朗讀。
npm run tts -- en 或 -- es 可將處理範圍限定於單一語言。
Cartesia 設定
- 設定位於
video.config.mjs(tts)中:模型sonic-3.6-2026-08-27,速度1。 - 英文語音:
5568a7df-e5ab-4442-9fae-2e9ba1b15ad8(en-GB)。 CARTESIA_API_KEY的查詢順序如下:- 環境變數;
- 影片資料夾中的
.env(已列入.gitignore;請複製.env.example); ~/Documents/repos/.env。
- 切勿列印金鑰、將其回顯或提交至版本控制。請在不顯示金鑰的情況下檢查其是否存在,
例如
test -n "$CARTESIA_API_KEY" && echo set。
引擎與 Kokoro 備援方案
video.config.mjs 中的 tts.engine:
auto(預設):找到金鑰且服務有回應時使用 Cartesia;否則該語言的所有行將改用 Kokoro(本地、免費)朗讀, 並印出警告訊息。同一語言不會混合使用兩種語音:如果 Cartesia 中途失效,整個語言會改用 Kokoro 重新生成, 下次執行時若 Cartesia 恢復,則會再次重新生成。- `cartesia》:如果不可用則直接失敗,不使用備援。
kokoro:保持離線模式。語音:af_bella(英文)、ef_dora(西班牙文)。Kokoro 不提供詞彙時間戳記, 因此字幕會按比例分配時間。
如果輸出中出現 Kokoro 相關的警告,表示該影片未使用 Cartesia 語音:交接影片時請務必說明此情況。
西班牙語語音
voices.es 在西班牙文版本完成前為 null。請從 Cartesia 語音庫中挑選一個西班牙語語音,
試聽腳本中的範例行,在 video.config.mjs 中記錄其 ID
(es: { id: '<voice-id>', language: 'es' }),然後將 'es' 加入 SETTINGS.voices
(若需要西班牙文字幕,也一併加入 SETTINGS.subtitles)。
發音
TTS 朗讀旁白文字;字幕則顯示書面文字。當 TTS 誤讀數字或符號時,請將該行的口語形式
以 say 的第四個引數傳入,並保留文章原本的書面形式作為字幕:
say(0.3, 'It solved 14/20 tasks.', 'Resolvió 14/20 tareas.', {
en: 'It solved fourteen out of twenty tasks.',
es: 'Resolvió catorce de veinte tareas.',
})
- TTS 將朗讀口語形式(當口語形式變更時,快取會重新朗讀該行);行長度也以口語形式為準。
- 字幕顯示書面文字,並按時間比例分配在該行的時間範圍內(詞彙時間戳記屬於口語詞彙, 因此不適用於該行)。
- 請先以書面形式直接書寫(例如 "14/20"、"83 %"、"p = 0.0018"),僅在試聽後發現 TTS 讀錯時, 才加入口語形式。
- 斜線、版本字串(如 "gpt-5.6")、檔案名稱與縮寫是常見的問題。請仔細聆聽每一行 是否包含此類內容。
音訊 QA
npm run audio-qa(寫入 out/audio-qa.md):
- 將每一行標準化至相同的響度(每個檔案版本只做一次);
- 若原始峰值達到 -0.1 dBFS,則將該行標記為削波;
- 若持續時間超過根據文字長度估算值的 1.6 倍,則將該行標記為過長: 這可能表示語音發生亂碼或重複。請聆聽每個被標記的行,並在確認錯誤後重新朗讀該行 (稍微修改文字,或刪除其 wav 檔);
- 執行
npm run render後,測量out/中每個混音是否符合 -16 LUFS 整合值,容差 ±1 LU (真實峰值 -1.5 dBTP),若不符合則以 exit code 1 結束。
朗讀完成後,請再次執行 npm run lint:實際長度會取代估算值,可能導致影片偏離目標長度
或字幕超過每秒 17 個字元。
背景音樂
系統會在本機自動生成柔和的背景音樂(npm run music,若缺少時 npm run render 會自動產生;
需要安裝 python3 及 numpy,或使用 uv)。在有旁白播放時,背景音樂會縮減至原本音量的 30%。
可將 SETTINGS.music 設為 null 以關閉背景音樂。