Communitygithub.com

nielssrb/视频转演示文稿

将研讨会、网络研讨会或会议录像转换为可编辑的幻灯片组:从视频帧中提取幻灯片、添加注释链接,并将转录摘录作为演讲者备注。

视频转演示文稿 是什么?

该技能专为 AI 代理(如 Claude Code 或类似工具)设计,用于自动化将录制的讲座或会议转变为结构化幻灯片组的工作流程。它避免手动重新观看整个视频,而是通过分析帧中的稳定片段来识别幻灯片,对转录文本进行去噪处理以创建准确的演讲者备注,并从视觉内容中提取链接和二维码。该技能支持视频帧中的光学字符识别(OCR)、基于 AssemblyAI 的转录(支持说话人分离)以及使用 ffmpeg 和 Python 脚本进行的本地处理,确保敏感数据不会上传到云端。它兼容 Mac(通过 Cowork 的绑定挂载)和 Unix 环境,并包括详细的规则,以确保准确性、处理矛盾信息并维护用户隐私。

兼容平台✓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 或 Figma 看板,也请勿使用 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. 检查活动文件夹:
    • 视频:分辨率、时长、帧率(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 <OUT> --key-file assemblyai_key.txt --lang <语言代码> [--speakers --min-speakers N --max-speakers M] --submit-only
    python3 pipeline/transcribe_assemblyai.py - <OUT> --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] 标签: 句子,其中 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 <OUT> --chunk 1000
    python3 pipeline/extract_slides.py video.mp4 <OUT> --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 OUT PREFIX 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 OUT --scale 2 --jpg,对于高分辨率使用 --scale 1 --jpg。
  • 不要检查或隐藏帧和网络研讨会材料中的个人数据(姓名、联系方式、登录名、通信):按原样保留。

步骤 5. 文本、OCR、二维码、数字

  • OCR。 在用户计算机上,tesseract 通常只有英语。对于其他语言,使用云端:apt-get install tesseract-ocr-<语言代码>,将摄像头窗口涂白,将帧放大 1.5 倍,tesseract -l <语言代码>+eng。对照帧检查结果:名称会失真。
  • 二维码: 在高分辨率帧上使用 cv2.QRCodeDetector,结果保存到 qr.json。
  • 数字。 使用脚本从幻灯片中重新计算行总和、百分比以及类似“≈1,700 per lead”的数字。不要修正差异;记录下来:“行总和为 60.3k,幻灯片显示为 64k”。将从未标记图表读取的值标记为“≈”。

步骤 6. 链接

  • 来源: 帧中的地址、二维码、语音、事件描述(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 中逐行修正乱码句子("line number": "text" 或 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 quickstart, intent slides),并遵循其 SKILL.md。根据经验(截至 2026 年 10 月的类型规则)重要的点:
    • 首先使用 deck.json 包含完整顺序和部分(每个演讲一个部分),然后每 3 张幻灯片一组进行发布(url + root);
    • 使用 Write 工具编写每张幻灯片,而不是使用脚本;每个文件一个 <section>,<aside> 作为最后一个子元素;不要通过渲染验证;
    • 资源:复制

…

[由于原始内容在步骤 8 处被截断,翻译仅覆盖已提供的内容。]

相关技能