Webber1979 commited on
Commit
4250c19
·
verified ·
1 Parent(s): c044dd5

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +70 -41
app.py CHANGED
@@ -1,39 +1,48 @@
1
  import os
2
- import subprocess
3
  import sys
4
- from fastapi import FastAPI, File, UploadFile, Form
5
- from fastapi.middleware.cors import CORSMiddleware
6
- from fastapi.responses import FileResponse
7
- import uvicorn
8
  import soundfile as sf
9
- import numpy as np
 
 
 
10
 
11
- # 1. Автоматически скачиваем MOSS-TTS-Nano, если его нет
12
- if not os.path.exists("MOSS-TTS-Nano"):
13
- print("Клонируем репозиторий MOSS-TTS-Nano...")
 
14
  subprocess.run(["git", "clone", "https://github.com/OpenMOSS/MOSS-TTS-Nano.git"])
15
 
16
- # Добавляем папку в пути Python, чтобы можно было импортировать их код
17
- sys.path.append("MOSS-TTS-Nano")
18
 
19
- # ЗДЕСЬ НУЖНО ИМПОРТИРОВАТЬ ФУНКЦИИ ИЗ MOSS-TTS
20
- # Например: from inference import synthesize, clone_voice
21
- # (Посмотри в их документации, как точно называется функция генерации)
22
 
23
  app = FastAPI()
24
 
25
- # Разрешаем нашему React-сайту делать запросы к этому API
26
  app.add_middleware(
27
  CORSMiddleware,
28
- allow_origins=["*"],
29
  allow_credentials=True,
30
  allow_methods=["*"],
31
  allow_headers=["*"],
32
  )
33
 
 
 
 
 
 
 
 
 
 
34
  @app.get("/")
35
  async def root():
36
- return {"message": "Бэкенд MOSS-TTS-Nano успешно работает! Готов принимать запросы от Reactнтерфейса."}
37
 
38
  @app.post("/api/predict")
39
  async def predict(
@@ -43,34 +52,54 @@ async def predict(
43
  speaker: str = Form("default"),
44
  reference_audio: UploadFile = File(None)
45
  ):
46
- output_filename = "output.wav"
47
-
48
- if mode == "clone" and reference_audio:
49
- # Сохраняем загруженный голос для клонирования
50
- ref_path = "temp_ref.wav"
51
- with open(ref_path, "wb") as f:
52
- f.write(await reference_audio.read())
 
 
 
53
 
54
- # === ВЫЗОВ MOSS-TTS ДЛЯ КЛОНИРОВАНИЯ ===
55
- # audio_data, sample_rate = clone_voice(text, ref_path, speed)
56
 
57
- # Заглушка (пока не подключишь реальную функцию)
58
- sample_rate = 24000
59
- audio_data = np.zeros(sample_rate)
60
- sf.write(output_filename, audio_data, sample_rate)
 
 
 
61
 
62
- else:
63
- # === ВЫЗОВ СТАНДАРТНОГО MOSS-TTS ===
64
- # audio_data, sample_rate = synthesize(text, speaker, speed)
65
 
66
- # Заглушка (пока не подключишь реальну�� функцию)
67
- sample_rate = 24000
68
- audio_data = np.zeros(sample_rate)
69
- sf.write(output_filename, audio_data, sample_rate)
70
-
71
- # Отправляем готовый WAV файл обратно на фронтенд
72
- return FileResponse(output_filename, media_type="audio/wav")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
 
74
- # Запуск сервера
75
  if __name__ == "__main__":
 
76
  uvicorn.run(app, host="0.0.0.0", port=7860)
 
1
  import os
 
2
  import sys
3
+ import subprocess
4
+ import tempfile
 
 
5
  import soundfile as sf
6
+ import librosa
7
+ from fastapi import FastAPI, File, Form, UploadFile
8
+ from fastapi.responses import FileResponse
9
+ from fastapi.middleware.cors import CORSMiddleware
10
 
11
+ # 1. АВТОМАТИЧЕСКОЕ СКАЧИВАНИЕ ОРИГИНАЛЬНОГО РЕПОЗИТОРИЯ
12
+ REPO_DIR = "MOSS-TTS-Nano"
13
+ if not os.path.exists(REPO_DIR):
14
+ print("Клонируем оригинальный репозиторий MOSS-TTS-Nano...")
15
  subprocess.run(["git", "clone", "https://github.com/OpenMOSS/MOSS-TTS-Nano.git"])
16
 
17
+ # Добавляем скачанную папку в пути Python, чтобы импорты работали
18
+ sys.path.append(REPO_DIR)
19
 
20
+ # 2. ИМПОРТИРУЕМ ОРИГИНАЛЬНЫЙ ДВИЖОК
21
+ from moss_tts_nano_runtime import NanoTTSService
 
22
 
23
  app = FastAPI()
24
 
25
+ # Разрешаем CORS для твоего React-интерфейса
26
  app.add_middleware(
27
  CORSMiddleware,
28
+ allow_origins=["*"],
29
  allow_credentials=True,
30
  allow_methods=["*"],
31
  allow_headers=["*"],
32
  )
33
 
34
+ # 3. ИНИЦИАЛИЗАЦИЯ МОДЕЛИ (скачает веса при первом запуске)
35
+ print("Загрузка весов MOSS-TTS-Nano (это может занять пару минут)...")
36
+ tts_service = NanoTTSService(
37
+ checkpoint_path="OpenMOSS-Team/MOSS-TTS-Nano",
38
+ audio_tokenizer_path="OpenMOSS-Team/MOSS-Audio-Tokenizer-Nano",
39
+ device="auto" # Автоматически включит GPU, если он есть
40
+ )
41
+ print("Модель успешно загружена и готова к работе!")
42
+
43
  @app.get("/")
44
  async def root():
45
+ return {"message": "Бэкенд MOSS-TTS-Nano работает! Жду запросов от React UI на /api/predict"}
46
 
47
  @app.post("/api/predict")
48
  async def predict(
 
52
  speaker: str = Form("default"),
53
  reference_audio: UploadFile = File(None)
54
  ):
55
+ prompt_audio_path = None
56
+
57
+ try:
58
+ # Если загружен файл для клонирования голоса
59
+ if mode == "clone" and reference_audio is not None:
60
+ temp_audio = tempfile.NamedTemporaryFile(delete=False, suffix=".wav")
61
+ content = await reference_audio.read()
62
+ temp_audio.write(content)
63
+ temp_audio.close()
64
+ prompt_audio_path = temp_audio.name
65
 
66
+ # Выбор стандартного голоса
67
+ voice_preset = "Junhao" # Дефолтный голос в MOSS
68
 
69
+ # 4. ЗАПУСК ОРИГИНАЛЬНОГО СИНТЕЗА
70
+ result = tts_service.synthesize(
71
+ text=text,
72
+ voice=voice_preset if not prompt_audio_path else None,
73
+ prompt_audio_path=prompt_audio_path,
74
+ mode="voice_clone", # В MOSS это универсальный режим
75
+ )
76
 
77
+ audio_data = result['audio']
78
+ sample_rate = result['sample_rate']
 
79
 
80
+ # 5. ОБРАБОТКА СКОРОСТИ (если ползунок скорости изменен)
81
+ if speed != 1.0:
82
+ audio_data = librosa.effects.time_stretch(audio_data, rate=speed)
83
+
84
+ # 6. СОХРАНЕНИЕ И ОТПРАВКА РЕЗУЛЬТАТА
85
+ output_file = tempfile.NamedTemporaryFile(delete=False, suffix=".wav")
86
+ sf.write(output_file.name, audio_data, sample_rate)
87
+
88
+ return FileResponse(
89
+ output_file.name,
90
+ media_type="audio/wav",
91
+ filename="output.wav"
92
+ )
93
+
94
+ except Exception as e:
95
+ import traceback
96
+ traceback.print_exc()
97
+ return {"error": str(e)}
98
+ finally:
99
+ # Убираем за собой временные файлы
100
+ if prompt_audio_path and os.path.exists(prompt_audio_path):
101
+ os.remove(prompt_audio_path)
102
 
 
103
  if __name__ == "__main__":
104
+ import uvicorn
105
  uvicorn.run(app, host="0.0.0.0", port=7860)