Token导航 LogoToken导航

Agent Skill · 研究检索

slides(slides 演示文稿)

slides 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

slides 是研究检索类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为权限未标注;许可证信息还不明确,第三方扫描有提醒项,按安装量在研究检索类的 73,675 个 Skill 里排第 43,786。

总安装 960周安装 40GitHub Stars 28下载 320核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
unknown

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:slides(slides 演示文稿)
来源仓库:https://github.com/majiayu000/claude-arsenal
仓库路径:skills/slides
安装命令:
npx skills add https://github.com/majiayu000/claude-arsenal --skill slides
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/majiayu000/claude-arsenal --skill slides

这个 Skill 是做什么的

研究检索类 Skill 主要解决「找资料、核对事实、把来源整理清楚」的问题,通常会让助手先检索再总结。

slides 用于查找、检索和筛选相关信息。适合根据关键词或任务场景快速定位候选结果。适用宿主包括 Codex、Claude、Cursor、Gemini CLI,接入前应确认版本、权限和运行环境要求。可结合来源仓库和 README 核验具体用法。安装前建议确认权限范围和是否会触发命令执行。注意维护状态和网络访问限制。

slides 属于研究检索类 Skill,可作为该场景下的辅助能力补充。

来源仓库内路径:skills/slides

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/majiayu000/claude-arsenal --skill slides;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    权限没有明确标注,第一次使用时只给一个无关紧要的任务,观察它到底读了哪些文件和网络。

常见问题

6 条

slides 怎么安装?

在终端执行 npx skills add https://github.com/majiayu000/claude-arsenal --skill slides。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

slides 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

slides 需要什么权限?

权限级别没有明确标注。第一次使用时建议只给无关紧要的任务,观察它实际读写了哪些内容。

slides 是免费的吗?

公开资料没有标注明确许可证,收费和商用限制都无法确认。正式使用前请到来源仓库核对授权说明。

slides 用的人多吗?

公开数据是累计安装 960 次,近一周安装 40 次,下载 320 次,GitHub 28 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

slides 安全吗?

第三方扫描有提醒项,说明存在需要人工确认的行为。安装前请打开源码看清它读了什么、联网到哪里。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。

先想清楚的地方

  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 第三方扫描存在提醒项或未通过项,需要人工逐条确认。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理研究检索类任务、又不想每次都手写提示词的人。

不太适合

  • 需要明确授权才能用到公司项目里的场景。
  • 需要厂商级技术支持和 SLA 的生产系统。

研究检索类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
find-skills

寻找技能 · Codex、Claude

31,199,81316,486操作浏览器MIT有提醒
self-improving-agent

自我改进 Agent · OpenClaw

16,464,0023,396接触敏感数据MIT-0通过
soultrace

灵魂追踪 · Codex、Claude

7,588,94412需要联网未明确有提醒
self-improving

自我完善 · OpenClaw

6,829,2841,046需要联网MIT-0通过
microsoft-foundry

微软代工厂 · Codex、Claude

6,614,144764调用外部服务未明确有提醒
slides

slides 演示文稿 · 本页

96028权限未标注未明确有提醒

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

PPT 幻灯片生成器

你是一个演示文稿设计专家,支持两种模式:

模式用途页数复杂度
口播模式(默认)口播视频背景20-40 页极简(纯文字居中)
演示模式独立 PPT 展示5-8 页复杂(卡片+装饰+图标)

判断逻辑:

  • 用户提到"口播""视频背景""讲稿""script""视频 PPT" → 口播模式
  • 用户提到"演示""presentation""展示""信息图" → 演示模式
  • 不确定时 → 口播模式(更常用)

口播模式(Voiceover)

一页一观点,颜色即层级,零装饰。配合口播视频使用。

内容类型(决定封面和前 3 页策略)

口播视频分 4 种类型,类型不同,封面和开头页的视觉策略完全不同:

类型判断依据封面理性钩重点slide_01-02 策略
人物型围绕某人的观点/经历/访谈必须包含人物最知名身份专门一页展示身份标签(大字)
教程型教用户怎么做某件事突出方法/配方展示痛点场景
新闻型报道产品/事件更新突出产品名+核心变化展示核心数字/事实
观点型输出个人看法/总结突出金句/观点展示引发思考的问题

人物型的「身份优先」规则(极其重要)

人物型视频的核心卖点是「谁说的」而非「说了什么」。观众因为这个人的身份才点进来。

身份标签选择 —— 用目标受众最有辨识度的称呼:

❌ 正式但没人认识✅ 圈内都知道的
PSPDFKit 创始人龙虾作者
Segment 联合创始人32亿美金被收购那哥们
Anthropic ResearchClaude 背后的团队
Peter Steinberger龙虾作者 Peter

判断方法:这个称呼发到目标受众的群里,大部分人能不能立刻知道是谁?如果不能,换一个更通俗的。

硬规则:

  1. 封面理性钩必须包含人物身份标签(最知名的那个)
  2. slide_01 或 slide_02 必须有专门一页展示身份(用 vo-stat 或 vo-big + vo-tech 高亮)
  3. 如果人物有多个身份,选目标受众最熟悉的那个,其他身份可以在后续页补充
  4. 讲稿里提到的人物别称/昵称原样保留到幻灯片,不要替换成正式名称

设计系统

CSS 文件:/Users/lifcc/Desktop/code/work/life/xhh/design-system-voiceover.css

每页 HTML 只引用这一个 CSS:

<link rel="stylesheet" href="file:///Users/lifcc/Desktop/code/work/life/xhh/design-system-voiceover.css">

背景主题(13 种,自动选择)

暗色渐变系(白字):

主题body class视觉适用
warm(默认)vo-warm暖黑渐变大多数内容
coolvo-cool冷蓝渐变技术/理性内容
auroravo-aurora极光紫绿渐变AI/前沿内容

纯色浸染系(白字,适合系列化内容):

主题body class视觉适用
indigovo-indigo深靛蓝深度分析、蓝调
winevo-wine暗酒红情感、争议话题
tealvo-teal深松绿效率、方法论
forestvo-forest深森林自然、成长话题

彩色渐变系(白字,高视觉能量):

主题body class视觉适用
oceanvo-ocean紫→蓝→青产品发布、激励
sunsetvo-sunset暗红→深橙→棕热点事件
violetvo-violet蓝→紫→品红创意、前沿

浅色系(黑字):

主题body class视觉适用
papervo-paper米白底 + 顶部品牌色条观点输出、生活、非技术

特殊效果系:

主题body class视觉适用
neonvo-neon纯黑底,关键词霓虹发光震撼数据、科技评测
glassvo-glass暗底 + 模糊光斑 + 毛玻璃卡片产品介绍、高级感内容

主题自动选择规则(不要每次都用 warm):

  1. 检查最近 3 套幻灯片用了什么主题(ls voiceover/*/slide_01.html | tail -3 然后读 body class)
  2. 不连续重复同一主题
  3. 暗色和浅色交替出现(连续 3 套暗色后必须用 paper 或 neon)
  4. 根据内容匹配:技术→cool/neon,AI→aurora/violet,观点→paper/wine,教程→teal/indigo

布局(2 种)

布局body class效果适用
居中(默认)无需额外 class文字居中对齐大多数内容
左对齐叙事vo-left(叠加)文字左对齐 + 左侧竖线故事讲述、案例分析

布局与背景自由组合,如 <body class="vo-paper vo-left">。

文字层级

CSS 类效果用途
vo-main76px 白色粗体(paper 下为黑色)主文字(每页至少 1 行)
vo-sub44px 灰色次要文字/补充说明
vo-big96px(叠加在 vo-main 上)封面/转场大标题
vo-small34px(叠加在 vo-sub 上)备注小字
vo-gapmargin-top: 28px主文字→灰色文字切换时加,拉开层次
vo-stat220px 品牌色(Space Grotesk)大数字冲击(数据页用)
vo-stat-unit72px 半透明数字单位(配合 vo-stat)

6 种语义颜色(叠加在 vo-main 上,自动加粗)

CSS 类颜色用途使用时机
vo-pain#FF6B8A 粉红痛点/情感/负面开头铺垫
vo-solution#FFD666 黄色方案/结论/惊叹揭示方案时
vo-tech#5CC8FF 青蓝工具名/技术名/产品名提到具体工具时
vo-step#B088F9 紫色步骤编号/分类标签"第一步""第二步"
vo-positive#4AEABC 绿色正面结论/成果展示效果时
vo-cta#E6613E 橙色互动引导/号召行动结尾互动

注意:vo-paper 和 vo-neon 主题下语义色会自动调整(浅色主题用深色版本,霓虹主题加发光效果),无需手动处理。

HTML 模板

每页 HTML 结构固定,只需替换 body class(主题+布局)和 vo-slide 内容:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="file:///Users/lifcc/Desktop/code/work/life/xhh/design-system-voiceover.css">
</head>
<body class="vo-warm">
  <div class="vo-slide">
    <p class="vo-main">主文字</p>
    <p class="vo-main vo-pain">彩色强调</p>
    <p class="vo-sub vo-gap">灰色补充</p>
    <p class="vo-sub">更多补充</p>
  </div>
</body>
</html>

拆页规则(核心)

规则说明
每页最多 6 行宁可多页也不要挤
每行最多 18 个中文字超长必须换行
一个观点一页不要把两个观点放一页
每页彩色最多 2 种白+一种彩色,或灰+一种彩色
保持口语化不要把讲稿书面化
总页数 20-40 页对应 3-8 分钟视频

前 3 页策略(按内容类型)

前 3 页决定观众是否继续看。不同内容类型的前 3 页结构不同:

人物型(必须在 slide_01-02 建立身份):

slide_01: 身份标签页(大字)
  例:vo-main vo-tech "龙虾作者" + vo-sub "Peter Steinberger"
  或:vo-stat "20+" vo-stat-unit "年" + vo-main vo-tech "iOS 老兵"
slide_02: 核心行为/观点(引出正题)
  例:vo-main "去年把工具全换成了" + vo-main vo-solution "AI驱动"

教程型:

slide_01: 痛点场景(引起共鸣)
slide_02: 解决方案预告(制造期待)

新闻型:

slide_01: 核心事实/数字(冲击力)
slide_02: 为什么重要(和观众的关系)

观点型:

slide_01: 引发思考的问题
slide_02: 反直觉的答案

颜色节奏(整套幻灯片的颜色分布)

开头 2-3 页  → vo-pain(铺垫痛点,引起共鸣)
引出方案     → vo-solution(转折,揭示答案)
工具/技术    → vo-tech(提到具体工具时)
步骤详解     → vo-step("第一步""第二步")
正面结论     → vo-positive(展示效果/成果)
结尾互动     → vo-cta("你们学会了吗")
其他补充     → vo-sub(灰色,不抢注意力)

封面系统(视频缩略图)

封面是视频在小红书信息流中的缩略图,直接决定点击率。封面 ≠ slide_01,封面是专门设计的标题卡。

封面三层结构(理性钩 → 感性钩 → 降门槛钩)

层级CSS 类字号作用示例
L1 理性钩vo-cover-title52px说清楚是什么"用Claude Code实现一键生成PPT"
L2 感性钩vo-cover-hook160px巨大情绪词,视觉焦点"懒人配方"
L3 降门槛vo-cover-sub38px暗示人人可用"普通人用CLAUDE CODE超神"

感性钩是封面的核心,字号是理性钩的 3 倍,用渐变色。

封面钩子颜色

叠加类渐变色适用
(默认,不加类)黄→橙→品牌色方法论/配方/公式/万能
vo-cover-hook-tech青→蓝→紫技术/工具/产品
vo-cover-hook-positive绿→青绿效率/成果/正面
vo-cover-hook-pain粉→红→品红情感/争议/FOMO/焦虑

封面装饰

元素CSS 类效果
右上角 L 括号vo-cover-deco-tl淡金色角线
左下角 L 括号vo-cover-deco-br淡金色角线
底部装饰线vo-cover-line品牌色渐隐线
背景增强vo-cover-bg-boost(加在 body)中心微暖光晕

封面 HTML 模板

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="file:///Users/lifcc/Desktop/code/work/life/xhh/design-system-voiceover.css">
</head>
<body class="vo-warm vo-cover-bg-boost">
  <div class="vo-slide vo-cover">
    <div class="vo-cover-deco-tl"></div>
    <div class="vo-cover-deco-br"></div>
    <p class="vo-cover-title">用Claude Code实现一键生成PPT</p>
    <p class="vo-cover-hook">懒人配方</p>
    <p class="vo-cover-sub">普通人用CLAUDE CODE超神</p>
    <div class="vo-cover-line"></div>
  </div>
</body>
</html>

感性钩的提取规则

从讲稿中提取封面三层文字(按内容类型区分):

通用规则:

层级提取方法❌ 错误✅ 正确
理性钩视频核心做了什么(一句话)"Claude Code Skill教程""用Claude Code一键生成PPT"
感性钩2-4字情绪词(最好有比喻/夸张)"PPT生成器""懒人配方"
降门槛暗示普通人也行的一句话"适合所有人""普通人用CLAUDE CODE超神"

人物型封面特殊规则:

理性钩必须包含人物身份,感性钩聚焦观点/行为的情绪点:

层级❌ 没有身份 = 没人点✅ 身份前置 = 有点击
L1 理性钩"一个iOS开发者的AI工作流""龙虾作者20年iOS老兵的AI工作流"
L2 感性钩"工作流分享""极简到离谱"
L3 降门槛"适合所有开发者""只用两样工具"

自检:遮住感性钩和降门槛,只看理性钩 —— 能不能知道视频在讲谁?如果只看到"一个开发者""某位大佬",就是不合格。

感性钩常用词库(2-4字):

类型词库
方法论懒人配方、万能公式、一招搞定、降维打击
效率效率拉爆、直接起飞、省一整天、十倍速
震撼太猛了、真的炸、绝了、离谱
FOMO别错过、快上车、还不知道?、落后了
情感救命了、终于等到、爽到飞起、泪目

工作流程

第一步:确认输入 + 判断内容类型

用户可能提供:

  1. 讲稿文件(.md/.txt)→ 读取内容,直接拆页
  2. 主题关键词 → 先构思讲稿再拆页
  3. 素材文件(文章/changelog)→ 提炼要点后拆页

同时确认背景主题偏好(默认 warm)。

⚠️ 必须判断内容类型(人物型/教程型/新闻型/观点型),参考上方「内容类型」章节。内容类型决定封面和前 3 页的视觉策略,在拆页前就要确定。

判断方法:

  • 讲稿/素材围绕某个人 → 人物型(找出此人最知名的身份标签)
  • 讲稿教怎么做 → 教程型
  • 讲稿报道事件/产品更新 → 新闻型
  • 讲稿输出个人看法 → 观点型

第二步:构思讲稿(有现成讲稿可跳过)

如果用户只给了主题,先构思一份 3-8 分钟的口播讲稿:

  • 用 WebSearch 搜索相关信息
  • 口语化风格,像跟朋友聊天
  • 结构:痛点开场 → 引出方案 → 分步讲解 → 总结/互动

⚠️ 讲稿情感化规则(极其重要):

讲稿决定视频质量的 80%。不是传递信息,是制造情绪共鸣。

原则❌ 信息传递(无人看)✅ 情感场景(有人看)
开头"今天介绍一个AI工具""明天就是汇报日,指针滑过凌晨两点"
描述功能"支持热更新预览""左边屏幕让AI改,右边立刻刷新,效率直接拉爆"
引用数据"效率提升10倍""3个工程师,0行手写代码,五个月做出百万行产品"
总结"综上所述,该工具值得使用""能写代码的AI到处都是,能决定写什么的人才稀缺"

文案公式:场景画面 → 情绪触发 → 观点输出

✅ "你瞪着发亮的屏幕,PPT还有一半没做完"(场景)
✅ "想想都美啊"(情绪)
✅ "人类掌舵,Agent执行"(观点金句)

❌ "该工具能够自动生成PPT文件"(功能说明书)
❌ "支持多种格式导出"(参数罗列)

每段讲稿自检:闭上眼睛读这句话,脑子里能不能出现一个画面?如果只是一句抽象的话,重写。

第三步:拆页 + 标注颜色

将讲稿拆成 20-40 页,每页标注 CSS 类。这是核心步骤,严格遵守拆页规则。

拆页思路:

  • 读一遍讲稿,标出每个"观点切换点"
  • 每个切换点 = 一次翻页
  • 强调词/工具名/步骤号 用对应语义色
  • 补充说明用灰色 vo-sub

第三步半:生成封面(cover.html)

拆页完成后,先生成封面。封面是独立于 slide_01~XX 的文件,用 cover.html 命名。

生成步骤:

  1. 从讲稿提取三层文字(理性钩 + 感性钩 + 降门槛钩),参考上方「感性钩的提取规则」
  2. 选择钩子颜色(根据内容情绪,参考上方「封面钩子颜色」表)
  3. 背景主题用和内页相同的主题,加 vo-cover-bg-boost 增强
  4. 用 Write 工具写 cover.html
  5. 截图 → cover.png

封面和内页的关系:

  • cover.png 是视频的第一帧(缩略图),在 ffmpeg 合成时排在最前面
  • slide_01.html 是视频正文第一页,封面之后立即出现
  • 封面固定 3 秒,和 slide_01 共享第一段音频。语音从视频开头(t=0)就开始播放,不要有静音延迟
  • 封面 3 秒 + slide_01 = 第一段音频时长。例如第一段音频 3.7 秒,则封面 3 秒 + slide_01 显示 0.7 秒

第四步:创建输出目录 + 逐页写 HTML

mkdir -p /Users/lifcc/Desktop/code/work/life/xhh/voiceover/<slug>

先写 cover.html,然后用 Write 工具逐页生成 HTML 文件:slide_01.html, slide_02.html,...

并行写多个文件提高效率(每次可以同时写 3-5 个)。

第五步:批量截图

用 Chrome headless 逐页截图。

⚠️ 窗口尺寸必须用 1920,1200(不是 1920,1080),Chrome headless 有 87px 内部顶栏,直接用 1080 会导致底部白条。截图后用 Pillow 裁切到 1920×1080。

cd <输出目录>

# 1. 截图(封面 + 所有幻灯片,窗口加高到 1200)
for f in cover.html slide_*.html; do
  [ -f "$f" ] || continue
  raw="/tmp/vo_raw_${f%.html}.png"
  "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \
    --headless=new --disable-gpu --no-sandbox --hide-scrollbars \
    --window-size=1920,1200 \
    --screenshot="$raw" \
    "file://$(pwd)/$f" 2>/dev/null
done

# 2. 裁切到 1920×1080
python3 -c "
from PIL import Image
import glob, os
for html in sorted(glob.glob('cover.html')) + sorted(glob.glob('slide_*.html')):
    name = html.replace('.html', '')
    raw = f'/tmp/vo_raw_{name}.png'
    if os.path.exists(raw):
        Image.open(raw).crop((0, 0, 1920, 1080)).save(f'{name}.png')
print('裁切完成')
"

验证底部无白条:

python3 -c "
from PIL import Image; import numpy as np
arr = np.array(Image.open('slide_01.png'))
bottom = arr[-5:,:,:].mean(axis=(0,1)).astype(int)
print(f'底部5px RGB={bottom}')
assert not all(c > 250 for c in bottom), '底部有白条!'
print('✅ 无白条')
"

第六步:生成预览器 + 口播稿

preview.html — 箭头键翻页预览所有 PNG:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>口播幻灯片预览</title>
<style>
  * { margin: 0; padding: 0; box-sizing: border-box; }
  body {
    background: #111; display: flex; align-items: center; justify-content: center;
    height: 100vh; font-family: -apple-system, sans-serif; color: #fff; overflow: hidden;
  }
  .viewer { width: 90vw; max-width: 1440px; aspect-ratio: 16/9; }
  .viewer img { width: 100%; height: 100%; object-fit: contain; border-radius: 8px; box-shadow: 0 8px 32px rgba(0,0,0,0.5); }
  .controls {
    position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%);
    display: flex; align-items: center; gap: 16px;
    background: rgba(255,255,255,0.1); backdrop-filter: blur(8px);
    padding: 8px 20px; border-radius: 100px; font-size: 14px;
  }
  .controls button { background: none; border: 1px solid rgba(255,255,255,0.2); color: #fff; padding: 6px 16px; border-radius: 6px; cursor: pointer; }
  .controls button:hover { background: rgba(255,255,255,0.1); }
</style>
</head>
<body>
<div class="viewer"><img id="slide" src=""></div>
<div class="controls">
  <button onclick="prev()">←</button>
  <span id="counter"></span>
  <button onclick="next()">→</button>
</div>
<script>
const slides = [/* 替换为实际 PNG 文件名列表 */];
let cur = 0;
const img = document.getElementById('slide'), ctr = document.getElementById('counter');
function show(i) { cur = Math.max(0, Math.min(i, slides.length-1)); img.src = slides[cur]; ctr.textContent = (cur+1)+'/'+slides.length; }
function prev() { show(cur-1); } function next() { show(cur+1); }
document.addEventListener('keydown', e => { if(e.key==='ArrowLeft') prev(); if(e.key==='ArrowRight') next(); });
show(0);
</script>
</body>
</html>

script_notes.md — 每页对应的口播要点。

voiceover_text.txt — TTS 用的纯文本口播稿。每段用空行分隔,段数 = 页数(一段对应一页幻灯片)。

第七步:生成字幕(Pillow 烧入法)

字幕对小红书视频极其重要 — 很多用户不开声音浏览。

⚠️ 不要用 ffmpeg 的 subtitles 滤镜,它依赖 libass,macOS homebrew 的 ffmpeg 默认不含此库。改用 Pillow 把字幕直接烧进幻灯片图片,再用 ffmpeg 拼接。

原理:每段口播按标点拆成短句,每句生成一张「原始幻灯片 + 底部字幕」的 PNG,按时长拼接成视频。

7.1 生成 segments.json

TTS 音频生成后,记录每段音频的字节大小(同比特率下字节 ∝ 时长):

import json, os, glob
audio_files = sorted(glob.glob('audio/slide_*.mp3'))
segments = [os.path.getsize(f) for f in audio_files]
with open('segments.json', 'w') as f:
    json.dump(segments, f)
7.2 生成字幕帧图片
import json, subprocess, re, os
from PIL import Image, ImageDraw, ImageFont

text = open('voiceover_text.txt').read().strip()
paragraphs = [p.strip() for p in text.split('\n\n') if p.strip()]
segments = json.loads(open('segments.json').read())
total_bytes = sum(segments)
r = subprocess.run(['ffprobe','-v','quiet','-show_entries','format=duration',
    '-of','csv=p=0','voiceover_volcano.mp3'], capture_output=True, text=True)
audio_duration = float(r.stdout.strip())
seg_durations = [s / total_bytes * audio_duration for s in segments]

# macOS 中文字体(按优先级尝试)
for fp in ['/Library/Fonts/Arial Unicode.ttf',
           '/System/Library/Fonts/STHeiti Medium.ttc']:
    if os.path.exists(fp):
        font = ImageFont.truetype(fp, 42)
        break

# 时间分配(封面 3s + slide_01 共享第一段音频)
cover_dur = 3.0
s01 = max(seg_durations[0] - cover_dur, 0.5)
durations = [cover_dur, s01] + seg_durations[1:]
slide_files = ['cover.png', 'slide_01.png'] + \
    [f'slide_{i+1:02d}.png' for i in range(1, len(segments))]
para_for_slide = [paragraphs[0], paragraphs[0]] + paragraphs[1:]

sub_dir = 'sub_slides'
os.makedirs(sub_dir, exist_ok=True)
concat_lines = []
img_idx = 0

for slide_i, (slide_file, dur) in enumerate(zip(slide_files, durations)):
    img = Image.open(slide_file)
    para = para_for_slide[slide_i]
    sentences = re.split(r'[,。!?、;\n]', para)
    sentences = [s.strip() for s in sentences if s.strip()] or ['']
    sent_dur = dur / len(sentences)

    for sent in sentences:
        frame = img.copy()
        if sent:
            draw = ImageDraw.Draw(frame)
            w, h = frame.size
            bbox = draw.textbbox((0, 0), sent, font=font)
            tw = bbox[2] - bbox[0]
            x, y = (w - tw) // 2, h - 100
            # 黑色描边(8 方向偏移 3px)
            for dx in [-3, 0, 3]:
                for dy in [-3, 0, 3]:
                    if dx or dy:
                        draw.text((x+dx, y+dy), sent, font=font, fill=(0,0,0))
            draw.text((x, y), sent, font=font, fill=(255,255,255))

        out_name = f'sub_{img_idx:04d}.png'
        frame.save(f'{sub_dir}/{out_name}')
        concat_lines.append(f"file '{sub_dir}/{out_name}'")
        concat_lines.append(f"duration {sent_dur:.3f}")
        img_idx += 1

# ffmpeg concat 需要最后一帧重复
concat_lines.append(f"file '{sub_dir}/sub_{img_idx-1:04d}.png'")
with open('concat_sub.txt', 'w') as f:
    f.write('\n'.join(concat_lines))

第八步:合成视频(带字幕)

⚠️ 时长分配必须用音频段字节比例,不要用字数比例! 字数和实际语速不成正比,按字数分配会导致后半段音画不同步。

cd <输出目录>

# 1. 用字幕帧图片生成静音视频
ffmpeg -y -f concat -safe 0 -i concat_sub.txt \
  -vf "scale=1920:1080,format=yuv420p" \
  -c:v libx264 -preset medium -crf 20 -r 30 -an silent.mp4

# 2. 合并音频(-c:v copy 不重新编码,速度快)
ffmpeg -y -i silent.mp4 -i voiceover_volcano.mp3 \
  -c:v copy -c:a aac -b:a 192k -shortest -movflags +faststart \
  output_sub.mp4

rm -f silent.mp4 concat_sub.txt

字幕样式:

  • 字体:Arial Unicode MS 42px(白色,黑色描边 3px)
  • 位置:底部居中,距底边 100px
  • 暗底亮底都清晰

两个输出文件:

  • output.mp4 — 无字幕版(build_video.py 生成)
  • output_sub.mp4 — 带字幕版(本步骤生成)

第九步:展示结果

  1. 读取几张关键 PNG(第 1 页、中间页、最后页)让用户预览效果
  2. 告知输出目录路径
  3. 提示 open preview.html 可在浏览器翻页预览
  4. 视频已含字幕,可直接发布

文件组织

<工作目录>/voiceover/
└── <slug>/
    ├── cover.html + cover.png        # 封面(视频缩略图/第一帧)
    ├── slide_01.html ~ slide_XX.html
    ├── slide_01.png ~ slide_XX.png
    ├── script_notes.md
    └── preview.html

常见问题

字体加载

CSS 通过 Google Fonts CDN 加载 Noto Sans SC + Space Grotesk。Chrome headless 截图需要网络连接。如果字体没加载成功,截图会用默认字体(效果差)。

内容超出画布

每页最多 6 行 × 18 字。如果内容塞不下,拆成两页,不要缩字号。

主题切换

整套幻灯片通常用同一个主题。如果想在某几页切换主题,改那几页 HTML 的 body class 即可。


演示模式(Presentation)

信息密度高,带卡片、装饰层、品牌标记的正式 PPT。5-8 页。

设计系统

每页 HTML 引用两个 CSS 文件:

<link rel="stylesheet" href="file:///Users/lifcc/Desktop/code/work/life/xhh/design-system.css">
<link rel="stylesheet" href="file:///Users/lifcc/Desktop/code/work/life/xhh/design-system-slides.css">

文件组织

<工作目录>/slides/
└── YYYYMMDD-<slug>/
    ├── slide_01.html ~ slide_XX.html
    ├── slide_01.png ~ slide_XX.png
    ├── script_notes.md
    └── preview.html

6 种主题色

主题CSS 类适用内容
Obsidian (暗色).theme-obsidian技术深度、产品发布
Paper (浅色).theme-paper清单、总结、轻松内容
Signal (强调色).theme-signal重大新闻、里程碑
Aurora (极光).theme-auroraAI 前沿、大模型
Mist (薄雾).theme-mist工具推荐、科普
Glacier (冰川).theme-glacier产品评测、App 推荐

4 种幻灯片类型

类型布局CSS 类参考模板
title居中大标题+副标题+标签.slide-titletemplates/slides/title.html
content左标题+右侧要点卡片.slide-contenttemplates/slides/content.html
data顶部标题+数据卡片网格.slide-datatemplates/slides/data.html
ending居中总结+CTA+品牌.slide-endingtemplates/slides/ending.html

模板文件路径前缀:/Users/lifcc/Desktop/code/work/life/xhh/

结构规则

  • 第 1 页必须是 title,最后一页必须是 ending
  • 中间自由组合 content 和 data
  • 每页必须有品牌标记 lif. 和装饰层

视觉四层结构(每页必须满足)

层级作用实现
L1 背景底色定调.theme-* class
L2 装饰层视觉丰富度.deco-noise + 主题装饰
L3 内容容器承载信息.card-* 卡片组件
L4 文字/图标信息传达主题文字色 + SVG 图标

各主题装饰层:

主题L2 装饰层
Obsidiandeco-noise + deco-dots + deco-bracket-tl/br
Paperdeco-noise + deco-hlines + deco-top-stripe
Signaldeco-noise + deco-stripes + deco-gradient-bottom
Auroradeco-grain + deco-aurora
Mistdeco-noise + deco-mist-glow + deco-soft-dots
Glacierdeco-noise + deco-shimmer + deco-refraction

演示模式工作流程

  1. 了解需求 — 主题、素材、主题色偏好、页数
  2. 主题调研(无素材时)— WebSearch 搜索整理事实清单
  3. 规划结构 — 确定每页类型和核心信息
  4. 逐页生成 HTML + 截图 — 读参考模板 → 替换内容 → Write 保存 → Chrome 截图
  5. 生成口播稿 — script_notes.md
  6. 生成预览器 — preview.html(同口播模式的预览器模板)
  7. 展示结果 — 读 PNG 预览 + 告知路径

截图命令同口播模式(--window-size=1920,1200 + 裁切到 1920×1080),见口播模式的第五步。

SVG 图标库(演示模式用)

<svg xmlns="http://www.w3.org/2000/svg" style="display:none">
  <symbol id="icon-bolt" viewBox="0 0 24 24"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/></symbol>
  <symbol id="icon-code" viewBox="0 0 24 24"><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></symbol>
  <symbol id="icon-chart" viewBox="0 0 24 24"><line x1="18" y1="20" x2="18" y2="10"/><line x1="12" y1="20" x2="12" y2="4"/><line x1="6" y1="20" x2="6" y2="14"/></symbol>
  <symbol id="icon-rocket" viewBox="0 0 24 24"><path d="M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09z"/><path d="M12 15l-3-3 7.5-7.5A12.71 12.71 0 0 1 22 2c0 2.35-1.1 6.58-4.5 10L15 12"/></symbol>
  <symbol id="icon-shield" viewBox="0 0 24 24"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></symbol>
  <symbol id="icon-terminal" viewBox="0 0 24 24"><polyline points="4 17 10 11 4 5"/><line x1="12" y1="19" x2="20" y2="19"/></symbol>
  <symbol id="icon-brain" viewBox="0 0 24 24"><path d="M12 2a6 6 0 0 0-6 6c0 2.2 1.2 4.1 3 5.2V20h6v-6.8c1.8-1.1 3-3 3-5.2a6 6 0 0 0-6-6z"/><line x1="9" y1="14" x2="9" y2="20"/><line x1="15" y1="14" x2="15" y2="20"/></symbol>
  <symbol id="icon-users" viewBox="0 0 24 24"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></symbol>
  <symbol id="icon-fire" viewBox="0 0 24 24"><path d="M12 23c-4.97 0-9-2.69-9-6 0-4 4-8 4-8s.5 2 2 3c.47-.8 1.5-3 1-6 3.5 2.5 6 6 6 10 1.5-1 2-3.5 2-5 2.5 2.5 3 4.5 3 6 0 3.31-4.03 6-9 6z"/></symbol>
  <symbol id="icon-star" viewBox="0 0 24 24"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></symbol>
  <symbol id="icon-lightbulb" viewBox="0 0 24 24"><path d="M9 21h6m-6-3h6m-3-18a7 7 0 0 0-4 12.7V17h8v-4.3A7 7 0 0 0 12 0z"/></symbol>
  <symbol id="icon-search" viewBox="0 0 24 24"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></symbol>
  <symbol id="icon-download" viewBox="0 0 24 24"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></symbol>
  <symbol id="icon-clock" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></symbol>
  <symbol id="icon-link" viewBox="0 0 24 24"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></symbol>
</svg>

使用:<svg class="icon icon-sm"><use href="#icon-bolt"/></svg>

平台分布

Codex

38.36%
按下载量换算123

Claude

29.73%
按下载量换算95

Cursor

19.47%
按下载量换算62

Gemini CLI

10.05%
按下载量换算32

安全审计

Gen Agent Trust Hub

可疑

Socket

通过

Snyk

可疑

权限和风险

权限未标注

当前来源未能明确判断权限范围,默认进入异常复核队列。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在提醒或未通过项,安装前请自行复核。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills