fix:aliyun,cozecn,custom,doubao,gpt_sovits_v2,gpt_sovits_v3,minimax,openai,siliconflow,ttson,这些tts兼容

This commit is contained in:
lizhongxiang
2025-03-31 16:31:06 +08:00
parent 93265be974
commit cc4aed5a8e
10 changed files with 195 additions and 25 deletions
@@ -6,6 +6,9 @@ import hashlib
import base64 import base64
import requests import requests
from datetime import datetime from datetime import datetime
from pydub import AudioSegment
from core.providers.tts.base import TTSProviderBase from core.providers.tts.base import TTSProviderBase
import http.client import http.client
@@ -13,6 +16,10 @@ import urllib.parse
import time import time
import uuid import uuid
from urllib import parse from urllib import parse
from core.providers.tts.dto.dto import TTSMessageDTO, MsgType, SentenceType
class AccessToken: class AccessToken:
@staticmethod @staticmethod
def _encode_text(text): def _encode_text(text):
@@ -105,7 +112,7 @@ class TTSProvider(TTSProviderBase):
def generate_filename(self, extension=".wav"): def generate_filename(self, extension=".wav"):
return os.path.join(self.output_file, f"tts-{__name__}{datetime.now().date()}@{uuid.uuid4().hex}{extension}") return os.path.join(self.output_file, f"tts-{__name__}{datetime.now().date()}@{uuid.uuid4().hex}{extension}")
async def text_to_speak(self, text, output_file): async def text_to_speak(self, u_id, text, is_last_text=False, is_first_text=False):
request_json = { request_json = {
"appkey": self.appkey, "appkey": self.appkey,
"token": self.token, "token": self.token,
@@ -119,14 +126,26 @@ class TTSProvider(TTSProviderBase):
} }
print(self.api_url, json.dumps(request_json, ensure_ascii=False)) print(self.api_url, json.dumps(request_json, ensure_ascii=False))
tmp_file = self.generate_filename()
try: try:
resp = requests.post(self.api_url, json.dumps(request_json), headers=self.header) resp = requests.post(self.api_url, json.dumps(request_json), headers=self.header)
# 检查返回请求数据的mime类型是否是audio/***,是则保存到指定路径下;返回的是binary格式的 # 检查返回请求数据的mime类型是否是audio/***,是则保存到指定路径下;返回的是binary格式的
if resp.headers['Content-Type'].startswith('audio/'): if resp.headers['Content-Type'].startswith('audio/'):
with open(output_file, 'wb') as f: with open(tmp_file, 'wb') as f:
f.write(resp.content) f.write(resp.content)
return output_file
else: else:
raise Exception(f"{__name__} status_code: {resp.status_code} response: {resp.content}") raise Exception(f"{__name__} status_code: {resp.status_code} response: {resp.content}")
# 使用 pydub 读取临时文件
audio = AudioSegment.from_file(tmp_file, format="wav")
audio = audio.set_channels(1).set_frame_rate(16000)
opus_datas = self.wav_to_opus_data_audio_raw(audio.raw_data)
yield TTSMessageDTO(u_id=u_id, msg_type=MsgType.TTS_TEXT_RESPONSE, content=opus_datas,
tts_finish_text=text, sentence_type=SentenceType.SENTENCE_START)
# 用完后删除临时文件
try:
os.remove(tmp_file)
except FileNotFoundError:
# 若文件不存在,忽略该异常
pass
except Exception as e: except Exception as e:
raise Exception(f"{__name__} error: {e}") raise Exception(f"{__name__} error: {e}")
@@ -4,7 +4,11 @@ import json
import base64 import base64
import requests import requests
from datetime import datetime from datetime import datetime
from pydub import AudioSegment
from core.providers.tts.base import TTSProviderBase from core.providers.tts.base import TTSProviderBase
from core.providers.tts.dto.dto import TTSMessageDTO, MsgType, SentenceType
class TTSProvider(TTSProviderBase): class TTSProvider(TTSProviderBase):
@@ -21,7 +25,7 @@ class TTSProvider(TTSProviderBase):
def generate_filename(self, extension=".wav"): def generate_filename(self, extension=".wav"):
return os.path.join(self.output_file, f"tts-{datetime.now().date()}@{uuid.uuid4().hex}{extension}") return os.path.join(self.output_file, f"tts-{datetime.now().date()}@{uuid.uuid4().hex}{extension}")
async def text_to_speak(self, text, output_file): async def text_to_speak(self, u_id, text, is_last_text=False, is_first_text=False):
request_json = { request_json = {
"model": self.model, "model": self.model,
"input": text, "input": text,
@@ -34,5 +38,18 @@ class TTSProvider(TTSProviderBase):
} }
response = requests.request("POST", self.api_url, json=request_json, headers=headers) response = requests.request("POST", self.api_url, json=request_json, headers=headers)
data = response.content data = response.content
file_to_save = open(output_file, "wb") tmp_file = self.generate_filename()
file_to_save = open(tmp_file, "wb")
file_to_save.write(data) file_to_save.write(data)
# 使用 pydub 读取临时文件
audio = AudioSegment.from_file(tmp_file, format="wav")
audio = audio.set_channels(1).set_frame_rate(16000)
opus_datas = self.wav_to_opus_data_audio_raw(audio.raw_data)
yield TTSMessageDTO(u_id=u_id, msg_type=MsgType.TTS_TEXT_RESPONSE, content=opus_datas, tts_finish_text=text,
sentence_type=SentenceType.SENTENCE_START)
# 用完后删除临时文件
try:
os.remove(tmp_file)
except FileNotFoundError:
# 若文件不存在,忽略该异常
pass
@@ -1,13 +1,17 @@
import os import os
import uuid import uuid
import requests import requests
from pydub import AudioSegment
from config.logger import setup_logging from config.logger import setup_logging
from datetime import datetime from datetime import datetime
from core.providers.tts.base import TTSProviderBase from core.providers.tts.base import TTSProviderBase
from core.providers.tts.dto.dto import TTSMessageDTO, MsgType, SentenceType
TAG = __name__ TAG = __name__
logger = setup_logging() logger = setup_logging()
class TTSProvider(TTSProviderBase): class TTSProvider(TTSProviderBase):
def __init__(self, config, delete_audio_file): def __init__(self, config, delete_audio_file):
super().__init__(config, delete_audio_file) super().__init__(config, delete_audio_file)
@@ -20,8 +24,9 @@ class TTSProvider(TTSProviderBase):
def generate_filename(self): def generate_filename(self):
return os.path.join(self.output_file, f"tts-{datetime.now().date()}@{uuid.uuid4().hex}.{self.format}") return os.path.join(self.output_file, f"tts-{datetime.now().date()}@{uuid.uuid4().hex}.{self.format}")
async def text_to_speak(self, text, output_file): async def text_to_speak(self, u_id, text, is_last_text=False, is_first_text=False):
request_params = {} request_params = {}
tmp_file = self.generate_filename()
for k, v in self.params.items(): for k, v in self.params.items():
if isinstance(v, str) and "{prompt_text}" in v: if isinstance(v, str) and "{prompt_text}" in v:
v = v.replace("{prompt_text}", text) v = v.replace("{prompt_text}", text)
@@ -29,7 +34,19 @@ class TTSProvider(TTSProviderBase):
resp = requests.get(self.url, params=request_params, headers=self.headers) resp = requests.get(self.url, params=request_params, headers=self.headers)
if resp.status_code == 200: if resp.status_code == 200:
with open(output_file, "wb") as file: with open(tmp_file, "wb") as file:
file.write(resp.content) file.write(resp.content)
else: else:
logger.bind(tag=TAG).error(f"Custom TTS请求失败: {resp.status_code} - {resp.text}") logger.bind(tag=TAG).error(f"Custom TTS请求失败: {resp.status_code} - {resp.text}")
# 使用 pydub 读取临时文件
audio = AudioSegment.from_file(tmp_file, format=self.format)
audio = audio.set_channels(1).set_frame_rate(16000)
opus_datas = self.wav_to_opus_data_audio_raw(audio.raw_data)
yield TTSMessageDTO(u_id=u_id, msg_type=MsgType.TTS_TEXT_RESPONSE, content=opus_datas, tts_finish_text=text,
sentence_type=SentenceType.SENTENCE_START)
# 用完后删除临时文件
try:
os.remove(tmp_file)
except FileNotFoundError:
# 若文件不存在,忽略该异常
pass
@@ -4,6 +4,10 @@ import json
import base64 import base64
import requests import requests
from datetime import datetime from datetime import datetime
from pydub import AudioSegment
from core.providers.tts.dto.dto import TTSMessageDTO, MsgType, SentenceType
from core.utils.util import check_model_key from core.utils.util import check_model_key
from core.providers.tts.base import TTSProviderBase from core.providers.tts.base import TTSProviderBase
@@ -23,7 +27,8 @@ class TTSProvider(TTSProviderBase):
def generate_filename(self, extension=".wav"): def generate_filename(self, extension=".wav"):
return os.path.join(self.output_file, f"tts-{datetime.now().date()}@{uuid.uuid4().hex}{extension}") return os.path.join(self.output_file, f"tts-{datetime.now().date()}@{uuid.uuid4().hex}{extension}")
async def text_to_speak(self, text, output_file): async def text_to_speak(self, u_id, text, is_last_text=False, is_first_text=False):
tmp_file = self.generate_filename()
request_json = { request_json = {
"app": { "app": {
"appid": f"{self.appid}", "appid": f"{self.appid}",
@@ -54,9 +59,21 @@ class TTSProvider(TTSProviderBase):
resp = requests.post(self.api_url, json.dumps(request_json), headers=self.header) resp = requests.post(self.api_url, json.dumps(request_json), headers=self.header)
if "data" in resp.json(): if "data" in resp.json():
data = resp.json()["data"] data = resp.json()["data"]
file_to_save = open(output_file, "wb") file_to_save = open(tmp_file, "wb")
file_to_save.write(base64.b64decode(data)) file_to_save.write(base64.b64decode(data))
else: else:
raise Exception(f"{__name__} status_code: {resp.status_code} response: {resp.content}") raise Exception(f"{__name__} status_code: {resp.status_code} response: {resp.content}")
except Exception as e: except Exception as e:
raise Exception(f"{__name__} error: {e}") raise Exception(f"{__name__} error: {e}")
# 使用 pydub 读取临时文件
audio = AudioSegment.from_file(tmp_file, format="wav")
audio = audio.set_channels(1).set_frame_rate(16000)
opus_datas = self.wav_to_opus_data_audio_raw(audio.raw_data)
yield TTSMessageDTO(u_id=u_id, msg_type=MsgType.TTS_TEXT_RESPONSE, content=opus_datas, tts_finish_text=text,
sentence_type=SentenceType.SENTENCE_START)
# 用完后删除临时文件
try:
os.remove(tmp_file)
except FileNotFoundError:
# 若文件不存在,忽略该异常
pass
@@ -3,9 +3,12 @@ import uuid
import json import json
import base64 import base64
import requests import requests
from pydub import AudioSegment
from config.logger import setup_logging from config.logger import setup_logging
from datetime import datetime from datetime import datetime
from core.providers.tts.base import TTSProviderBase from core.providers.tts.base import TTSProviderBase
from core.providers.tts.dto.dto import TTSMessageDTO, MsgType, SentenceType
TAG = __name__ TAG = __name__
logger = setup_logging() logger = setup_logging()
@@ -36,7 +39,8 @@ class TTSProvider(TTSProviderBase):
def generate_filename(self, extension=".wav"): def generate_filename(self, extension=".wav"):
return os.path.join(self.output_file, f"tts-{datetime.now().date()}@{uuid.uuid4().hex}{extension}") return os.path.join(self.output_file, f"tts-{datetime.now().date()}@{uuid.uuid4().hex}{extension}")
async def text_to_speak(self, text, output_file): async def text_to_speak(self, u_id, text, is_last_text=False, is_first_text=False):
tmp_file = self.generate_filename()
request_json = { request_json = {
"text": text, "text": text,
"text_lang": self.text_lang, "text_lang": self.text_lang,
@@ -61,7 +65,19 @@ class TTSProvider(TTSProviderBase):
resp = requests.post(self.url, json=request_json) resp = requests.post(self.url, json=request_json)
if resp.status_code == 200: if resp.status_code == 200:
with open(output_file, "wb") as file: with open(tmp_file, "wb") as file:
file.write(resp.content) file.write(resp.content)
else: else:
logger.bind(tag=TAG).error(f"GPT_SoVITS_V2 TTS请求失败: {resp.status_code} - {resp.text}") logger.bind(tag=TAG).error(f"GPT_SoVITS_V2 TTS请求失败: {resp.status_code} - {resp.text}")
# 使用 pydub 读取临时文件
audio = AudioSegment.from_file(tmp_file, format="wav")
audio = audio.set_channels(1).set_frame_rate(16000)
opus_datas = self.wav_to_opus_data_audio_raw(audio.raw_data)
yield TTSMessageDTO(u_id=u_id, msg_type=MsgType.TTS_TEXT_RESPONSE, content=opus_datas, tts_finish_text=text,
sentence_type=SentenceType.SENTENCE_START)
# 用完后删除临时文件
try:
os.remove(tmp_file)
except FileNotFoundError:
# 若文件不存在,忽略该异常
pass
@@ -1,9 +1,12 @@
import os import os
import uuid import uuid
import requests import requests
from pydub import AudioSegment
from config.logger import setup_logging from config.logger import setup_logging
from datetime import datetime from datetime import datetime
from core.providers.tts.base import TTSProviderBase from core.providers.tts.base import TTSProviderBase
from core.providers.tts.dto.dto import TTSMessageDTO, MsgType, SentenceType
TAG = __name__ TAG = __name__
logger = setup_logging() logger = setup_logging()
@@ -29,7 +32,8 @@ class TTSProvider(TTSProviderBase):
def generate_filename(self, extension=".wav"): def generate_filename(self, extension=".wav"):
return os.path.join(self.output_file, f"tts-{datetime.now().date()}@{uuid.uuid4().hex}{extension}") return os.path.join(self.output_file, f"tts-{datetime.now().date()}@{uuid.uuid4().hex}{extension}")
async def text_to_speak(self, text, output_file): async def text_to_speak(self, u_id, text, is_last_text=False, is_first_text=False):
tmp_file = self.generate_filename()
request_params = { request_params = {
"refer_wav_path": self.refer_wav_path, "refer_wav_path": self.refer_wav_path,
"prompt_text": self.prompt_text, "prompt_text": self.prompt_text,
@@ -48,7 +52,19 @@ class TTSProvider(TTSProviderBase):
resp = requests.get(self.url, params=request_params) resp = requests.get(self.url, params=request_params)
if resp.status_code == 200: if resp.status_code == 200:
with open(output_file, "wb") as file: with open(tmp_file, "wb") as file:
file.write(resp.content) file.write(resp.content)
else: else:
logger.bind(tag=TAG).error(f"GPT_SoVITS_V3 TTS请求失败: {resp.status_code} - {resp.text}") logger.bind(tag=TAG).error(f"GPT_SoVITS_V3 TTS请求失败: {resp.status_code} - {resp.text}")
# 使用 pydub 读取临时文件
audio = AudioSegment.from_file(tmp_file, format="wav")
audio = audio.set_channels(1).set_frame_rate(16000)
opus_datas = self.wav_to_opus_data_audio_raw(audio.raw_data)
yield TTSMessageDTO(u_id=u_id, msg_type=MsgType.TTS_TEXT_RESPONSE, content=opus_datas, tts_finish_text=text,
sentence_type=SentenceType.SENTENCE_START)
# 用完后删除临时文件
try:
os.remove(tmp_file)
except FileNotFoundError:
# 若文件不存在,忽略该异常
pass
@@ -3,7 +3,11 @@ import uuid
import json import json
import requests import requests
from datetime import datetime from datetime import datetime
from pydub import AudioSegment
from core.providers.tts.base import TTSProviderBase from core.providers.tts.base import TTSProviderBase
from core.providers.tts.dto.dto import TTSMessageDTO, MsgType, SentenceType
class TTSProvider(TTSProviderBase): class TTSProvider(TTSProviderBase):
@@ -50,7 +54,8 @@ class TTSProvider(TTSProviderBase):
def generate_filename(self, extension=".mp3"): def generate_filename(self, extension=".mp3"):
return os.path.join(self.output_file, f"tts-{__name__}{datetime.now().date()}@{uuid.uuid4().hex}{extension}") return os.path.join(self.output_file, f"tts-{__name__}{datetime.now().date()}@{uuid.uuid4().hex}{extension}")
async def text_to_speak(self, text, output_file): async def text_to_speak(self, u_id, text, is_last_text=False, is_first_text=False):
tmp_file = self.generate_filename()
request_json = { request_json = {
"model": self.model, "model": self.model,
"text": text, "text": text,
@@ -69,9 +74,21 @@ class TTSProvider(TTSProviderBase):
# 检查返回请求数据的status_code是否为0 # 检查返回请求数据的status_code是否为0
if resp.json()["base_resp"]["status_code"] == 0: if resp.json()["base_resp"]["status_code"] == 0:
data = resp.json()['data']['audio'] data = resp.json()['data']['audio']
file_to_save = open(output_file, "wb") file_to_save = open(tmp_file, "wb")
file_to_save.write(bytes.fromhex(data)) file_to_save.write(bytes.fromhex(data))
else: else:
raise Exception(f"{__name__} status_code: {resp.status_code} response: {resp.content}") raise Exception(f"{__name__} status_code: {resp.status_code} response: {resp.content}")
except Exception as e: except Exception as e:
raise Exception(f"{__name__} error: {e}") raise Exception(f"{__name__} error: {e}")
# 使用 pydub 读取临时文件
audio = AudioSegment.from_file(tmp_file, format="mp3")
audio = audio.set_channels(1).set_frame_rate(16000)
opus_datas = self.wav_to_opus_data_audio_raw(audio.raw_data)
yield TTSMessageDTO(u_id=u_id, msg_type=MsgType.TTS_TEXT_RESPONSE, content=opus_datas, tts_finish_text=text,
sentence_type=SentenceType.SENTENCE_START)
# 用完后删除临时文件
try:
os.remove(tmp_file)
except FileNotFoundError:
# 若文件不存在,忽略该异常
pass
@@ -2,6 +2,10 @@ import os
import uuid import uuid
import requests import requests
from datetime import datetime from datetime import datetime
from pydub import AudioSegment
from core.providers.tts.dto.dto import TTSMessageDTO, MsgType, SentenceType
from core.utils.util import check_model_key from core.utils.util import check_model_key
from core.providers.tts.base import TTSProviderBase from core.providers.tts.base import TTSProviderBase
@@ -20,7 +24,8 @@ class TTSProvider(TTSProviderBase):
def generate_filename(self, extension=".wav"): def generate_filename(self, extension=".wav"):
return os.path.join(self.output_file, f"tts-{datetime.now().date()}@{uuid.uuid4().hex}{extension}") return os.path.join(self.output_file, f"tts-{datetime.now().date()}@{uuid.uuid4().hex}{extension}")
async def text_to_speak(self, text, output_file): async def text_to_speak(self, u_id, text, is_last_text=False, is_first_text=False):
tmp_file = self.generate_filename()
headers = { headers = {
"Authorization": f"Bearer {self.api_key}", "Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json" "Content-Type": "application/json"
@@ -34,7 +39,19 @@ class TTSProvider(TTSProviderBase):
} }
response = requests.post(self.api_url, json=data, headers=headers) response = requests.post(self.api_url, json=data, headers=headers)
if response.status_code == 200: if response.status_code == 200:
with open(output_file, "wb") as audio_file: with open(tmp_file, "wb") as audio_file:
audio_file.write(response.content) audio_file.write(response.content)
else: else:
raise Exception(f"OpenAI TTS请求失败: {response.status_code} - {response.text}") raise Exception(f"OpenAI TTS请求失败: {response.status_code} - {response.text}")
# 使用 pydub 读取临时文件
audio = AudioSegment.from_file(tmp_file, format="wav")
audio = audio.set_channels(1).set_frame_rate(16000)
opus_datas = self.wav_to_opus_data_audio_raw(audio.raw_data)
yield TTSMessageDTO(u_id=u_id, msg_type=MsgType.TTS_TEXT_RESPONSE, content=opus_datas, tts_finish_text=text,
sentence_type=SentenceType.SENTENCE_START)
# 用完后删除临时文件
try:
os.remove(tmp_file)
except FileNotFoundError:
# 若文件不存在,忽略该异常
pass
@@ -2,7 +2,11 @@ import os
import uuid import uuid
import requests import requests
from datetime import datetime from datetime import datetime
from pydub import AudioSegment
from core.providers.tts.base import TTSProviderBase from core.providers.tts.base import TTSProviderBase
from core.providers.tts.dto.dto import TTSMessageDTO, MsgType, SentenceType
class TTSProvider(TTSProviderBase): class TTSProvider(TTSProviderBase):
@@ -22,7 +26,8 @@ class TTSProvider(TTSProviderBase):
def generate_filename(self, extension=".wav"): def generate_filename(self, extension=".wav"):
return os.path.join(self.output_file, f"tts-{datetime.now().date()}@{uuid.uuid4().hex}{extension}") return os.path.join(self.output_file, f"tts-{datetime.now().date()}@{uuid.uuid4().hex}{extension}")
async def text_to_speak(self, text, output_file): async def text_to_speak(self, u_id, text, is_last_text=False, is_first_text=False):
tmp_file = self.generate_filename()
request_json = { request_json = {
"model": self.model, "model": self.model,
"input": text, "input": text,
@@ -35,5 +40,17 @@ class TTSProvider(TTSProviderBase):
} }
response = requests.request("POST", self.api_url, json=request_json, headers=headers) response = requests.request("POST", self.api_url, json=request_json, headers=headers)
data = response.content data = response.content
file_to_save = open(output_file, "wb") file_to_save = open(tmp_file, "wb")
file_to_save.write(data) file_to_save.write(data)
# 使用 pydub 读取临时文件
audio = AudioSegment.from_file(tmp_file, format="wav")
audio = audio.set_channels(1).set_frame_rate(16000)
opus_datas = self.wav_to_opus_data_audio_raw(audio.raw_data)
yield TTSMessageDTO(u_id=u_id, msg_type=MsgType.TTS_TEXT_RESPONSE, content=opus_datas, tts_finish_text=text,
sentence_type=SentenceType.SENTENCE_START)
# 用完后删除临时文件
try:
os.remove(tmp_file)
except FileNotFoundError:
# 若文件不存在,忽略该异常
pass
@@ -4,7 +4,11 @@ import json
import requests import requests
import shutil import shutil
from datetime import datetime from datetime import datetime
from pydub import AudioSegment
from core.providers.tts.base import TTSProviderBase from core.providers.tts.base import TTSProviderBase
from core.providers.tts.dto.dto import TTSMessageDTO, MsgType, SentenceType
class TTSProvider(TTSProviderBase): class TTSProvider(TTSProviderBase):
@@ -28,7 +32,8 @@ class TTSProvider(TTSProviderBase):
def generate_filename(self, extension=".mp3"): def generate_filename(self, extension=".mp3"):
return os.path.join(self.output_file, f"tts-{datetime.now().date()}@{uuid.uuid4().hex}{extension}") return os.path.join(self.output_file, f"tts-{datetime.now().date()}@{uuid.uuid4().hex}{extension}")
async def text_to_speak(self, text, output_file): async def text_to_speak(self, u_id, text, is_last_text=False, is_first_text=False):
tmp_file = self.generate_filename()
url = f'{self.url}{self.token}' url = f'{self.url}{self.token}'
result = "firefly" result = "firefly"
payload = json.dumps({ payload = json.dumps({
@@ -45,7 +50,7 @@ class TTSProvider(TTSProviderBase):
resp = requests.request("POST", url, data=payload) resp = requests.request("POST", url, data=payload)
if resp.status_code != 200: if resp.status_code != 200:
return None return
resp_json = resp.json() resp_json = resp.json()
try: try:
result = resp_json['url'] + ':' + str( result = resp_json['url'] + ':' + str(
@@ -56,9 +61,21 @@ class TTSProvider(TTSProviderBase):
print("error:", e) print("error:", e)
audio_content = requests.get(result) audio_content = requests.get(result)
with open(output_file, "wb") as f: with open(tmp_file, "wb") as f:
f.write(audio_content.content) f.write(audio_content.content)
return True # 使用 pydub 读取临时文件
audio = AudioSegment.from_file(tmp_file, format="mp3")
audio = audio.set_channels(1).set_frame_rate(16000)
opus_datas = self.wav_to_opus_data_audio_raw(audio.raw_data)
yield TTSMessageDTO(u_id=u_id, msg_type=MsgType.TTS_TEXT_RESPONSE, content=opus_datas, tts_finish_text=text,
sentence_type=SentenceType.SENTENCE_START)
# 用完后删除临时文件
try:
os.remove(tmp_file)
except FileNotFoundError:
# 若文件不存在,忽略该异常
pass
voice_path = resp_json.get("voice_path") voice_path = resp_json.get("voice_path")
des_path = output_file des_path = tmp_file
shutil.move(voice_path, des_path) shutil.move(voice_path, des_path)