MEscriva's picture
Upload app.py with huggingface_hub
1451438 verified
import gradio as gr
import os
import tempfile
from pathlib import Path
import sys
# Importer le script de diarisation (dans le même répertoire)
from diarization_pyannote_demo import run_pyannote_diarization, write_rttm, write_json
def diarize_audio(audio_file, model_name, num_speakers, min_speakers, max_speakers, use_exclusive):
"""Interface Gradio pour la diarisation pyannote."""
if audio_file is None:
return None, None, "❌ Veuillez uploader un fichier audio"
try:
# Gérer le chemin du fichier audio (Gradio peut retourner un tuple ou un string)
if isinstance(audio_file, tuple):
# Gradio Audio avec type="filepath" retourne (sample_rate, filepath)
audio_path = audio_file[1] if len(audio_file) > 1 else audio_file[0]
elif isinstance(audio_file, str):
# C'est déjà un chemin de fichier
audio_path = audio_file
elif hasattr(audio_file, 'name'):
# Objet avec attribut name
audio_path = audio_file.name
else:
# Fallback
audio_path = str(audio_file)
if not os.path.exists(audio_path):
return None, None, f"❌ Fichier audio introuvable: {audio_path}"
# Créer un répertoire temporaire pour les résultats
with tempfile.TemporaryDirectory() as tmpdir:
# Exécuter la diarisation
result = run_pyannote_diarization(
audio_path,
output_dir=tmpdir,
model_name=model_name,
num_speakers=num_speakers if num_speakers > 0 else None,
min_speakers=min_speakers if min_speakers > 0 else None,
max_speakers=max_speakers if max_speakers > 0 else None,
use_exclusive=use_exclusive,
show_progress=False
)
# Générer les fichiers de sortie
audio_name = Path(audio_path).stem
rttm_path = os.path.join(tmpdir, f"{audio_name}.rttm")
json_path = os.path.join(tmpdir, f"{audio_name}.json")
write_rttm(result["segments"], rttm_path, audio_name)
write_json(result["segments"], json_path)
# Créer un résumé
summary = f"""
# Résultats de diarisation
**Fichier:** {Path(audio_path).name}
**Modèle:** {model_name}
**Locuteurs détectés:** {result['num_speakers']}
**Segments:** {len(result['segments'])}
**Durée totale:** {result.get('duration', 0):.2f} secondes
## Statistiques par locuteur
"""
from collections import defaultdict
speaker_stats = defaultdict(lambda: {"total_duration": 0.0, "num_segments": 0})
for seg in result["segments"]:
speaker = seg["speaker"]
duration = seg["end"] - seg["start"]
speaker_stats[speaker]["total_duration"] += duration
speaker_stats[speaker]["num_segments"] += 1
for speaker, stats in sorted(speaker_stats.items()):
avg_duration = stats["total_duration"] / stats["num_segments"] if stats["num_segments"] > 0 else 0
summary += f"\n- **{speaker}**: {stats['num_segments']} segments, {stats['total_duration']:.2f}s total, {avg_duration:.2f}s moyenne/segment"
# Retourner les fichiers (Gradio gère automatiquement les fichiers temporaires)
return rttm_path, json_path, summary
except Exception as e:
import traceback
error_details = traceback.format_exc()
error_msg = f"""❌ **Erreur lors de la diarisation**
**Message:** {str(e)}
**Détails techniques:**
```
{error_details}
```
**Solutions possibles:**
- Vérifiez que le fichier audio est valide
- Assurez-vous que le token HF_TOKEN est configuré dans les secrets de la Space
- Réessayez avec un fichier audio plus court
"""
return None, None, error_msg
# Interface Gradio
with gr.Blocks(title="Gilbert - Diarisation pyannote") as demo:
gr.Markdown("""
# 🎤 Gilbert - Diarisation pyannote
Interface pour la diarisation de locuteurs avec pyannote.audio
**Instructions:**
1. Uploadez un fichier audio (WAV, MP3, M4A)
2. Configurez les paramètres (optionnel)
3. Cliquez sur "Diariser"
4. Téléchargez les résultats (RTTM et JSON)
""")
with gr.Row():
with gr.Column():
audio_input = gr.Audio(
label="Fichier audio",
type="filepath"
)
model_name = gr.Dropdown(
choices=[
"pyannote/speaker-diarization-3.1",
"pyannote/speaker-diarization-community-1",
],
value="pyannote/speaker-diarization-3.1",
label="Modèle pyannote"
)
with gr.Row():
num_speakers = gr.Number(
label="Nombre exact de locuteurs",
value=0,
minimum=0,
info="0 = auto-détection"
)
min_speakers = gr.Number(
label="Min locuteurs",
value=0,
minimum=0,
info="0 = pas de limite"
)
max_speakers = gr.Number(
label="Max locuteurs",
value=0,
minimum=0,
info="0 = pas de limite"
)
use_exclusive = gr.Checkbox(
label="Exclusive speaker diarization",
value=False,
info="Simplifie la réconciliation avec transcription"
)
diarize_btn = gr.Button("🎯 Diariser", variant="primary")
with gr.Column():
summary_output = gr.Markdown(label="Résumé")
rttm_output = gr.File(label="Fichier RTTM", type="filepath")
json_output = gr.File(label="Fichier JSON", type="filepath")
diarize_btn.click(
fn=diarize_audio,
inputs=[audio_input, model_name, num_speakers, min_speakers, max_speakers, use_exclusive],
outputs=[rttm_output, json_output, summary_output]
)
gr.Markdown("""
---
**Note:** Vous devez avoir un token Hugging Face configuré avec accès aux modèles pyannote.
Configurez-le avec: `export HF_TOKEN="votre_token"`
""")
if __name__ == "__main__":
demo.launch()