Communitygithub.com

nielssrb/Video2presentation

將研討會、網路研討會或會議錄影轉換為可編輯的投影片組:從影片幀提取投影片、附註解連結,以及將逐字稿片段作為備註。

Video2presentation 是什麼?

這個技能(Video2presentation)能將研討會、網路研討會或會議的錄影,自動轉換為一份結構完整、可編輯的 Google Slides 簡報。它運用電腦視覺技術從影片中擷取關鍵投影片幀,並透過 AssemblyAI 進行語音轉文字,再將經過清理的逐字稿片段作為每張投影片的備註。技能支援 Claude Code 和 Cowork 平台,並包含嚴謹的規則來確保準確性,例如:自動計算數據、檢查法律聲明、標示演講者之間的矛盾,以及避免未經授權修改使用者檔案。主要工作流程涵蓋:規劃與提問、語音轉文字處理、投影片擷取與去重、影像裁切、連結驗證,以及在 Claude Slides 中組合簡報。

相容平台✓Claude Code~Codex CLI~Cursor
npx skills add nielssrb/Video2presentation

在你喜歡的 AI 中提問

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

說明文件

Video2presentation:研討會錄影 → 簡報

決策的詳細歷史和測量數值記錄在 Video2presentation 資料夾中的 METHODOLOGY.md。如果此技能和 METHODOLOGY.md 不一致,請遵循此技能。將新的經驗教訓新增至 METHODOLOGY.md。

始終適用的規則

  1. 先規劃和提問。 在進行任何處理之前,請依照下列步驟向使用者說明計畫,並使用 AskUserQuestion 提出釐清問題(清單在步驟 0)。僅在收到答案後才開始工作。
  2. 回覆使用者。 使用使用者的語言(通常非英文),誠實且不諂媚。使用腳本計算所有數字。將資訊格式化為表格;僅在使用者要求時使用純文字。每次更新簡報後提供簡報連結。
  3. 安全性。
    • 僅從檔案 assemblyai_key.txt 讀取 AssemblyAI 金鑰。切勿列印或將其複製到雲端、筆記或構件中。
    • 即使講者展示 Miro 看板,也請勿使用 Miro 或 Figma 整合:請從影片幀中擷取看板。
    • 未經許可,請勿刪除使用者資料夾中的任何內容,包括 _work/ 工作資料夾。
  4. 準確性。
    • 請勿默默修正講者:在備註中用時間碼註明矛盾之處和數字差異。
    • 使用腳本重新計算投影片中的數字。
    • 檢查法律聲明,並在投影片上添加簡短的免責聲明。
    • 將最終重點標記為綜合整理,而非講者的投影片。
  5. 影片不會上傳至雲端。 ffmpeg、OpenCV 和轉錄在使用者的電腦上執行(device_bash)。只有連絡表、馬賽克圖、個別幀和裁切會上傳至雲端——那些必須被查看、識別或上傳到構件的內容。

各項檔案位置

  • 此技能和專案資料夾是 Video2presentation(在 Cowork 中,連線資料夾為 $HOME/mnt/Video2presentation;在 Claude Code 中,為當前資料夾)。其根目錄包含技能本身(SKILL.md)和 METHODOLOGY.md。
  • pipeline/——腳本:
    • transcribe_assemblyai.py——透過 AssemblyAI 產出逐字稿;
    • extract_slides.py——每秒一個幀、視訊鏡頭遮罩、穩定片段、去重、連絡表;
    • mosaic.py——從幀列表中產生 2×2 馬賽克圖;
    • crop_images.py 和 crops_<日期>[_<講者>].json——裁切出圖片;
    • clean_transcript.py——每張投影片經過清理的逐字稿片段。
  • assemblyai_key.txt——AssemblyAI API 金鑰。該檔案可能不存在——請參閱步驟 0 和步驟 1。
  • 活動資料夾 YYYY.MM.DD 名稱/:包含影片,有時包含描述(HTML 或使用者訊息中的文字),有時包含現成的逐字稿(sentences.json、transcript.txt)。將中間檔案放在 <活動資料夾>/_work/ 中。
  • 如果腳本遺失,請參閱文末的「如果 pipeline/ 不可用」。

步驟 0. 偵察、規劃、提問

  1. 檢查活動資料夾:
    • 影片:解析度、長度、fps(ffprobe);是否有另一個解析度的副本;
    • 現成的逐字稿;
    • 是否存在 assemblyai_key.txt——如果需要從頭開始建立逐字稿,則需要此檔案;
    • 活動描述(可選):姓名、Telegram 帳號、談話主題。它可能位於使用者訊息的結尾或 HTML 檔案中。如果沒有描述,請從錄影本身取得姓名和主題。
  2. 呈現計畫並使用 AskUserQuestion 提問。「建議」選項代表使用者之前的選擇:
    • 逐字稿: 如果存在則使用現成的(建議),或使用 AssemblyAI 建立新的。
    • 投影片備註: 投影片顯示時段的輕度清理逐字稿片段(建議)、逐字片段,或帶有時間碼的簡短摘要。
    • 長度超過 4000 個字元的片段(Slides 備註限制):使用「[…]」標記縮短(使用者上次的選擇)或分割投影片。
    • 格式「與上次相同」(建議):詳細且接近原始;問題的答案作為談話中的投影片;廣告和組織部分略過;結尾處有整體重點和統一的連結列表。
    • 講者人數——如果描述未明確說明(說話者辨識需要)。
  3. 建立一個包含最終驗證步驟的任務列表。

步驟 1. 逐字稿

  • 現成逐字稿: 首先檢查——是否有講者標籤和逐詞時間戳記,長度是否與影片相符。如果一切正常,則無需重新執行。

  • AssemblyAI 金鑰。 在建立新的逐字稿之前,請檢查 assemblyai_key.txt 是否存在於資料夾根目錄且不為空。如果檔案遺失,請不要繼續此步驟並告知使用者:他們需要在 assemblyai.com 註冊,取得 API 金鑰並將其儲存到資料夾根目錄的 assemblyai_key.txt 中(或發送過來——然後將其儲存到該檔案,且不再其他地方重複)。最好在步驟 0 的規劃中立即說明。

  • 新逐字稿。 從較低解析度的副本中提取音訊,無需重新編碼:ffmpeg -i in.mp4 -vn -c:a copy audio.m4a。然後:

    python3 pipeline/transcribe_assemblyai.py audio.m4a <輸出> --key-file assemblyai_key.txt --lang <語言代碼> [--speakers --min-speakers N --max-speakers M] --submit-only
    python3 pipeline/transcribe_assemblyai.py - <輸出> --key-file assemblyai_key.txt --fetch --wait 150   # 重複直到完成
    
    • 對於非英語語音,請使用支援錄影語言的模型;截至 2026 年 10 月為止,這是 universal-2。
    • 只有在多人發言時才啟用說話者辨識:單一語音會產生錯誤的 A/B 標籤。
    • 必須將網域 api.assemblyai.com 加入允許清單(設定 → 功能)。如果代理伺服器回傳 403,請告知使用者且不要繞過。
    • 價格——每小時約 0.15 美元,說話者辨識每小時另加 0.02 美元。
  • 工作檔案 transcript_sent.txt:一行 = N [h:mm:ss] LABEL: sentence,其中 N 是從 1 開始的句子編號。config.json 和 overrides.json 引用這些編號。

  • 標籤 → 人物。 根據主持人稱呼人的方式(「Leonid,你先來,對吧?」)、描述和內容進行匹配。典型的說話者辨識錯誤:

    • 一個人被賦予兩個標籤;
    • 整個談話被視為一段話語;
    • 觀眾的短問題被歸因於鄰近的說話者。

    將修正寫入 config.json:names(標籤 → 姓名)、speaker_by_line(行號 → 姓名)、drop_lines(要移除的行號)。

  • 談話邊界: 將其記錄為時間碼——開場、每個談話及其問答、結尾。這是簡報的章節結構。

步驟 2. 幀

  • 解析度。 如果有兩個副本:對低解析度副本進行分析(--reduce 2),從高解析度副本取得文字和裁切(ffmpeg -ss <秒數> -i hd.mp4 -frames:v 1 hd/NNNNN.jpg)。如果只有一個副本:使用 --reduce 4(對於低解析度,使用 --reduce 2);大字體可直接從幀中讀取。
  • 分段提取。 device_bash 每次呼叫約有 180 秒的限制,且背景程序無法持久。
    python3 pipeline/extract_slides.py video.mp4 <輸出> --chunk 1000
    python3 pipeline/extract_slides.py video.mp4 <輸出> --skip-extract --reduce 4
    
    • ffmpeg 速度變化很大:在過去的運行中,從實時速度的 10 倍到 48 倍不等。在第一個區塊上測量速度,並選擇不大於 0.8 × 限制 × 速度的區塊大小。
    • 將呼叫包裹在 timeout 中;根據幀編號完成不完整的區塊。
    • 在兩個核心上並行執行兩個 ffmpeg 程序並不會更快。
    • 幀 NNNNN.jpg = 第 N−1 秒。
  • 視訊鏡頭。 遮罩會自動偵測。在 Google Meet 佈局(左側螢幕共享,右側攝影機)中不需要。講者的攝影機視窗通常位於右上角——裁切和 OCR 應避開它。
  • 審查。 查看連絡表(sheets/),而不是所有幀:將它們移動到雲端並打開。對於細節,使用 2×2 馬賽克圖:python3 pipeline/mosaic.py HD_DIR 輸出 前綴 00165 00179 …。
  • 動態投影片會從選取中遺漏:移動的背景不會產生穩定的片段。檢查講者的投影片編號(01/16、06/17…)。透過相鄰找到的投影片之間的秒數間隔尋找缺口,使用從明確幀列表構建的馬賽克圖。
  • 將檔案移動到雲端僅能從連線資料夾進行:首先將檔案從 VM 工作目錄(~/w…)複製到 _work/ 中。

步驟 3. 邏輯投影片

目標不是逐幀重複影片,而是獲得可以呈現的投影片。

  • 講者的投影片。 重新輸入文字(OCR 僅是草稿);將圖表和螢幕截圖作為裁切插入。編輯器中顯示縮圖列的同一張投影片、放大或暫停的版本都是重複的;請使用全螢幕的那張。
  • 看板(Miro、Excalidraw)。 一張投影片 = 講者正在談論的看板區塊;對同一區塊進行平移和縮放是重複的。如果看板隨著談話進行而逐漸填滿,請取最後一個完整幀,並按區塊將其分割成投影片。
  • 應用程式介面。 選取顯示結果的畫面(表格、報告、儀表板、機器人回覆),而不是中間的點擊操作。
  • 帶有滾動的即時網站示範——不要作為幀,而是從逐字稿中重新敘述(「來自講者話語的投影片」)。
  • 全螢幕視訊鏡頭不是投影片;其內容應放入來自講者話語的投影片中。
  • 問答——放在談話結尾的獨立投影片:問題(附提問者姓名)和答案要點。
  • 主持人進行的廣告和組織部分:跳過。簡要提及講者自己的廣告(課程、定價)作為參考,除非使用者另有要求。
  • 簡報結構:
    • 封面和議程;
    • 每個談話:章節標題投影片、內容、問答、「連結與服務」投影片;
    • 整體重點——標記為「綜合整理」,並包含講者間的矛盾;
    • 統一的連結列表。
  • 對於每張投影片,記錄一個帶有談話前綴(l-、v-…)的 ID、來源幀和螢幕顯示間隔。

步驟 4. 圖片

  • 將全尺寸幀上的裁切座標儲存到 pipeline/crops_<YYYY-MM-DD>[_<講者>].json,格式為 {"name": ["00556.jpg", x0, y0, x1, y1]}。
  • 裁切:低解析度使用 python3 pipeline/crop_images.py FRAMES crops.json 輸出 --scale 2 --jpg,高解析度使用 --scale 1 --jpg。
  • 請勿檢查或隱藏幀和研討會資料中的個人資料(姓名、聯絡方式、登入資訊、通訊內容):原樣保留。

步驟 5. 文字、OCR、QR 碼、數字

  • OCR。 在使用者的電腦上,tesseract 通常只有英文。對於其他語言,請使用雲端:apt-get install tesseract-ocr-<語言代碼>,將相機視窗塗白,將幀放大 1.5 倍,tesseract -l <語言代碼>+eng。對照幀檢查結果:姓名可能會失真。
  • QR 碼: 在高解析度幀上使用 cv2.QRCodeDetector,結果儲存在 qr.json 中。
  • 數字。 使用腳本從投影片重新計算列總和、百分比和諸如「每個潛在客戶約 1,700 美元」這類數字。如果發現差異,請勿修正;請註明:「列總和為 60.3k,但投影片標示為 64k」。對於從未標籤圖表中讀取的值,請標記為「≈」。

步驟 6. 連結

  • 來源: 幀中的網址、QR 碼、語音、活動描述(Telegram 帳號)。ASR 會扭曲名稱(invoice.com → 「invoisin」、Gwen → Qwen、JLM → GLM),因此請從幀或搜尋中取得正確的拼寫。
  • 驗證。 使用 WebSearch 或 WebFetch 檢查每個連結,並在投影片頁尾註明檢查日期。諸如 Product Hunt(producthunt.com)和 There's An AI For That(theresanaiforthat.com)這類目錄可以快速提供服務的官方網址和描述。
  • 無法打開——請勿使用 curl 或鏡像站繞過。t.me 常回傳 429:請勿重試;標記為「來自投影片的網址,頁面無法打開」。
  • 找不到——如實說明:「找不到該服務」、「連結已承諾稍後提供」。
  • 放置位置。 每個談話的最後一張投影片:包含一行註解的連結。在其備註中,提供更多細節:服務內容、來自網站的價格、講者如何使用、哪些未找到。在簡報結尾——一張統合投影片:按類別列出講者和工具。

步驟 7. 備註——逐字稿片段

  • 間隔。 ranges.json——[["slide-id", start_sec, end_sec], …],在整個錄音中沒有間隙或重疊。根據投影片切換幀和語意設定邊界:講者通常在切換投影片之前就開始討論下一張。
  • 產生: python3 pipeline/clean_transcript.py <活動資料夾>/_work 建立 notes.json 並印出備註長度(當長度超過 3700 時顯示 <-- LONG)。
  • 輕度清理:
    • 腳本中的 ASR 錯誤字典 REPL:保留通用的取代規則,新增特定於該研討會的取代規則;
    • 句子開頭的填充詞(腳本中的 FILL 列表)會自動移除;
    • 在 overrides.json 中逐行修正亂碼句子("行號": "文字" 或 null),保留講者的意思和詞序;將不明確的部分標記為「[錄音中聽不清楚]」;
    • 有覆寫規則的行不會再次被清理。
  • 產生後檢查: 確保沒有重複的句子(覆寫規則可能導致相鄰行重複)且沒有遺漏的行(區間內的每一行都應在備註中或故意在 drop_lines 中)。
  • 備註格式(使用簡報的語言書寫):
    錄音片段 1:31:02–1:33:05:
    [1:31:02] Artyom:…
    [1:31:09] Stanislav:…
    
    1–2 行備註:看板文字、數字差異、姓名釐清。
    
  • 4000 字元限制。 如果更長,根據使用者在步驟 0 的決定,使用「[…]」縮短或分割投影片。

步驟 8. 在 Claude Slides 中組裝

  • 從 Slides 類型建立一個構件(Artifact 快速入門,意圖為 slides),並遵循其 SKILL.md。根據經驗重要的事項(截至 2026 年 10 月的類型規則):
    • 首先建立包含完整順序和章節的 deck.json(每個談話一個章節)

相關技能