Mohssinibra's picture
Update app.py
33aca12 verified
raw
history blame
5 kB
import gradio as gr
import librosa
import numpy as np
import soundfile as sf
import os
from transformers import pipeline
import torchaudio
from pyannote.audio import Pipeline
hf_token = os.getenv("diarizationToken")
# Charger le modèle de reconnaissance vocale
print("Chargement du modèle Wav2Vec2...")
stt_pipeline = pipeline("automatic-speech-recognition", model="boumehdi/wav2vec2-large-xlsr-moroccan-darija")
print("Modèle chargé avec succès !")
# Charger le pipeline de diarisation (détection des speakers)
print("Chargement du modèle de diarisation...")
#diarization_pipeline = Pipeline.from_pretrained("pyannote/speaker-diarization", use_auth_token=hf_token)
diarization_pipeline = Pipeline.from_pretrained("Revai/reverb-diarization-v2", use_auth_token=hf_token)
print("Modèle de diarisation chargé !")
def reduce_noise(audio, sr):
"""Réduction du bruit pour améliorer la transcription"""
audio = librosa.effects.preemphasis(audio)
noise_threshold = np.percentile(np.abs(audio), 10)
audio = np.where(np.abs(audio) > noise_threshold, audio, 0)
return audio
def calculate_min_silence_duration(audio_path):
# Charger l'audio pour obtenir sa durée
audio, sr = librosa.load(audio_path, sr=None)
total_duration = len(audio) / sr
dynamic_min_silence = total_duration * 0.05 # 5% de la durée totale de l'audio
return dynamic_min_silence
def diarize_audio(audio_path):
"""
Diarisation de l'audio : détecte qui parle et à quel moment.
Retourne une liste de (speaker, début, fin).
"""
# Calculer la durée minimale de silence en fonction de la durée de l'audio
min_silence_duration = calculate_min_silence_duration(audio_path)
print(f"Durée minimale de silence ajustée à : {min_silence_duration} secondes")
diarization = diarization_pipeline(audio_path)
speaker_segments = {}
previous_speaker = None
last_end = 0
for turn, _, speaker in diarization.itertracks(yield_label=True):
start, end = turn.start, turn.end
# Si le silence entre deux segments est trop court, on fusionne avec le speaker précédent
if previous_speaker is not None and start - last_end < min_silence_duration:
speaker_segments[previous_speaker].append((start, end))
else:
# Nouveau speaker ou silence long : on l'ajoute comme un segment distinct
if speaker not in speaker_segments:
speaker_segments[speaker] = []
speaker_segments[speaker].append((start, end))
previous_speaker = speaker
last_end = end
return speaker_segments
def merge_speaker_segments(audio, sr, speaker_segments):
"""
Fusionne les segments d’un même speaker pour améliorer la précision.
Retourne un dictionnaire {speaker: signal_audio_fusionné}.
"""
merged_audio = {}
for speaker, segments in speaker_segments.items():
combined_audio = np.array([])
for start, end in segments:
start_sample = int(start * sr)
end_sample = int(end * sr)
combined_audio = np.concatenate((combined_audio, audio[start_sample:end_sample]))
merged_audio[speaker] = combined_audio
return merged_audio
def process_audio(audio_path):
print(f"Fichier reçu : {audio_path}")
try:
# Charger l'audio
audio, sr = librosa.load(audio_path, sr=None)
print(f"Audio chargé avec {len(audio)} échantillons à {sr} Hz")
# Réduction du bruit
audio = reduce_noise(audio, sr)
# Étape de diarisation : détection des speakers
speaker_segments = diarize_audio(audio_path)
print(f"Speakers détectés : {list(speaker_segments.keys())}")
# Fusionner les segments de chaque speaker
merged_audio = merge_speaker_segments(audio, sr, speaker_segments)
# Transcrire chaque speaker
result = []
for speaker, audio_data in merged_audio.items():
temp_filename = f"temp_{speaker}.wav"
sf.write(temp_filename, np.array(audio_data), sr)
# Transcription du segment fusionné
transcription = stt_pipeline(temp_filename)
text = transcription["text"].strip()
if text:
result.append(f"{speaker}: {text}")
# Supprimer le fichier temporaire
os.remove(temp_filename)
if not result:
return "Aucune parole détectée."
return "\n".join(result)
except Exception as e:
print(f"Erreur : {e}")
return f"Une erreur s'est produite. + {e}"
# Interface Gradio
print("Démarrage de Gradio...")
iface = gr.Interface(
fn=process_audio,
inputs=gr.Audio(type="filepath"),
outputs="text",
title="Transcription avec Diarisation",
description="Upload un fichier audio pour une transcription avec détection des speakers."
)
iface.launch()
print("Interface lancée avec succès !")