文档音频工作流 (Docs TTS)
文档分类下的文章(如 docs/LookAround/)支持 TTS 朗读音频播放。与博客音频不同,文档音频播放器自动注入到页面布局中,无需在每篇文章的 MDX 文件里手动引入组件。
当前已接入音频的文档分类:
| 分类 | 目录 | 文章数 | 中文音频 | 英文音频 |
|---|---|---|---|---|
| 东张西望 (LookAround) | docs/LookAround/ | 13 | 部分已生成 | 部分已生成 |
架构概览
文档音频系统复用了博客音频播放器,但使用独立的文档音频清单和独立 OSS 路径。这样博客和文档可以共享播放体验,又不会互相污染 manifest。
组件关系
BlogAudioPlayer (核心播放逻辑)
├── BlogPostPage 自动注入:<BlogAudioPlayer slug={audioSlug} />
│ ├── slug 由 getBlogAudioSlug(metadata) 从 permalink 推导
│ └── 读取 blogAudioManifest.json(默认清单)
│
└── DocsAudioPlayer (薄包装)
└── <DocsAudioPlayer slug="xxx" />
└── 传入 docsAudioManifest.json + keyPrefix="docs/"
关键文件
| 文件 | 作用 |
|---|---|
src/components/BlogAudioPlayer/index.js | 核心播放器组件,支持 manifest 和 keyPrefix props |
src/components/DocsAudioPlayer/index.js | 文档音频薄包装,传入文档清单和前缀 |
src/theme/BlogPostPage/index.js | 博客页面布局 swizzle,自动注入博客播放器 |
src/utils/blogAudio.js | 从 permalink 推导博客音频 slug |
src/utils/lookAroundDocs.js | LookAround 文档检测工具函数 |
src/theme/DocItem/Layout/index.js | 文档布局,自动注入文档播放器 |
src/data/blogAudioManifest.json | 博客音频清单(静态 import) |
src/data/docsAudioManifest.json | 文档音频清单(静态 import) |
static/audio/blog/manifest.json | 博客音频清单(备用访问路径) |
static/audio/docs/manifest.json | 文档音频清单(备用访问路径) |
清单文件结构
docsAudioManifest.json 的 key 格式:
- 中文:
docs/{slug},如docs/omega-horizontal-vertical-analysis - 英文:
en/docs/{slug},如en/docs/omega-horizontal-vertical-analysis
每个条目包含:
{
"docs/omega-horizontal-vertical-analysis": {
"urls": [
"https://oss.nevergpdzy.com/Audio/docs/omega-horizontal-vertical-analysis_001.mp3",
"https://oss.nevergpdzy.com/Audio/docs/omega-horizontal-vertical-analysis_002.mp3"
],
"voice": "茉莉",
"generatedAt": "2026-05-02T06:10:34.705519+00:00"
}
}
OSS 路径
| 内容 | OSS 路径 |
|---|---|
| 中文文档音频 | Audio/docs/{slug}.mp3 或 Audio/docs/{slug}_001.mp3 等 |
| 英文文档音频 | Audio/docs/en/en_{slug}.mp3 或 Audio/docs/en/en_{slug}_001.mp3 等 |
| 文档音频清单 | Audio/docs/manifest.json |
文档音频 manifest 中的公开 URL 必须使用 https://oss.nevergpdzy.com/,不要把已退役 picture 域名重新写回 src/data/docsAudioManifest.json 或 static/audio/docs/manifest.json。
与博客音频(Audio/blog/)完全独立,互不干扰。
生成策略
文档文章通常比博客长,而且包含表格、参考资料和图片资源段落。生成器的 docs 模式做了这些处理:
- 提取纯文本,去除 frontmatter、代码块、JSX、图片、原始 URL、来源/参考资料/图片资源等不适合朗读的段落。
- 在处理普通 Markdown 之前先转换表格,把每行转换成适合朗读的短句,而不是直接朗读竖线和分隔符。
- 按段落边界分块,默认
--chunk-char-limit 2400,必要时可以对单篇文章降低到1200之类的更稳值。 - 并发只发生在文章级别,
--article-jobs会同时处理多篇文章;同一篇文章内部的 chunk 始终串行生成,保证音频顺序和文字顺序严格一致。 - 每个 chunk 生成后用
ffprobe检查时长,明显过短或截断的音频会删除并重试。 - 只要有文章失败,本次 publish manifest 不会上传,避免发布部分缺段的清单。
中文语音使用「茉莉」,提示词强调缓慢、温柔舒缓、自然停顿。英文语音使用 Chloe,保持自然流畅朗读提示词,不额外强制舒缓节奏。不要再用 atempo 或其他 MP3 后处理去改变语速;语速应由 TTS 提示词和分块稳定性控制。
生成音频
全量生成中文 LookAround 音频
cd ../tts-blog-generator
python generate.py --type docs --lang zh --force --article-jobs 2
默认扫描 ../Dev-Knowledge-Base/docs/LookAround。
全量生成英文 LookAround 音频
cd ../tts-blog-generator
python generate.py --type docs --lang en \
--blog-dir "../Dev-Knowledge-Base/i18n/en/docusaurus-plugin-content-docs/current/LookAround" \
--force --article-jobs 2
英文音频使用 Chloe 语音,文件名带 en_ 前缀,存储在 OSS 的 Audio/docs/en/ 目录下。