76 lines
2.3 KiB
Python
76 lines
2.3 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
import asyncio
|
|
import uuid
|
|
from pathlib import Path
|
|
from typing import Optional, Tuple
|
|
|
|
import edge_tts
|
|
from mutagen.mp3 import MP3
|
|
|
|
|
|
class EdgeTTS:
|
|
"""
|
|
edge在线语音合成
|
|
"""
|
|
|
|
# 中文音色
|
|
TIMBRES = {
|
|
"女声-晓晓": "zh-CN-XiaoxiaoNeural",
|
|
"女声-晓辰": "zh-CN-XiaochenNeural",
|
|
"女声-晓倩": "zh-CN-XiaoqianNeural",
|
|
}
|
|
|
|
def __init__(
|
|
self,
|
|
materials_path: Path,
|
|
):
|
|
"""
|
|
初始化语音合成器
|
|
:param materials_path: 素材文件夹路径
|
|
"""
|
|
# 素材文件夹路径
|
|
self.materials_path = materials_path
|
|
|
|
def generate_audio(
|
|
self,
|
|
content: str,
|
|
timbre: Optional[str] = "女声-晓晓",
|
|
rate: str = "+0%",
|
|
volume: str = "+0%",
|
|
) -> Tuple[str, int]:
|
|
"""
|
|
根据文本内容合成语音并返回音频素材名称
|
|
:param content: 文本内容
|
|
:param timbre: 音色名称,例如女声-晓晓
|
|
:param rate: 语速
|
|
:param volume: 音量
|
|
:return 音频素材名称和持续时长
|
|
"""
|
|
# noinspection PyBroadException
|
|
try:
|
|
# 异步处理:根据文本内容合成语音并保存为音频素材
|
|
async def _async_generate_audio():
|
|
# 实例化Communicate
|
|
communicator = edge_tts.Communicate(
|
|
text=content,
|
|
voice=self.TIMBRES[timbre],
|
|
rate=rate,
|
|
volume=volume,
|
|
)
|
|
# 音频素材名称
|
|
name = f"{uuid.uuid4().hex[-16:].upper()}.mp3"
|
|
# 音频素材路径
|
|
audio_path = self.materials_path / name
|
|
await communicator.save(audio_path := audio_path.as_posix())
|
|
# 音频持续时长(单位为微妙)
|
|
duration = int(round(MP3(audio_path).info.length * 1000000))
|
|
return name, duration
|
|
|
|
# 同步调用异步逻辑,对外暴露纯同步接口
|
|
return asyncio.run(_async_generate_audio())
|
|
except Exception as exception:
|
|
raise RuntimeError(
|
|
f"根据文本内容合成语音并保存为音频素材发声异常:{str(exception)}"
|
|
)
|