Communitygithub.com

demo-voiceover

使用 ElevenLabs TTS 生成並同步 AI 語音旁白,適用於展示影片。當使用者要求時啟用。

demo-voiceover 是什麼?

此技能是展示影片處理流程的最終階段,可為錄製的螢幕操作影片加上 AI 語音旁白。它接收來自 `/demo-script` 的腳本 JSON、來自 `/record-demo` 的原始影片與時間戳記日誌,並能獨立運作以處理現有影片。技能使用 ElevenLabs 的帶時間戳端點生成語音,支援多種播放時機策略(例如在動作完成後的停頓期間播放旁白),並自動透過 atempo 濾鏡調整時長。最終輸出包含帶旁白的影片、內嵌字幕的影片、獨立的 SRT 字幕檔案,以及完整的音軌。支援個別段落重新生成,無需重新處理整個影片。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/arozumenko/video-producer/tree/main/skills/demo-voiceover

在你喜歡的 AI 中提問

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

說明文件

Demo Voiceover 技能

為展示影片生成並同步 AI 語音旁白。

定位

這是展示影片處理管道中的第三個階段:

/demo-script  →  /record-demo  →  /demo-voiceover
  (規劃)          (錄製)             (旁白與交付)

亦可獨立使用,為任何現有影片加上時間戳日誌的旁白。

輸入

技能需要以下資料:

  1. Demo 腳本 JSON — 來自 /demo-script (workspace/<date>/demo-script-<name>.json)
  2. 原始影片檔 — 來自 /record-demo (workspace/<date>/<name>_raw.mp4)
  3. 時間戳日誌 — 來自 /record-demo (workspace/<date>/<name>_timestamps.json)

時間戳日誌格式(由 /record-demo 產生):

{
  "video_file": "demo_raw.mp4",
  "start_epoch": 1739545200.0,
  "steps": [
    {
      "scene_id": "intro",
      "step_index": 0,
      "action": "navigate",
      "narration": "歡迎使用 OneTest,讓我們建立第一個測試案例。",
      "timestamp_sec": 0.0,
      "completed_sec": 1.2
    },
    {
      "scene_id": "navigate-to-test-cases",
      "step_index": 0,
      "action": "click",
      "narration": "從側邊欄開啟測試案例區塊。",
      "timestamp_sec": 3.2,
      "completed_sec": 3.8
    }
  ]
}

處理流程

階段 1:旁白規劃

決定每一段旁白應在影片中的哪個時間點播放:

時間策略選項:

策略旁白開始時機最佳用途
on_action在動作開始時 (timestamp_sec)解釋即將發生的動作
after_action在動作完成後 (completed_sec)描述剛才發生的動作
before_action在動作開始前 0.5 秒營造期待感
fill_pause在 pause_after_ms 的停頓期間在刻意暫停時加入旁白

預設:fill_pause — 旁白在每個動作後的停頓期間播放,讓觀眾先看到動作,然後在畫面穩定時聽到解說。這感覺最自然。

規劃輸出:

{
  "segments": [
    {
      "index": 0,
      "text": "歡迎使用 OneTest,讓我們建立第一個測試案例。",
      "video_start_sec": 1.2,
      "max_duration_sec": 2.0
    },
    {
      "index": 1,
      "text": "從側邊欄開啟測試案例區塊。",
      "video_start_sec": 3.8,
      "max_duration_sec": 1.5
    }
  ]
}

階段 2:音訊生成 (ElevenLabs)

使用 ElevenLabs 的帶時間戳端點生成每段旁白:

  • 回傳字符級對齊(精確到毫秒的持續時間)
  • 可免費生成字幕
  • 透過 previous_request_ids(最多 3 個)支援連續性鏈

執行指令:python scripts/generate_narration.py --plan voiceover_plan.json --voice rachel --output-dir .

有關 API 詳細資料,請參閱 references/elevenlabs-api.md。

階段 3:時間對齊

生成音訊後,比對規劃與實際的持續時間:

  1. 音訊可放入可用時間窗口 -> 在規劃時間點開始播放
  2. 音訊較短 -> 多餘的靜音沒問題(展示需要呼吸空間)
  3. 音訊較長 -> 加速(最大 1.15 倍,透過 atempo),或縮短文字重新生成

速度調整上限為 1.15 倍 — 超過會聽起來很趕。

階段 4:音訊組裝

使用輔助腳本將旁白段落與影片合併:

bash scripts/merge_audio_video.sh demo_raw.mp4 narration_results.json final_demo.mp4

該腳本會建立一個包含 adelay(每段延遲)和 atempo(速度調整)的 ffmpeg filter_complex。

階段 5:字幕生成

ElevenLabs 的字符級時間戳可免費產生 SRT 格式字幕:

  • 將字符組成單詞,單詞組成字幕行(最多 8 個單詞)
  • 偏移各段落的 video_start_sec
  • 輸出為標準 SRT 格式

要將字幕燒錄到影片中:

ffmpeg -i final_demo.mp4 -vf subtitles=demo.srt \
    -c:v libx264 -crf 18 -c:a copy \
    final_demo_subtitled.mp4

語音設定

根據目標受眾選擇語音,草稿階段使用 eleven_turbo_v2,最終版本使用 eleven_multilingual_v2。

有關語音 ID、設定指南、模型比較和連續性鏈的詳細資料,請參閱 references/elevenlabs-api.md。

節奏調整

問題解決方案限制
音訊稍微過長使用 atempo 濾鏡加速最大 1.15 倍
音訊太長縮短旁白文字,重新生成只重新生成該段落
音訊太短加入靜音填補(自然)展示中的靜音沒問題
段落間間隔尷尬延長停頓或加入過渡語停頓保持在 3 秒內

輸出檔案

檔案說明
<name>_final.mp4影片 + 旁白合併
<name>_final_subtitled.mp4影片 + 旁白 + 內嵌字幕
<name>.srt字幕檔(獨立)
<name>_narration_full.mp3完整旁白音軌(可重複使用)
narration_NNN.mp3單一段落(供重新生成)
<name>_voiceover_plan.json時間規劃檔案(用於除錯/迭代)

所有檔案儲存在 workspace/<date>/

迭代工作流程

技能支援重新生成個別段落,而無需重新處理全部內容:

  1. 使用者檢視影片:「場景 3 的旁白太快了」
  2. 代理調整:縮短文字,只重新生成段落 3
  3. 使用段落 1-2 的 previous_request_ids 保持連續性
  4. 使用 ffmpeg 重新合併(僅音軌變更,影片不變)

這個流程很快,因為:

  • 影片無需重新錄製
  • 每個變更的段落只需一次 ElevenLabs API 呼叫
  • ffmpeg 合併只需要幾秒鐘

Individual skills in this repo

This repo contains 2 individual skills — each has its own dedicated page.

相關技能