# Fichier: /data/generate_audio.py (VERSION ANTI-BRUIT & FILTRAGE) import sys import os import json import wave import torch import re # FIX SÉCURITÉ PYTORCH original_load = torch.load def patched_load(*args, **kwargs): kwargs['weights_only'] = False return original_load(*args, **kwargs) torch.load = patched_load from TTS.api import TTS def clean_text_pro(text): """Nettoyage chirurgical pour éviter les bruits de calcul""" # 1. Remplacer les caractères problématiques vus dans vos logs # Le modèle n'aime pas les accents combinés, on simplifie text = text.replace('̃', 'n') # Fix pour le "on" nasal text = text.replace('œ', 'oe') # 2. Supprimer les caractères spéciaux inutiles text = re.sub(r'[#@*<>]', '', text) # 3. Normaliser les espaces et la ponctuation text = text.replace('...', '…') # Utilise le vrai caractère de pause # 4. Ajouter un micro-espace au début et à la fin pour éviter les "clics" d'attaque return " " + text.strip() + " " try: if len(sys.argv) < 3: sys.exit(1) input_text = sys.argv[1] output_file = sys.argv[2] processed_text = clean_text_pro(input_text) # Initialisation tts = TTS(model_name="tts_models/fr/mai/tacotron2-DDC", progress_bar=False, gpu=False) # Génération tts.tts_to_file(text=processed_text, file_path=output_file) # --- POST-PROCESS OPTIONNEL (Si ffmpeg est nécessaire pour lisser) --- # On peut forcer un petit fondu (fade-in/fade-out) pour supprimer les clics clean_output = output_file.replace('.wav', '_clean.wav') os.system(f"ffmpeg -y -i {output_file} -af 'afade=t=in:ss=0:d=0.05,afade=t=out:st=13.5:d=0.1' {clean_output} > /dev/null 2>&1") # On remet le fichier propre à la place de l'original if os.path.exists(clean_output): os.replace(clean_output, output_file) with wave.open(output_file, 'rb') as wf: duration = wf.getnframes() / float(wf.getframerate()) print(json.dumps({"status": "success", "audioPath": output_file, "duration": round(duration, 2)})) except Exception as e: print(json.dumps({"status": "error", "message": str(e)}), file=sys.stderr) sys.exit(1)