关于 blog-audio
blog-audio 使用 Google 的 Gemini TTS 为博客文章生成语音版本,适用于文章作者和内容团队。支持摘要、全文朗读和双人对话模式,并提供语音选择及 HTML5 嵌入代码。
主要功能
- 01生成摘要或全文朗读
- 02制作双人对话脚本
- 03从语音目录中选择音色
- 04输出可用于 HTML5 嵌入的音频
- 05FFmpeg 可用时转换为 MP3
适用场景
- 01为博客文章提供音频版本
- 02制作简短的文章语音概览
- 03将文章改编为播客式对话
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ infrasity-labs/ dev-gtm-claude-skills --skill blog-audio安装后在 Claude Code 中输入/blog-audio确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/voices.mdscripts/__init__.pygenerate_audio.pyrequirements.lockrequirements.txtrun.pysetup_environment.py详细介绍
博客音频:使用 Gemini TTS 为博客文章配音
使用 Google 的 Gemini TTS 为博客内容生成专业配音。 提供三种模式:摘要(200–300 字的口播概述)、全文朗读 或双人播客对话。支持 30 种声音、80 多种语言,并可生成 HTML5 嵌入内容。
快速参考
| 命令 | 功能 |
|---|---|
/blog audio generate <file> | 为博客文章生成配音 |
/blog audio voices | 显示可用声音及其特点 |
/blog audio setup | 检查/配置 Gemini TTS 的 API 密钥 |
前置条件
- Python 3.11+(由
run.py自动管理 venv) GOOGLE_AI_API_KEY环境变量(与 blog-image 使用同一密钥)- FFmpeg(用于将 WAV 转换为 MP3;如果缺少,则回退到 WAV)
始终使用 run.py 包装器
# CORRECT:
python3 scripts/run.py generate_audio.py --text "..." --voice Charon --json
# WRONG:
python3 scripts/generate_audio.py --text "..." # Fails without venv
API 密钥检查(门控模式)
生成音频前,检查是否存在 API 密钥:
echo $GOOGLE_AI_API_KEY
- 如果已设置:继续生成
- 如果未设置:引导用户:
“生成音频需要 Google AI API 密钥。请访问 https://aistudio.google.com/apikey 免费获取。
然后进行设置:
export GOOGLE_AI_API_KEY=your-key这与/blog image使用的是同一密钥:如果图像生成可用,音频生成也可用。” - 内部调用时(来自 blog-write):如果缺少密钥,则静默返回。 切勿阻止写作工作流。
设置
对于 /blog audio setup:
- 检查环境中是否已设置
GOOGLE_AI_API_KEY - 如果已配置 blog-image(检查
.mcp.json),则密钥已可用 - 如果没有,引导用户访问 https://aistudio.google.com/apikey
- 使用试运行进行验证:
python3 scripts/run.py generate_audio.py --text "Test" --dry-run --json
声音选择
对于 /blog audio voices:
加载 references/voices.md,并向用户展示声音目录。
询问用户偏好的声音,或根据内容类型进行推荐:
- 文章配音:Charon(信息丰富)或 Sadaltager(知识渊博)
- 教程/操作指南:Achird(友好)或 Sulafat(温暖)
- 新闻/分析:Rasalgethi(信息丰富)或 Schedar(平和)
- 生活方式/健康:Aoede(轻快)或 Vindemiatrix(温和)
- 对话主持人:Puck(活泼)或 Laomedeia(活泼)
- 对话专家:Kore(坚定)或 Charon(信息丰富)
生成工作流
对于 /blog audio generate <file>:
步骤 1:阅读博客文章
读取文件并提取:
- 标题(来自 H1 或 frontmatter)
- 全部内容(Markdown 正文)
- 估算字数
步骤 2:选择模式
询问用户(如果用户已指定 --mode,则自动选择):
| 模式 | 适用场景 | 输出 |
|---|---|---|
| Summary | 快速音频概述(1–2 分钟) | 200–300 字的口播摘要 |
| Full | 完整朗读(5–15 分钟) | 将全文转换为自然口语 |
| Dialogue | 播客风格(3–8 分钟) | 两人围绕文章展开对话 |
步骤 3:准备文本
**重要:**由 Claude 准备文本。脚本仅负责 TTS。
摘要模式: 撰写一段 200-300 词的文章口语摘要。规则:
- 写得像自然对话,而不是书面文字
- 开篇点出文章的关键发现或答案
- 涵盖 3-5 个主要要点
- 以可执行的建议收尾
- 不使用 Markdown,不要写“本文……”,也不要添加元评论
- 使用对话式过渡语(“这里的重点是……”“关键发现是……”)
全文模式: 将 Markdown 内容转换为简洁、适合朗读的文本:
- 将标题改为自然的过渡语(“接下来,我们来看看……”)
- 将链接改为纯文本(移除 URL,保留锚文本)
- 省略图片和图表,或简要描述(“数据表明……”)
- 用口头表达描述代码块(“这段代码使用了一个 for 循环……”)
- 将列表改写为自然的句子
- 移除 frontmatter、schema 标记和 HTML 标签
- 添加简短的开场白:“这篇文章是《[标题]》,发表于 [日期]。”
对话模式: 撰写一段关于文章的双人对话稿:
- Speaker1 = 主持人(充满好奇,会提出有深度的问题)
- Speaker2 = 专家(知识渊博,回答清晰)
- 每行格式为:
[Speaker1] 这里的关键要点是什么? - 以对话方式涵盖文章的主要内容
- 进行 15-25 轮对话(生成约 3-8 分钟的音频)
- 对话自然、不生硬(例如用“说得好”而不是“确实,正如研究所表明的那样”)
步骤 4:选择语音
如果用户选择了语音,就使用该语音。否则,根据模式推荐:
- 摘要/全文:默认使用 Charon(信息型)
- 对话:默认使用 Puck(主持人)+ Kore(专家)
步骤 5:生成音频
将准备好的文本写入临时文件,然后调用:
# Single voice (summary or full mode)
python3 scripts/run.py generate_audio.py \
--text-file /tmp/blog_audio_prepared.txt \
--voice Charon \
--model flash \
--output /path/to/audio/post-slug.mp3 \
--json
# Two voices (dialogue mode)
python3 scripts/run.py generate_audio.py \
--text-file /tmp/blog_audio_dialogue.txt \
--voice Puck \
--voice2 Kore \
--model pro \
--output /path/to/audio/post-slug-dialogue.mp3 \
--json
模型选择:
flash(默认):速度快、成本低。适合摘要和标准旁白。pro:质量更高。用于对话模式或优质内容。
步骤 6:交付
向用户展示结果:
- 文件路径:音频的保存位置
- 时长:以易读格式显示(例如“3:42”)
- 嵌入代码:可直接粘贴的 HTML5 音频标签
- 费用:预估 API 费用
- 放置建议:建议在博客文章中的插入位置
嵌入指南
标准 HTML(Hugo、Jekyll、静态网站)
<audio controls preload="metadata">
<source src="audio/post-slug.mp3" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
MDX(Next.js、Gatsby)
<audio controls preload="metadata">
<source src="/audio/post-slug.mp3" type="audio/mpeg" />
</audio>
WordPress
[audio src="audio/post-slug.mp3"]
放置位置
将音频播放器插入引言之后(第一个 H2 标题下方),或放在文章最顶部,并添加标签:“收听本文”或“音频版”。
内部 API(适用于 blog-write)
从 blog-write 内部调用时:
输入:
text:准备好的文本(已由 Claude 清理)voice:语音名称(默认:Charon)voice2:对话模式的第二个语音(可选)model:flash 或 prooutput_path:文件保存位置
输出:
### Audio Narration
- **Path:** /path/to/audio/post-slug.mp3
- **Duration:** 3:42
- **Voice:** Charon
- **Embed:** `<audio controls preload="metadata"><source src="audio/post-slug.mp3" type="audio/mpeg"></audio>`
**优雅降级:**如果未设置 GOOGLE_AI_API_KEY,则立即返回且不报错。写作工作流会在不生成音频的情况下继续。音频生成不可用时,绝不要阻塞 blog-write。
错误处理
| 错误 | 解决方法 |
|---|---|
| 未设置 GOOGLE_AI_API_KEY | 在 https://aistudio.google.com/apikey 获取密钥 |
| 未找到 FFmpeg | 安装:sudo apt install ffmpeg。将回退为 WAV 输出。 |
| 触发速率限制 | 等待后重试。在 https://aistudio.google.com/rate-limit 查看限制 |
| 文本过长(>32k 个 token) | 拆分为多个部分,分别生成 |
| 未知语音名称 | 运行 /blog audio voices 查看有效选项 |
| API 错误 | 检查密钥是否有效,以及模型是否可用(预览模型) |
| 缺少 API 密钥(内部调用) | 静默返回:写作工作流继续运行 |
参考文档
按需加载:启动时不要加载全部内容:
references/voices.md:完整的 30 种语音目录、按内容类型提供的建议以及对话语音搭配