mpt2026 / test /services /test_voice.py
chaowenguo's picture
Upload 108 files
e58b6a6 verified
import asyncio
import unittest
import os
import sys
from pathlib import Path
# add project root to python path
sys.path.insert(0, str(Path(__file__).parent.parent.parent))
from app.utils import utils
from app.services import voice as vs
temp_dir = utils.storage_dir("temp")
text_en = """
What is the meaning of life?
This question has puzzled philosophers, scientists, and thinkers of all kinds for centuries.
Throughout history, various cultures and individuals have come up with their interpretations and beliefs around the purpose of life.
Some say it's to seek happiness and self-fulfillment, while others believe it's about contributing to the welfare of others and making a positive impact in the world.
Despite the myriad of perspectives, one thing remains clear: the meaning of life is a deeply personal concept that varies from one person to another.
It's an existential inquiry that encourages us to reflect on our values, desires, and the essence of our existence.
"""
text_zh = """
预计未来3天深圳冷空气活动频繁,未来两天持续阴天有小雨,出门带好雨具;
10-11日持续阴天有小雨,日温差小,气温在13-17℃之间,体感阴凉;
12日天气短暂好转,早晚清凉;
"""
voice_rate=1.0
voice_volume=1.0
class TestVoiceService(unittest.TestCase):
def setUp(self):
self.loop = asyncio.new_event_loop()
asyncio.set_event_loop(self.loop)
def tearDown(self):
self.loop.close()
def test_siliconflow(self):
voice_name = "siliconflow:FunAudioLLM/CosyVoice2-0.5B:alex-Male"
voice_name = vs.parse_voice_name(voice_name)
async def _do():
parts = voice_name.split(":")
if len(parts) >= 3:
model = parts[1]
# 移除性别后缀,例如 "alex-Male" -> "alex"
voice_with_gender = parts[2]
voice = voice_with_gender.split("-")[0]
# 构建完整的voice参数,格式为 "model:voice"
full_voice = f"{model}:{voice}"
voice_file = f"{temp_dir}/tts-siliconflow-{voice}.mp3"
subtitle_file = f"{temp_dir}/tts-siliconflow-{voice}.srt"
sub_maker = vs.siliconflow_tts(
text=text_zh, model=model, voice=full_voice, voice_file=voice_file, voice_rate=voice_rate, voice_volume=voice_volume
)
if not sub_maker:
self.fail("siliconflow tts failed")
vs.create_subtitle(sub_maker=sub_maker, text=text_zh, subtitle_file=subtitle_file)
audio_duration = vs.get_audio_duration(sub_maker)
print(f"voice: {voice_name}, audio duration: {audio_duration}s")
else:
self.fail("siliconflow invalid voice name")
self.loop.run_until_complete(_do())
def test_azure_tts_v1(self):
voice_name = "zh-CN-XiaoyiNeural-Female"
voice_name = vs.parse_voice_name(voice_name)
print(voice_name)
voice_file = f"{temp_dir}/tts-azure-v1-{voice_name}.mp3"
subtitle_file = f"{temp_dir}/tts-azure-v1-{voice_name}.srt"
sub_maker = vs.azure_tts_v1(
text=text_zh, voice_name=voice_name, voice_file=voice_file, voice_rate=voice_rate
)
if not sub_maker:
self.fail("azure tts v1 failed")
vs.create_subtitle(sub_maker=sub_maker, text=text_zh, subtitle_file=subtitle_file)
audio_duration = vs.get_audio_duration(sub_maker)
print(f"voice: {voice_name}, audio duration: {audio_duration}s")
def test_azure_tts_v2(self):
voice_name = "zh-CN-XiaoxiaoMultilingualNeural-V2-Female"
voice_name = vs.parse_voice_name(voice_name)
print(voice_name)
async def _do():
voice_file = f"{temp_dir}/tts-azure-v2-{voice_name}.mp3"
subtitle_file = f"{temp_dir}/tts-azure-v2-{voice_name}.srt"
sub_maker = vs.azure_tts_v2(
text=text_zh, voice_name=voice_name, voice_file=voice_file
)
if not sub_maker:
self.fail("azure tts v2 failed")
vs.create_subtitle(sub_maker=sub_maker, text=text_zh, subtitle_file=subtitle_file)
audio_duration = vs.get_audio_duration(sub_maker)
print(f"voice: {voice_name}, audio duration: {audio_duration}s")
self.loop.run_until_complete(_do())
if __name__ == "__main__":
# python -m unittest test.services.test_voice.TestVoiceService.test_azure_tts_v1
# python -m unittest test.services.test_voice.TestVoiceService.test_azure_tts_v2
unittest.main()