图像与设计
需要把博客文章转为摘要音频、全文朗读或双人播客对话时,用…
当用户说 blog audio、narrate blog、audio version、text to speech、tts、podcast mode、read aloud 等,需要为博客内容生成音频旁白时使用。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 59/100 ×0.15
适用场景
需要把博客文章转为摘要音频、全文朗读或双特定
解决思路
- 使用 `/blog audio generate <file>` 生成博客文章音频旁白;使用 `/blog audio voices` 查看可用声音及特征;使用 `/blog audio setup` 检查/配置 Gemini TTS 的 API key。
- 确认前置条件:Python 3.11+(由 `run.py` 自动管理 venv);设置 `GOOGLE_AI_API_KEY` 环境变量(可与 blog-image 使用同一 key);安装 FFmpeg 用于 WAV 转 MP3,缺失时回退输出 WAV。
- 始终通过 `run.py` 包装器调用:正确命令为 `python3 scripts/run.py generate_audio.py --text "..." --voice Charon --json`;不要直接运行 `python3 scripts/generate_audio.py ...`,否则没有 venv 会失败。
- 生成音频前执行 API key 门禁检查:`test -n "${GOOGLE_AI_API_KEY:-}" && echo "GOOGLE_AI_API_KEY is set" || echo "GOOGLE_AI_API_KEY is not set"`。
- 如果 API key 已设置,继续生成;如果未设置,引导用户到 https://aistudio.google.com/apikey 获取免费 key,并执行 `export GOOGLE_AI_API_KEY=your-key`;说明可与 `/blog image` 使用同一 key,但必须在 shell 中导出。
- 当从 blog-write 内部调用时,如果 API key 缺失则静默返回,绝不阻塞写作工作流。
- `/blog audio setup` 操作:检查环境中是否设置 `GOOGLE_AI_API_KEY`。
- `/blog audio setup` 操作:如果 blog-image 使用项目 `.mcp.json`,确认其中引用的环境变量已导出。
- `/blog audio setup` 操作:如果未设置,引导用户访问 https://aistudio.google.com/apikey。
- `/blog audio setup` 操作:用 dry run 验证:`python3 scripts/run.py generate_audio.py --text "Test" --dry-run --json`。
- `/blog audio voices` 操作:加载 `references/voices.md` 并向用户展示声音目录。
- 询问用户偏好的声音,或按内容类型推荐:文章旁白选 Charon(Informative)或 Sadaltager(Knowledgeable);教程/how-to 选 Achird(Friendly)或 Sulafat(Warm);新闻/分析选 Rasalgethi(Informative)或 Schedar(Even);生活方式/健康选 Aoede(Breezy)或 Vindemiatrix(Gentle);对话主持人选 Puck(Upbeat)或 Laomedeia(Upbeat);对话专家选 Kore(Firm)或 Charon(Informative)。
- 生成流程 Step 1:读取博客文章,提取标题(来自 H1 或 frontmatter)、完整内容(markdown 正文)和大致字数。
- 生成流程 Step 2:询问用户选择模式,或用户指定 `--mode` 时自动选择;Summary 用于快速音频概览(1-2 分钟,200-300 词口播摘要);Full 用于完整朗读(5-15 分钟,全文自然语音);Dialogue 用于播客风格(3-8 分钟,围绕文章的双人对话)。
- 生成流程 Step 3 关键点:由 Claude 准备文本,脚本只做 TTS。
- Summary 模式准备文本:写 200-300 词口播摘要;规则:写成自然口语而非书面文本;以文章关键发现或答案开头;覆盖 3-5 个主要要点;以可操作建议结尾;不要 markdown,不要 "In this article...",不要元评论;使用对话式过渡(如 "Here's what matters..."、"The key finding is...")。
- Full 模式准备文本:把 markdown 内容剥离成干净口播文本;标题变成自然过渡(如 "Next, let's look at...");链接变成纯文本(移除 URL,保留锚文本);图片和图表省略或简要描述(如 "As the data shows...");代码块口头描述(如 "The code uses a for-loop to...");列表转成自然句子;移除 frontmatter、schema markup、HTML 标签;添加简短开场:"This is [title], published on [date]."。
- Dialogue 模式准备文本:写 2 人对话脚本;Speaker1 = 主持人(好奇,问好问题);Speaker2 = 专家(知识渊博,给出清晰回答);每行格式为 `Speaker1: What's the key takeaway here?`;以对话方式覆盖文章主要观点;15-25 轮交换(产生约 3-8 分钟);自然不僵硬(用 "That's a great point" 而非 "Indeed, as the research indicates")。
- 生成流程 Step 4:如果用户选择了声音则使用;否则按模式推荐:Summary/Full 默认 Charon(Informative);Dialogue 默认 Puck(Host)+ Kore(Expert)。
- 生成流程 Step 5:将准备好的文本写入临时文件,然后调用生成命令;单声音(Summary 或 Full 模式):`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`;双声音(Dialogue 模式):`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`(默认)映射到 `gemini-3.1-flash-tts`,适合摘要和标准旁白;`flash31` 是 `gemini-3.1-flash-tts` 的显式别名;`legacy-flash25` 仅为旧兼容保留;`pro` 或 `legacy-pro25` 映射到 `gemini-2.5-pro-preview-tts`,仅在需要时使用。
- 生成流程 Step 6:向用户交付结果:文件路径;人类可读时长(如 "3:42");可粘贴的 HTML5 audio 嵌入代码;预估 API 成本;在博客文章中插入嵌入的位置建议。
- 嵌入指南 Standard 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 下方)插入音频播放器,或放在文章最顶部并加标签 "Listen to this article" 或 "Audio version"。
- 内部 API(供 blog-write 调用):输入包括 `text`(已由 Claude 清理的准备文本)、`voice`(声音名,默认 Charon)、`voice2`(对话第二声音,可选)、`model`(flash 或 pro)、`output_path`(保存位置)。
- 内部输出 markdown:`### 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 not set`:到 https://aistudio.google.com/apikey 获取 key。
- 错误处理 `FFmpeg not found`:安装 `sudo apt install ffmpeg`;回退为 WAV 输出。
- 错误处理 `Rate limited`:等待并重试;查看限制 https://aistudio.google.com/rate-limit。
- 错误处理 `Text too long (>8,192 input tokens)`:拆分为约 7,800 tokens 的段落;脚本会对准备文本分块并拼接。
- 错误处理 `Unknown voice name`:运行 `/blog audio voices` 查看有效选项。
- 错误处理 `API error`:检查 key 有效性和模型可用性。
- 错误处理 `API key missing (internal call)`:静默返回,写作工作流继续。
- 参考文档按需加载,不要在启动时全部加载:`references/voices.md` 包含完整 30 声音目录、按内容类型的推荐、对话配对。
适用边界 · 注意事项
- 未配置 `GOOGLE_AI_API_KEY` 且不想获取 Google AI API key 时不要使用;内部调用应静默跳过。
- 没有 FFmpeg 且不能接受 WAV 输出时,MP3 转换会缺失/回退为 WAV。
- 文本超过 8,192 input tokens 且不想拆分/分块时,直接生成可能失败;需要拆分到约 7,800 tokens。