import spaces import os import sys import time import json import numpy as np import gradio as gr import soundfile as sf from datetime import datetime sys.path.append("neutts-air") from neuttsair.neutts import NeuTTSAir # === Đường dẫn cơ bản === BASE_PATH = os.getcwd() SAMPLES_PATH = os.path.join(BASE_PATH, "neutts-air", "samples") HISTORY_PATH = os.path.join(BASE_PATH, "history") os.makedirs(HISTORY_PATH, exist_ok=True) DEFAULT_REF_TEXT = "So I'm live on radio..." DEFAULT_REF_PATH = os.path.join(SAMPLES_PATH, "dave.wav") DEFAULT_GEN_TEXT = "My name is Dave, and um, I'm from London." # === Khởi tạo NeuTTS-Air ở CPU === tts = NeuTTSAir( backbone_repo="neuphonic/neutts-air", backbone_device="cpu", codec_repo="neuphonic/neucodec", codec_device="cpu" ) # === Hàm xử lý chính === def infer(ref_text, ref_audio_path, gen_text): gr.Info("Bắt đầu xử lý (CPU mode)...") # Mã hóa reference ref_codes = tts.encode_reference(ref_audio_path) # Sinh âm thanh mới wav = tts.infer(gen_text, ref_codes, ref_text) sr = 24000 # === Lưu vào history === timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") fname = f"tts_{timestamp}.wav" fpath = os.path.join(HISTORY_PATH, fname) sf.write(fpath, wav, sr) # Lưu metadata meta = { "timestamp": timestamp, "ref_text": ref_text, "gen_text": gen_text, "ref_audio": os.path.basename(ref_audio_path), "output_audio": fname, } with open(os.path.join(HISTORY_PATH, f"{timestamp}.json"), "w", encoding="utf-8") as f: json.dump(meta, f, ensure_ascii=False, indent=2) gr.Info(f"Đã lưu file: {fpath}") return sr, wav, f"Lưu thành công: {fname}" # === Hàm tải lại lịch sử === def load_history(): items = [] for file in sorted(os.listdir(HISTORY_PATH)): if file.endswith(".json"): with open(os.path.join(HISTORY_PATH, file), "r", encoding="utf-8") as f: data = json.load(f) wav_path = os.path.join(HISTORY_PATH, data["output_audio"]) if os.path.exists(wav_path): items.append( (data["timestamp"], data["gen_text"], wav_path) ) if not items: return "Chưa có lịch sử nào." html = "

Lịch sử đã tạo:

" return html # === Giao diện Gradio === with gr.Blocks(title="NeuTTS-Air☁️ CPU Mode + Auto History") as demo: gr.Markdown("## 🌀 NeuTTS-Air (CPU Mode) — Lưu tự động & tải lại lịch sử") with gr.Row(): ref_text = gr.Textbox(label="Reference Text", value=DEFAULT_REF_TEXT) ref_audio = gr.Audio(type="filepath", label="Reference Audio", value=DEFAULT_REF_PATH) gen_text = gr.Textbox(label="Text to Generate", value=DEFAULT_GEN_TEXT) output_audio = gr.Audio(type="numpy", label="Generated Speech") info_text = gr.Textbox(label="Kết quả / Trạng thái") gen_btn = gr.Button("🎤 Generate & Save") gen_btn.click(infer, inputs=[ref_text, ref_audio, gen_text], outputs=[output_audio, info_text, info_text]) hist_html = gr.HTML() reload_btn = gr.Button("🔄 Tải lại lịch sử") reload_btn.click(load_history, outputs=hist_html) # Tải sẵn lịch sử khi mở demo.load(load_history, outputs=hist_html) if __name__ == "__main__": print("Chạy nền NeuTTS-Air CPU Mode (có lưu lịch sử)...") demo.launch(allowed_paths=[SAMPLES_PATH, HISTORY_PATH], inbrowser=True)