test-api-fix3
This commit is contained in:
parent
c66a3a42b4
commit
cfa15f2c5c
@ -34,11 +34,17 @@ class CosyVoiceService:
|
|||||||
return []
|
return []
|
||||||
|
|
||||||
result = self.client.predict(api_name="/refresh_sft_spk")
|
result = self.client.predict(api_name="/refresh_sft_spk")
|
||||||
|
logger.info(f"音色列表原始返回: {result}")
|
||||||
|
|
||||||
# 处理返回的字典格式
|
# 处理返回的字典格式
|
||||||
if isinstance(result, dict) and 'choices' in result:
|
if isinstance(result, dict) and 'choices' in result:
|
||||||
# 从choices中提取音色名称
|
# 从choices中提取音色名称,格式是 [['name', 'name'], ...]
|
||||||
voices = [choice[0] for choice in result['choices'] if choice[0] != '.ipynb_checkpoints']
|
voices = []
|
||||||
|
for choice in result['choices']:
|
||||||
|
if isinstance(choice, list) and len(choice) > 0:
|
||||||
|
voice_name = choice[0]
|
||||||
|
if voice_name != '.ipynb_checkpoints':
|
||||||
|
voices.append(voice_name)
|
||||||
return voices
|
return voices
|
||||||
elif isinstance(result, list):
|
elif isinstance(result, list):
|
||||||
# 直接是列表格式
|
# 直接是列表格式
|
||||||
@ -62,7 +68,10 @@ class CosyVoiceService:
|
|||||||
|
|
||||||
# 处理返回的字典格式
|
# 处理返回的字典格式
|
||||||
if isinstance(result, dict) and 'choices' in result:
|
if isinstance(result, dict) and 'choices' in result:
|
||||||
audios = [choice[0] for choice in result['choices']]
|
audios = []
|
||||||
|
for choice in result['choices']:
|
||||||
|
if isinstance(choice, list) and len(choice) > 0:
|
||||||
|
audios.append(choice[0])
|
||||||
return audios
|
return audios
|
||||||
elif isinstance(result, list):
|
elif isinstance(result, list):
|
||||||
return result
|
return result
|
||||||
@ -89,6 +98,35 @@ class CosyVoiceService:
|
|||||||
logger.error(f"语音识别失败: {str(e)}")
|
logger.error(f"语音识别失败: {str(e)}")
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
def _create_empty_audio_file(self) -> str:
|
||||||
|
"""创建临时的空音频文件"""
|
||||||
|
import tempfile
|
||||||
|
import wave
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
# 创建临时文件
|
||||||
|
temp_fd, temp_path = tempfile.mkstemp(suffix='.wav')
|
||||||
|
os.close(temp_fd) # 关闭文件描述符
|
||||||
|
|
||||||
|
try:
|
||||||
|
# 创建一个很短的静音音频
|
||||||
|
with wave.open(temp_path, 'w') as wav_file:
|
||||||
|
wav_file.setnchannels(1) # 单声道
|
||||||
|
wav_file.setsampwidth(2) # 16位
|
||||||
|
wav_file.setframerate(16000) # 16kHz采样率
|
||||||
|
# 写入0.01秒的静音
|
||||||
|
silence = np.zeros(160, dtype=np.int16)
|
||||||
|
wav_file.writeframes(silence.tobytes())
|
||||||
|
|
||||||
|
return temp_path
|
||||||
|
except Exception as e:
|
||||||
|
# 如果创建失败,删除临时文件
|
||||||
|
try:
|
||||||
|
os.unlink(temp_path)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
raise e
|
||||||
|
|
||||||
def generate_speech_with_preset_voice(
|
def generate_speech_with_preset_voice(
|
||||||
self,
|
self,
|
||||||
text: str,
|
text: str,
|
||||||
@ -98,33 +136,22 @@ class CosyVoiceService:
|
|||||||
stream: bool = False
|
stream: bool = False
|
||||||
) -> Tuple[Optional[str], Optional[str]]:
|
) -> Tuple[Optional[str], Optional[str]]:
|
||||||
"""使用预训练音色生成语音"""
|
"""使用预训练音色生成语音"""
|
||||||
|
temp_audio_path = None
|
||||||
try:
|
try:
|
||||||
if not self.client:
|
if not self.client:
|
||||||
if not self.connect():
|
if not self.connect():
|
||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
# 创建临时空音频文件用于占位
|
# 创建临时空音频文件
|
||||||
import tempfile
|
temp_audio_path = self._create_empty_audio_file()
|
||||||
import wave
|
|
||||||
import numpy as np
|
|
||||||
|
|
||||||
# 创建一个短的静音音频作为占位符
|
|
||||||
temp_audio = tempfile.NamedTemporaryFile(suffix='.wav', delete=False)
|
|
||||||
with wave.open(temp_audio.name, 'w') as wav_file:
|
|
||||||
wav_file.setnchannels(1) # 单声道
|
|
||||||
wav_file.setsampwidth(2) # 16位
|
|
||||||
wav_file.setframerate(16000) # 16kHz采样率
|
|
||||||
# 写入很短的静音(0.1秒)
|
|
||||||
silence = np.zeros(1600, dtype=np.int16)
|
|
||||||
wav_file.writeframes(silence.tobytes())
|
|
||||||
|
|
||||||
result = self.client.predict(
|
result = self.client.predict(
|
||||||
tts_text=text,
|
tts_text=text,
|
||||||
mode_checkbox_group="预训练音色",
|
mode_checkbox_group="预训练音色",
|
||||||
sft_dropdown=voice,
|
sft_dropdown=voice,
|
||||||
prompt_text="",
|
prompt_text="",
|
||||||
prompt_wav_upload=handle_file(temp_audio.name),
|
prompt_wav_upload=handle_file(temp_audio_path),
|
||||||
prompt_wav_record=handle_file(temp_audio.name),
|
prompt_wav_record=handle_file(temp_audio_path),
|
||||||
instruct_text="",
|
instruct_text="",
|
||||||
seed=float(seed),
|
seed=float(seed),
|
||||||
stream="True" if stream else "False",
|
stream="True" if stream else "False",
|
||||||
@ -132,11 +159,7 @@ class CosyVoiceService:
|
|||||||
api_name="/generate_audio"
|
api_name="/generate_audio"
|
||||||
)
|
)
|
||||||
|
|
||||||
# 清理临时文件
|
logger.info(f"预训练音色生成结果: {result}")
|
||||||
try:
|
|
||||||
os.unlink(temp_audio.name)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# result是一个元组 [流式音频路径, 完整音频路径]
|
# result是一个元组 [流式音频路径, 完整音频路径]
|
||||||
if isinstance(result, (list, tuple)) and len(result) >= 2:
|
if isinstance(result, (list, tuple)) and len(result) >= 2:
|
||||||
@ -147,6 +170,13 @@ class CosyVoiceService:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"预训练音色语音生成失败: {str(e)}")
|
logger.error(f"预训练音色语音生成失败: {str(e)}")
|
||||||
return None, None
|
return None, None
|
||||||
|
finally:
|
||||||
|
# 清理临时文件
|
||||||
|
if temp_audio_path and os.path.exists(temp_audio_path):
|
||||||
|
try:
|
||||||
|
os.unlink(temp_audio_path)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
def generate_speech_with_voice_cloning(
|
def generate_speech_with_voice_cloning(
|
||||||
self,
|
self,
|
||||||
@ -198,33 +228,22 @@ class CosyVoiceService:
|
|||||||
seed: int = 42
|
seed: int = 42
|
||||||
) -> Tuple[Optional[str], Optional[str]]:
|
) -> Tuple[Optional[str], Optional[str]]:
|
||||||
"""使用自然语言控制生成语音"""
|
"""使用自然语言控制生成语音"""
|
||||||
|
temp_audio_path = None
|
||||||
try:
|
try:
|
||||||
if not self.client:
|
if not self.client:
|
||||||
if not self.connect():
|
if not self.connect():
|
||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
# 创建临时空音频文件用于占位
|
# 创建临时空音频文件
|
||||||
import tempfile
|
temp_audio_path = self._create_empty_audio_file()
|
||||||
import wave
|
|
||||||
import numpy as np
|
|
||||||
|
|
||||||
# 创建一个短的静音音频作为占位符
|
|
||||||
temp_audio = tempfile.NamedTemporaryFile(suffix='.wav', delete=False)
|
|
||||||
with wave.open(temp_audio.name, 'w') as wav_file:
|
|
||||||
wav_file.setnchannels(1) # 单声道
|
|
||||||
wav_file.setsampwidth(2) # 16位
|
|
||||||
wav_file.setframerate(16000) # 16kHz采样率
|
|
||||||
# 写入很短的静音(0.1秒)
|
|
||||||
silence = np.zeros(1600, dtype=np.int16)
|
|
||||||
wav_file.writeframes(silence.tobytes())
|
|
||||||
|
|
||||||
result = self.client.predict(
|
result = self.client.predict(
|
||||||
tts_text=text,
|
tts_text=text,
|
||||||
mode_checkbox_group="自然语言控制",
|
mode_checkbox_group="自然语言控制",
|
||||||
sft_dropdown="中文女",
|
sft_dropdown="中文女",
|
||||||
prompt_text="",
|
prompt_text="",
|
||||||
prompt_wav_upload=handle_file(temp_audio.name),
|
prompt_wav_upload=handle_file(temp_audio_path),
|
||||||
prompt_wav_record=handle_file(temp_audio.name),
|
prompt_wav_record=handle_file(temp_audio_path),
|
||||||
instruct_text=instruction,
|
instruct_text=instruction,
|
||||||
seed=float(seed),
|
seed=float(seed),
|
||||||
stream="False",
|
stream="False",
|
||||||
@ -232,12 +251,6 @@ class CosyVoiceService:
|
|||||||
api_name="/generate_audio"
|
api_name="/generate_audio"
|
||||||
)
|
)
|
||||||
|
|
||||||
# 清理临时文件
|
|
||||||
try:
|
|
||||||
os.unlink(temp_audio.name)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if isinstance(result, (list, tuple)) and len(result) >= 2:
|
if isinstance(result, (list, tuple)) and len(result) >= 2:
|
||||||
return result[0], result[1]
|
return result[0], result[1]
|
||||||
else:
|
else:
|
||||||
@ -246,6 +259,13 @@ class CosyVoiceService:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"自然语言控制语音生成失败: {str(e)}")
|
logger.error(f"自然语言控制语音生成失败: {str(e)}")
|
||||||
return None, None
|
return None, None
|
||||||
|
finally:
|
||||||
|
# 清理临时文件
|
||||||
|
if temp_audio_path and os.path.exists(temp_audio_path):
|
||||||
|
try:
|
||||||
|
os.unlink(temp_audio_path)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
def generate_random_seed(self) -> int:
|
def generate_random_seed(self) -> int:
|
||||||
"""生成随机种子"""
|
"""生成随机种子"""
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user