115 lines
5.1 KiB
Python
115 lines
5.1 KiB
Python
#!/usr/bin/env python3
|
||
# -*- coding: utf-8 -*-
|
||
"""
|
||
播客对话生成脚本
|
||
生成Sonia和Author的对话,不使用Judy
|
||
"""
|
||
|
||
import asyncio
|
||
import edge_tts
|
||
import os
|
||
import json
|
||
from datetime import datetime
|
||
|
||
class PodcastGenerator:
|
||
def __init__(self):
|
||
# 加载角色配置
|
||
config_path = "output/podcast/characters/character_config.json"
|
||
if os.path.exists(config_path):
|
||
with open(config_path, 'r', encoding='utf-8') as f:
|
||
self.config = json.load(f)
|
||
else:
|
||
# 如果配置文件不存在,使用默认配置
|
||
self.config = {
|
||
"Sonia": {"voice_model": "en-GB-RyanNeural"},
|
||
"Author": {"voice_model": "en-US-GuyNeural"}
|
||
}
|
||
|
||
async def generate_audio(self, text, voice, output_file):
|
||
"""生成音频文件"""
|
||
communicate = edge_tts.Communicate(text, voice)
|
||
await communicate.save(output_file)
|
||
print(f"✓ 生成音频: {output_file}")
|
||
|
||
def create_podcast_script(self):
|
||
"""创建播客对话脚本"""
|
||
script = [
|
||
{
|
||
"speaker": "Sonia",
|
||
"text": "欢迎来到本期节目,今天我们有幸邀请到作者,一起回顾2001-2009年这段特殊的历史时期。这段时间被称为'韩信的入场券',充满了复杂的地缘政治变化。能否请您为我们概述一下这个时代的主要特点?"
|
||
},
|
||
{
|
||
"speaker": "Author",
|
||
"text": "这个时代最突出的特点是中国的战略隐忍。面对1999年大使馆被炸的屈辱、2001年南海撞机的紧张局势,中国选择了与美国合作反恐,从而获得了宝贵的发展窗口期。"
|
||
},
|
||
{
|
||
"speaker": "Sonia",
|
||
"text": "在2008年金融危机中,您特别提到了一个叫'高斯联结函数'的数学模型,以及它如何影响了亚洲歌神张学友的投资。这个数学模型究竟是如何运作的?"
|
||
},
|
||
{
|
||
"speaker": "Author",
|
||
"text": "这个模型由华裔数学家李祥林提出,它巧妙地'删除'了违约的相关性,使得一篮子高风险贷款可以被评级为AAA级资产。张学友投资的雷曼兄弟迷你债券正是被这种模型包装后的产品,导致他损失了约4000万港币。"
|
||
},
|
||
{
|
||
"speaker": "Sonia",
|
||
"text": "您提到了'瓦良格'号航母和普京寻求加入北约被拒的事件。这两件事看似无关,但它们如何共同构成了中国崛起的战略机遇?"
|
||
},
|
||
{
|
||
"speaker": "Author",
|
||
"text": "这是一个非常有趣的巧合。美国忙于反恐战争,无力阻止中国购买并改造'瓦良格'号;同时,北约拒绝普京的加入请求,迫使俄罗斯转向与中国合作。这两大因素为中国创造了有利的外部环境。"
|
||
},
|
||
{
|
||
"speaker": "Sonia",
|
||
"text": "最后一个问题,您认为2001-2009年这段时间为中国后来的发展奠定了怎样的基础?"
|
||
},
|
||
{
|
||
"speaker": "Author",
|
||
"text": "这十年是中国嵌入全球产业链、积累资本和技术的关键时期。通过隐忍和务实的战略,中国不仅成功避免了与美国的直接冲突,还利用了美国的战略重心转移,实现了经济的快速发展。"
|
||
},
|
||
{
|
||
"speaker": "Sonia",
|
||
"text": "感谢您今天的精彩分享,让我们更好地理解了这一段复杂而重要的历史。"
|
||
}
|
||
]
|
||
return script
|
||
|
||
async def generate_podcast(self):
|
||
"""生成播客音频"""
|
||
script = self.create_podcast_script()
|
||
|
||
# 创建输出目录
|
||
output_dir = "output/podcast/interview"
|
||
os.makedirs(output_dir, exist_ok=True)
|
||
|
||
tasks = []
|
||
for i, line in enumerate(script):
|
||
speaker = line["speaker"]
|
||
text = line["text"]
|
||
|
||
# 获取角色的语音模型
|
||
voice_model = self.config.get(speaker, {}).get("voice_model", "en-US-GuyNeural")
|
||
|
||
# 生成音频文件
|
||
output_file = f"{output_dir}/{speaker.lower()}_{i+1:02d}.mp3"
|
||
task = self.generate_audio(text, voice_model, output_file)
|
||
tasks.append(task)
|
||
|
||
# 并行执行所有音频生成任务
|
||
await asyncio.gather(*tasks)
|
||
|
||
# 创建脚本文件
|
||
script_file = f"{output_dir}/podcast_script.txt"
|
||
with open(script_file, 'w', encoding='utf-8') as f:
|
||
for line in script:
|
||
f.write(f"{line['speaker']}: {line['text']}\n\n")
|
||
|
||
print(f"\n✓ 播客脚本已保存到: {script_file}")
|
||
print(f"✓ 共生成 {len(script)} 个音频片段")
|
||
print("✓ 播客生成完成!")
|
||
|
||
async def main():
|
||
generator = PodcastGenerator()
|
||
await generator.generate_podcast()
|
||
|
||
if __name__ == "__main__":
|
||
asyncio.run(main()) |