Spaces:
Sleeping
Sleeping
from fastapi import FastAPI, UploadFile, File, HTTPException | |
from fastapi.responses import FileResponse | |
from pydantic import BaseModel | |
from typing import List | |
import tempfile | |
from pathlib import Path | |
import os | |
import torch | |
from .voice_clone import VoiceCloneSystem | |
# 创建临时目录 | |
TEMP_DIR = Path("temp") | |
TEMP_DIR.mkdir(exist_ok=True) | |
# 创建应用 | |
app = FastAPI( | |
title="语音克隆 API", | |
description="将输入文本转换为目标说话人的语音", | |
version="1.0.0" | |
) | |
# 初始化语音克隆系统 | |
system = VoiceCloneSystem(device="cpu") | |
class TextInput(BaseModel): | |
text: str | |
async def clone_voice( | |
text: TextInput, | |
reference_audio: List[UploadFile] = File(...) | |
): | |
""" | |
克隆语音接口 | |
Args: | |
text: 要转换的文本 | |
reference_audio: 参考音频文件列表 | |
Returns: | |
生成的音频文件 | |
""" | |
try: | |
# 保存上传的音频文件 | |
audio_paths = [] | |
for audio in reference_audio: | |
# 创建临时文件 | |
temp_path = TEMP_DIR / f"{audio.filename}" | |
# 保存音频 | |
with open(temp_path, "wb") as f: | |
content = await audio.read() | |
f.write(content) | |
audio_paths.append(temp_path) | |
# 生成语音 | |
speech = system.clone_voice(text.text, audio_paths) | |
# 保存生成的音频 | |
output_path = TEMP_DIR / "output.wav" | |
system.save_audio(speech, output_path) | |
# 返回音频文件 | |
return FileResponse( | |
output_path, | |
media_type="audio/wav", | |
filename="cloned_voice.wav" | |
) | |
except Exception as e: | |
raise HTTPException(status_code=500, detail=str(e)) | |
finally: | |
# 清理临时文件 | |
for path in audio_paths: | |
if os.path.exists(path): | |
os.remove(path) | |
async def root(): | |
"""API 根路径""" | |
return { | |
"message": "欢迎使用语音克隆 API", | |
"usage": "POST /clone_voice 来克隆语音" | |
} |