mirror of
https://github.com/harry0703/MoneyPrinterTurbo.git
synced 2025-11-25 03:15:04 +08:00
feat: add test for voice service
This commit is contained in:
@@ -7,6 +7,7 @@ This directory contains unit tests for the **MoneyPrinterTurbo** project.
|
||||
- `services/`: Tests for components in the `app/services` directory
|
||||
- `test_video.py`: Tests for the video service
|
||||
- `test_task.py`: Tests for the task service
|
||||
- `test_voice.py`: Tests for the voice service
|
||||
|
||||
## Running Tests
|
||||
|
||||
|
||||
107
test/services/test_voice.py
Normal file
107
test/services/test_voice.py
Normal file
@@ -0,0 +1,107 @@
|
||||
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()
|
||||
Reference in New Issue
Block a user