Video2presentation:研討會錄影 → 簡報
決策的詳細歷史和測量數值記錄在 Video2presentation 資料夾中的 METHODOLOGY.md。如果此技能和 METHODOLOGY.md 不一致,請遵循此技能。將新的經驗教訓新增至 METHODOLOGY.md。
始終適用的規則
- 先規劃和提問。 在進行任何處理之前,請依照下列步驟向使用者說明計畫,並使用 AskUserQuestion 提出釐清問題(清單在步驟 0)。僅在收到答案後才開始工作。
- 回覆使用者。 使用使用者的語言(通常非英文),誠實且不諂媚。使用腳本計算所有數字。將資訊格式化為表格;僅在使用者要求時使用純文字。每次更新簡報後提供簡報連結。
- 安全性。
- 僅從檔案
assemblyai_key.txt讀取 AssemblyAI 金鑰。切勿列印或將其複製到雲端、筆記或構件中。 - 即使講者展示 Miro 看板,也請勿使用 Miro 或 Figma 整合:請從影片幀中擷取看板。
- 未經許可,請勿刪除使用者資料夾中的任何內容,包括
_work/工作資料夾。
- 僅從檔案
- 準確性。
- 請勿默默修正講者:在備註中用時間碼註明矛盾之處和數字差異。
- 使用腳本重新計算投影片中的數字。
- 檢查法律聲明,並在投影片上添加簡短的免責聲明。
- 將最終重點標記為綜合整理,而非講者的投影片。
- 影片不會上傳至雲端。 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. 偵察、規劃、提問
- 檢查活動資料夾:
- 影片:解析度、長度、fps(
ffprobe);是否有另一個解析度的副本; - 現成的逐字稿;
- 是否存在
assemblyai_key.txt——如果需要從頭開始建立逐字稿,則需要此檔案; - 活動描述(可選):姓名、Telegram 帳號、談話主題。它可能位於使用者訊息的結尾或 HTML 檔案中。如果沒有描述,請從錄影本身取得姓名和主題。
- 影片:解析度、長度、fps(
- 呈現計畫並使用 AskUserQuestion 提問。「建議」選項代表使用者之前的選擇:
- 逐字稿: 如果存在則使用現成的(建議),或使用 AssemblyAI 建立新的。
- 投影片備註: 投影片顯示時段的輕度清理逐字稿片段(建議)、逐字片段,或帶有時間碼的簡短摘要。
- 長度超過 4000 個字元的片段(Slides 備註限制):使用「[…]」標記縮短(使用者上次的選擇)或分割投影片。
- 格式「與上次相同」(建議):詳細且接近原始;問題的答案作為談話中的投影片;廣告和組織部分略過;結尾處有整體重點和統一的連結列表。
- 講者人數——如果描述未明確說明(說話者辨識需要)。
- 建立一個包含最終驗證步驟的任務列表。
步驟 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 美元。
- 對於非英語語音,請使用支援錄影語言的模型;截至 2026 年 10 月為止,這是
-
工作檔案
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),保留講者的意思和詞序;將不明確的部分標記為「[錄音中聽不清楚]」; - 有覆寫規則的行不會再次被清理。
- 腳本中的 ASR 錯誤字典
- 產生後檢查: 確保沒有重複的句子(覆寫規則可能導致相鄰行重複)且沒有遺漏的行(區間內的每一行都應在備註中或故意在
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(每個談話一個章節)
- 首先建立包含完整順序和章節的