Generate podcasts from documents using Mimo LLM, Mimo TTS, and MiniMax BGM
Project description
PodcastGen
📻 文档播客生成工具 — 基于 Mimo LLM + Mimo TTS + MiniMax BGM
将文档自动转换为高质量播客音频:AI 分析文档结构 → 生成播客脚本 → 语音合成 → 背景音乐 → 混音输出。
✨ 特性
- 📊 智能文档分析:Mimo LLM (OpenAI 格式) 分析文档,按段落结构化输出 JSON
- 📝 脚本生成:支持单人/双人模式,三种风格(专业/轻松/叙事),多语言
- 🎤 TTS 合成:Mimo TTS 分段合成,自动拼接停顿
- 🎵 BGM 生成:MiniMax Music 2.6 生成背景音乐,自动循环+淡入淡出
- 🔊 混音输出:独立音量控制,自动归一化,WAV 输出
- 🎛️ CLI 命令:一键生成,支持丰富参数
📦 安装
pip install podcastgen
或从源码安装:
git clone <repo-url>
cd podcast_generator
pip install -e .
🔑 配置
设置环境变量:
export MIMO_API_KEY="your-mimo-api-key"
export MINIMAX_API_KEY="your-minimax-api-key"
🚀 使用
命令行
# 基本用法:基于已有播客文案生成(直接分段,不重新生成文本)
podcastgen -i document.md
# 基于话题直接生成脚本(无需文档)
podcastgen -t "人工智能对教育行业的影响"
# 双人播客(文案中用 [Host]: / [Guest]: 标记角色)
podcastgen -i document.md --mode double --tone casual --duration 20
# 话题模式 + 联网搜索 + 叙事风格
podcastgen -t "2024年AI大模型发展趋势" --web-search --tone storytelling --duration 15
# 仅解析分段(不生成音频)
podcastgen -i document.md --analyze-only
# 自定义BGM和音量
podcastgen -i document.md --bgm-prompt "lo-fi chillhop" --voice-volume 1.0 --bgm-volume 0.25
# 不要BGM,纯人声
podcastgen -i document.md --no-bgm
# 自定义音色
podcastgen -i document.md --host-voice "冰糖" --guest-voice "苏打"
# 英文播客使用英文音色
podcastgen -i document.md --language en --host-voice "Mia" --guest-voice "Dean"
# 使用音色复刻(通过音频样本克隆声音)
podcastgen -i document.md --host-voice-sample ./host_voice.mp3 --guest-voice-sample ./guest_voice.wav
# 话题生成 + 音色复刻
podcastgen -t "时间管理的艺术" --host-voice-sample ./my_voice.wav --duration 10
音色复刻 + 风格控制
podcastgen -i document.md --host-voice-sample ./voice.mp3 --tone casual
### 文档模式(直接分段)
当传入已有播客文案(`--input`)时,**不会调用 LLM 重新生成文本**,而是直接对文档内容做分段处理:
- **默认单人模式(无角色标签)**:按换行符分段,每个非空行作为一段 `Host` 台词,空行自动跳过
- **双人模式(带角色标签)**:在文档中用 `[Host]:` / `[Guest]:` 标签标记每段台词的角色,按角色分段合成不同音色
- 角色标签格式:`[Host]: 台词内容` 或 `[Guest]: 台词内容`(也支持 `主持人` / `嘉宾`)
**示例文档(单人模式,按行分段):**
```text
欢迎收听本期播客,今天我们来聊聊人工智能的发展。
近年来,大语言模型取得了突破性进展...
接下来我们看看它对各行业的影响。
示例文档(双人模式,按角色分段):
[Host]: 欢迎收听本期播客,今天的主题是人工智能。
[Guest]: 很高兴来参加节目,这个话题最近确实很热。
[Host]: 能不能先聊聊大模型的核心突破?
[Guest]: 当然,最主要的变化在于规模化和多模态...
语气分析(Alpha 测试)
使用 --use-tone 参数启用语气分析功能。开启后,系统会对每段台词进行情绪和风格分析(限制 token 2048),自动为每段台词匹配合适的语气,使播客更有表现力。
# 启用语气分析(document 模式)
podcastgen -i document.md --use-tone
# 启用语气分析(topic 模式)
podcastgen -t "人工智能的未来" --use-tone
⚠️ Alpha 测试阶段,分析结果可能不够精准,欢迎反馈。
音频标签(细粒度控制)
通过在文本中插入音频标签,你可以对声音进行细粒度控制,精准调节语气、情绪和表达风格。标签支持中文括号 () 和英文括号 (),可以出现在文本的任意位置。
风格类型:
| 类别 | 示例 |
|---|---|
| 语速与节奏 | 吸气 / 深呼吸 / 叹气 / 长叹一口气 / 喘息 / 屏息 / 语速加快 / 语速放慢 / 停顿 / 沉默片刻 |
| 情绪状态 | 紧张 / 害怕 / 激动 / 疲惫 / 委屈 / 撒娇 / 心虚 / 震惊 / 不耐烦 / 兴奋 / 难过 / 开心 |
| 语音特征 | 颤抖 / 声音颤抖 / 变调 / 破音 / 鼻音 / 气声 / 沙哑 / 轻声 / 大声 / 耳语 / 小声 |
| 哭笑表达 | 笑 / 轻笑 / 大笑 / 冷笑 / 抽泣 / 呜咽 / 哽咽 / 嚎啕大哭 / 苦笑 |
使用示例:
(紧张,深呼吸)呼……冷静,冷静。不就是一个面试吗……(语速加快,碎碎念)自我介绍已经背了五十遍了,应该没问题的。加油,你可以的……(小声)哎呀,领带歪没歪?
(极其疲惫,有气无力)师傅……到地方了叫我一声……(长叹一口气)我先眯一会儿,这班加得我魂儿都要散了。
如果我当时……(沉默片刻)哪怕再坚持一秒钟,结果是不是就不一样了?(苦笑)呵,没如果了。
(寒冷导致的急促呼吸)呼——呼——这、这大兴安岭的雪……(咳嗽)简直能把人骨头冻透了……别、别停下,走,快走。
(提高音量喊话)大姐!这鱼新鲜着呢!早上刚捞上来的!哎!那个谁,别乱翻,压坏了你赔啊?!
规则说明:
- 标签格式:
(风格描述)或(风格描述) - 标签作用于紧随其后的文本内容
- 可以在一段话中插入多个标签,每段标签后的文本按对应风格合成
- 多个风格用逗号分隔,如
(紧张,语速加快,小声) - 支持中英文括号混合使用
话题生成模式
无需文档,直接根据话题生成播客脚本。适合快速创作知识分享类播客。
# 基于话题生成播客
podcastgen -t "人工智能在教育领域的应用与挑战"
# 话题 + 双人对话 + 轻松风格
podcastgen -t "职场新人如何快速成长" --mode double --tone casual --duration 15
# 话题模式 + 联网搜索(获取最新信息)
podcastgen -t "2024年诺贝尔物理学奖解读" --web-search
# 启用语气分析(自动为每段匹配情绪风格,Alpha 测试)
podcastgen -i document.md --use-tone
# 话题 + 英文播客
podcastgen -t "The future of renewable energy" --language en --duration 20
音色复刻
通过传入音频样本文件,精准复刻目标音色。使用 mimo-v2.5-tts-voiceclone 模型。
注意事项:
- 支持 mp3 和 wav 格式
- 文件大小不能超过 10MB
- 建议使用清晰的人声录音(30秒以上效果更佳),音频时长不能超过30秒
示例:
# 使用音频样本克隆主持人音色
podcastgen -i document.md --host-voice-sample ./my_voice.wav
# 双人播客,两人都使用音色复刻
podcastgen -i document.md --mode double \
--host-voice-sample ./host_sample.mp3 \
--guest-voice-sample ./guest_sample.wav
可选音色
| 音色名 | Voice ID | 语言 | 性别 |
|---|---|---|---|
| MiMo-默认 | mimo_default |
因部署集群而异 | - |
| 冰糖 | 冰糖 |
中文 | 女性 |
| 茉莉 | 茉莉 |
中文 | 女性 |
| 苏打 | 苏打 |
中文 | 男性 |
| 白桦 | 白桦 |
中文 | 男性 |
| Mia | Mia |
英文 | 女性 |
| Chloe | Chloe |
英文 | 女性 |
| Milo | Milo |
英文 | 男性 |
| Dean | Dean |
英文 | 男性 |
Python API
from podcastgen import PodcastPipeline, load_config
# 使用默认配置
pipeline = PodcastPipeline()
# 基于文档生成播客(直接分段,不重新生成文本)
result = pipeline.run(
document="你的文档内容...", # 已有文案,直接分段;双人模式可用 [Host]:/[Guest]: 标签
mode="single", # single / double
tone="professional", # professional / casual / storytelling
duration_min=10,
language="zh",
)
print(result["files"]["final"]) # 最终音频路径
# 基于话题生成播客(无需文档)
result = pipeline.run(
topic="人工智能在教育领域的应用与挑战",
mode="single",
tone="casual",
duration_min=15,
language="zh",
web_search=True, # 启用联网搜索
)
# 完整参数示例
result = pipeline.run(
document="你的文档内容...",
mode="double",
tone="casual",
duration_min=20,
language="zh",
bgm_prompt="lo-fi chillhop",
voice_volume=1.0,
bgm_volume=0.3,
no_bgm=False,
analyze_only=False,
host_voice="冰糖",
guest_voice="苏打",
host_voice_sample=None, # 音色样本文件路径,启用音色复刻
guest_voice_sample=None,
)
# 使用音色复刻
result = pipeline.run(
document="你的文档内容...",
mode="single",
host_voice_sample="./my_voice.wav", # 通过音频样本克隆声音
)
# 也可以分步调用
analysis = pipeline.analyze(document)
script = pipeline.generate_script(document, analysis)
voice = pipeline.synthesize_voice(script["script"])
bgm = pipeline.generate_bgm("ambient, chill")
mixed = pipeline.mix_audio(voice, bgm)
📁 输出结构
output/podcast_YYYYMMDD_HHMMSS/
├── analysis.json # 文档分析结果(JSON)
├── script.txt # 播客脚本
├── voice.wav # 人声音频
├── podcast.lrc # 带时间标签的脚本(LRC格式,可在播放器显示字幕)
├── bgm.wav # 背景音乐
├── podcast_final.wav # 最终混音
└── metadata.json # 元数据
🔧 API 参考
PodcastPipeline
| 方法 | 说明 |
|---|---|
run(document=None, topic=None, ...) |
完整流程:document 直接分段 / topic 生成脚本 + TTS + BGM + 混音(二选一) |
analyze(document, options) |
分析文档,返回结构化 JSON |
generate_script_from_document(document, analysis, options) |
基于文档生成完整播客脚本 |
generate_script_from_topic(topic, options) |
基于话题生成播客脚本(无需文档) |
synthesize_voice(script_text, progress_cb) |
TTS 合成语音 |
generate_bgm(prompt, duration_sec) |
生成背景音乐 |
mix_audio(voice_data, bgm_data, ...) |
混音合成 |
DocumentAnalyzer
| 方法 | 说明 |
|---|---|
analyze_document(document, options) |
分析文档,返回结构化 JSON |
generate_full_script(document, analysis, options) |
基于文档生成完整播客脚本 |
generate_podcast_script_from_topic(topic, options) |
基于话题生成播客脚本 |
parse_script_segments(script_text) |
解析脚本为角色分段 |
TTSSynthesizer
| 方法 | 说明 |
|---|---|
synthesize_segment(text, role, style) |
合成单段语音 |
synthesize_segments(segments, progress_callback) |
批量合成 |
synthesize_segments_with_timestamps(segments, progress_callback) |
批量合成并返回时间戳 |
save_wav(float_data, path) |
保存为 WAV |
save_lrc(timestamps, path, title) |
保存 LRC 字幕文件 |
BGMGenerator
| 方法 | 说明 |
|---|---|
generate_bgm(prompt, duration_sec) |
生成背景音乐 |
loop_bgm(bgm_data, target_duration_sec) |
循环延长 BGM |
apply_fade(audio_data, fade_in_sec, fade_out_sec) |
添加淡入淡出 |
AudioMixer
| 方法 | 说明 |
|---|---|
mix(voice_data, bgm_data, voice_volume, bgm_volume) |
混音 |
normalize(audio_data) |
归一化音量 |
extract_waveform(audio_data, num_points) |
提取波形数据 |
📋 参数说明
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
document |
str | None |
输入文档内容(与 topic 二选一) |
topic |
str | None |
播客话题描述(与 document 二选一) |
mode |
str | single |
播客模式:single 单人 / double 双人 |
tone |
str | professional |
风格:professional / casual / storytelling |
duration_min |
int | 10 |
目标时长(分钟) |
language |
str | zh |
语言:zh / en |
voice_volume |
float | 1.0 |
人声音量 |
bgm_volume |
float | 0.3 |
BGM 音量 |
host_voice |
str | 冰糖 |
主持人音色 |
guest_voice |
str | 苏打 |
嘉宾音色(双人模式) |
host_voice_sample |
str | "" |
主持人音色样本文件路径(启用音色复刻) |
guest_voice_sample |
str | "" |
嘉宾音色样本文件路径(启用音色复刻) |
web_search |
bool | False |
启用联网搜索(仅用于话题模式) |
use_tone |
bool | False |
启用语气分析(Alpha 测试),自动为每段匹配情绪风格 |
no_bgm |
bool | False |
不生成 BGM,仅生成人声 |
analyze_only |
bool | False |
仅解析分段,不生成音频 |
📝 License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file podcastgen-0.1.7.tar.gz.
File metadata
- Download URL: podcastgen-0.1.7.tar.gz
- Upload date:
- Size: 31.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b90001cf34634e371a8fc8338ea69532a1c812e1a1dfa4b4e887a1dc0f462612
|
|
| MD5 |
19c96c0d6e0bdf6ec8bb6ee018a0a2b4
|
|
| BLAKE2b-256 |
88123b0f704b4450b6a66917aa9c2f9ed34de65643547521703212360af2a0e0
|
File details
Details for the file podcastgen-0.1.7-py3-none-any.whl.
File metadata
- Download URL: podcastgen-0.1.7-py3-none-any.whl
- Upload date:
- Size: 28.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
801b99c4632686875f833969bddd6b0a9537eb8d38a6f7ceccdf63c5ba0d71e0
|
|
| MD5 |
4f5d7ea9638a528628e816436b7937d6
|
|
| BLAKE2b-256 |
4f19dac2412eaa91a909815b309ff9ce8490cc6c9cf5f2368312594067939709
|