用 Python 打造一套中文文本转语音与字幕自动生成工具
本文最后更新于67 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com

最近整理了一个自用的小工具,用来把整理好的 .txt 文本批量转换成语音音频、SRT/VTT 字幕以及供前端使用的结构化数据。

整个工具不依赖任何付费 API,完全在本地运行,生成结果可以直接用于博客、网页播放器、视频剪辑或播客制作。这篇文章做一个完整记录。


工具能做什么

一句话概括:输入一段文本,输出一个完整的”音频 + 字幕 + 时间轴”数据包

具体输出内容包括:

  • audio.mp3 —— 完整朗读音频
  • subtitle.srt —— 标准 SRT 字幕
  • subtitle.vtt —— 网页可用的 WebVTT 字幕
  • dialog.json —— 逐句结构化数据,含开始/结束时间
  • markers.json —— 章节时间标记
  • origin.txt —— 处理后的原始文本

这些文件配合使用,可以做出:逐句高亮播放、聊天气泡对话展示、带章节目录的网页音频播放器等效果。


项目结构

AI_Read/
├── input/
│   ├── oldcalendar/      # 对话类内容(多角色)
│   └── whiteartical/     # 文章类内容(单人朗读)
├── output/               # 生成结果
├── cache/                # TTS 语音缓存
├── batch_tts.py          # 对话模式处理脚本
├── batch_tts_single.py   # 文章模式处理脚本
└── sentence_splitter.py  # 分句逻辑

目前处理两类内容:

  • oldcalendar:偏对话格式,支持 A/B 双角色,各自使用不同音色
  • whiteartical:偏长文朗读,单一音色,支持章节标记

核心功能详解

一、自动分句

文本直接送入 TTS 效果通常很差——句子太长语调会拖沓,太短又显得机械。因此专门做了一个分句模块。

当前分句逻辑:

  • 。!?;, 等标点处切分,标点保留在前一句末尾
  • 切分时吞掉尾随的闭合符号,如 "
  • 过滤空片段和纯标点,避免单独的 进入 TTS 导致报错
  • 数字中的逗号和小数点不会被误切,如 1,234.56
  • 超长句兜底按最大字数强制切断

示例:

输入:更多解释:这是一个测试句子。后面还有内容。
输出:
  更多解释:这是一个测试句子。
  后面还有内容。
输入:价格是1,234.56元,对吧?
输出:
  价格是1,234.56元,对吧?   ← 数字完整保留,不会被逗号拆开

二、多角色 TTS 生成

工具使用 edge-tts 调用微软 Azure TTS,免费且音质出色。

文章朗读模式使用固定音色:

VOICE = "zh-CN-YunyangNeural"
RATE = "+10%"

对话模式支持角色映射,不同角色自动使用不同音色:

VOICE_MAP = {
    "A": {"voice": "zh-CN-XiaoxiaoNeural", "rate": "+10%"},
    "B": {"voice": "zh-CN-YunyangNeural",  "rate": "+10%"},
}

文本文件中只需这样写:

A: 你好,今天天气怎么样?
B: 还不错,阳光很好。

运行后 A 和 B 会自动使用各自的音色朗读,生成的音频听起来有对话感。并发数量可配置,默认 4 线程同时生成:

MAX_WORKERS = 4

三、缓存机制

每条语音片段生成后,都会以 voice|rate|text 的哈希值作为文件名缓存到 cache/ 目录。再次运行时,只要文本、音色、语速完全一致,就直接复用缓存,不会重复请求 TTS。

运行日志示例:

⚡ 缓存命中: 230, 未命中: 0

这对反复调整分句参数或修改少量文本非常友好——改了一句话只需重新生成那几个片段,其余全部复用缓存,耗时极短。


四、音频拼接

每句文本独立生成一个临时 mp3 片段,最终用 pydub 顺序拼接成完整音频。片段之间加入 50 毫秒静音间隔,让朗读不会完全粘连,听感更自然。


五、字幕同步

字幕的时间轴直接来自音频片段的实际时长,因此字幕与音频天然同步,无需手动校对时间。同时输出两种格式:

  • subtitle.srt:适用于视频剪辑软件(Premiere、剪映等)和播放器
  • subtitle.vtt:适用于 HTML5 网页播放器

六、dialog.json

这是给前端使用的逐句数据,结构如下:

[
  {
    "text": "这是一句字幕内容",
    "start": 1200,
    "end": 3600,
    "line_start": true,
    "line_end": false
  }
]

line_startline_end 标记了该句是否是原文一行的起始或结尾,方便前端按段落做高亮效果。

对话模式的 JSON 还额外包含角色和方向信息:

{
  "role": "A",
  "side": "left",
  "text": "你好,今天天气怎么样?",
  "start": 800,
  "end": 2400
}

可以直接用来实现类似微信聊天气泡的对话播放效果。


七、章节时间标记

文章模式支持在文本中插入 $$$ 作为章节分隔符:

第一章内容……

$$$

第二章内容……

生成后会输出 markers.json

[
  {"index": 1, "time": 0},
  {"index": 2, "time": 45320}
]

time 是该章节在音频中的毫秒时间点,可用于网页播放器章节跳转、视频时间轴标注、文章阅读进度同步等场景。


运行效果

$ python batch_tts_single.py

📚 共发现 1 个文本文件
🎯 正在处理: 05_04.txt
🧩 共 228 条任务
🎤 TTS 合成: 100%|██████████| 228/228
🎧 拼接音频...
🎶 拼接进度: 100%|██████████| 243/243
⚡ 缓存命中: 215, 未命中: 13
📍 时间节点: 13
✅ 完成: output/whiteartical/2026/05_04

输出目录:

output/whiteartical/2026/05_04/
├── audio.mp3
├── subtitle.srt
├── subtitle.vtt
├── dialog.json
├── markers.json
└── origin.txt

依赖

edge-tts
pydub
ffmpeg
regex
tqdm

小结

这套工具的核心价值在于:不只是生成一段音频,而是同时生成配套的字幕、时间轴和结构化 JSON,后续对接任何展示场景都比较方便。

目前已经在稳定使用,后续计划继续扩展:

  • WordPress 短代码嵌入播放器
  • 逐句高亮朗读网页组件
  • 自动批量上传到媒体库
  • 多音色快速切换配置

如果你也在做类似的中文语音内容,欢迎交流。

文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇