Mohssinibra commited on
Commit
d32b773
·
verified ·
1 Parent(s): fc3405f
Files changed (1) hide show
  1. app.py +56 -37
app.py CHANGED
@@ -2,44 +2,61 @@ import gradio as gr
2
  import librosa
3
  import numpy as np
4
  import soundfile as sf
5
- from transformers import pipeline
6
  import os
 
 
 
7
 
8
- print("Chargement du modèle Wav2Vec2...")
 
9
  stt_pipeline = pipeline("automatic-speech-recognition", model="boumehdi/wav2vec2-large-xlsr-moroccan-darija")
10
  print("Modèle chargé avec succès !")
11
 
 
 
 
 
 
12
  def reduce_noise(audio, sr):
13
- """Réduction du bruit avec un filtre passe-haut et suppression des faibles amplitudes"""
14
  audio = librosa.effects.preemphasis(audio)
15
  noise_threshold = np.percentile(np.abs(audio), 10)
16
  audio = np.where(np.abs(audio) > noise_threshold, audio, 0)
17
  return audio
18
 
19
- def segment_audio(audio, sr, segment_length=2.0, silence_threshold=0.01):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  """
21
- Découpe l'audio en segments courts de ~0.5s à 3s, en détectant les silences.
 
22
  """
23
- intervals = librosa.effects.split(audio, top_db=20) # Détecte les zones non silencieuses
24
- segments = []
25
-
26
- for start, end in intervals:
27
- segment = audio[start:end]
28
- duration = (end - start) / sr # Convertir en secondes
29
-
30
- # S'assurer que le segment est dans l'intervalle 0.5s - 3s
31
- if duration < 0.5:
32
- continue # Trop court, on l'ignore
33
- elif duration > 3.0:
34
- num_subsegments = int(duration / segment_length)
35
- subsegment_length = len(segment) // num_subsegments
36
- for i in range(num_subsegments):
37
- subseg = segment[i * subsegment_length: (i + 1) * subsegment_length]
38
- segments.append(subseg)
39
- else:
40
- segments.append(segment)
41
-
42
- return segments
43
 
44
  def process_audio(audio_path):
45
  print(f"Fichier reçu : {audio_path}")
@@ -52,23 +69,25 @@ def process_audio(audio_path):
52
  # Réduction du bruit
53
  audio = reduce_noise(audio, sr)
54
 
55
- # Découpage de l’audio en segments courts
56
- segments = segment_audio(audio, sr, segment_length=2.0)
57
- print(f"Nombre de segments générés : {len(segments)}")
 
 
 
58
 
59
- # Transcrire chaque segment
60
  result = []
61
- for i, segment in enumerate(segments):
62
- temp_filename = f"temp_segment_{i}.wav"
63
- sf.write(temp_filename, np.array(segment), sr)
64
 
65
- # Transcription du segment
66
  transcription = stt_pipeline(temp_filename)
67
  text = transcription["text"].strip()
68
 
69
- # Vérification du contenu
70
  if text:
71
- result.append(f"Segment {i+1}: {text}")
72
 
73
  # Supprimer le fichier temporaire
74
  os.remove(temp_filename)
@@ -88,8 +107,8 @@ iface = gr.Interface(
88
  fn=process_audio,
89
  inputs=gr.Audio(type="filepath"),
90
  outputs="text",
91
- title="Transcription optimisée",
92
- description="Upload un fichier audio pour transcription par segments courts."
93
  )
94
 
95
  iface.launch()
 
2
  import librosa
3
  import numpy as np
4
  import soundfile as sf
 
5
  import os
6
+ from transformers import pipeline
7
+ import torchaudio
8
+ from pyannote.audio import Pipeline
9
 
10
+ # Charger le modèle de reconnaissance vocale
11
+ print("Chargement du modèle Wav2Vec2...")
12
  stt_pipeline = pipeline("automatic-speech-recognition", model="boumehdi/wav2vec2-large-xlsr-moroccan-darija")
13
  print("Modèle chargé avec succès !")
14
 
15
+ # Charger le pipeline de diarisation (détection des speakers)
16
+ print("Chargement du modèle de diarisation...")
17
+ diarization_pipeline = Pipeline.from_pretrained("pyannote/speaker-diarization", use_auth_token="YOUR_HF_TOKEN")
18
+ print("Modèle de diarisation chargé !")
19
+
20
  def reduce_noise(audio, sr):
21
+ """Réduction du bruit pour améliorer la transcription"""
22
  audio = librosa.effects.preemphasis(audio)
23
  noise_threshold = np.percentile(np.abs(audio), 10)
24
  audio = np.where(np.abs(audio) > noise_threshold, audio, 0)
25
  return audio
26
 
27
+ def diarize_audio(audio_path):
28
+ """
29
+ Diarisation de l'audio : détecte qui parle et à quel moment.
30
+ Retourne une liste de (speaker, début, fin).
31
+ """
32
+ diarization = diarization_pipeline(audio_path)
33
+ speaker_segments = {}
34
+
35
+ for turn, _, speaker in diarization.itertracks(yield_label=True):
36
+ start, end = turn.start, turn.end
37
+ if speaker not in speaker_segments:
38
+ speaker_segments[speaker] = []
39
+ speaker_segments[speaker].append((start, end))
40
+
41
+ return speaker_segments
42
+
43
+ def merge_speaker_segments(audio, sr, speaker_segments):
44
  """
45
+ Fusionne les segments d’un même speaker pour améliorer la précision.
46
+ Retourne un dictionnaire {speaker: signal_audio_fusionné}.
47
  """
48
+ merged_audio = {}
49
+
50
+ for speaker, segments in speaker_segments.items():
51
+ combined_audio = np.array([])
52
+ for start, end in segments:
53
+ start_sample = int(start * sr)
54
+ end_sample = int(end * sr)
55
+ combined_audio = np.concatenate((combined_audio, audio[start_sample:end_sample]))
56
+
57
+ merged_audio[speaker] = combined_audio
58
+
59
+ return merged_audio
 
 
 
 
 
 
 
 
60
 
61
  def process_audio(audio_path):
62
  print(f"Fichier reçu : {audio_path}")
 
69
  # Réduction du bruit
70
  audio = reduce_noise(audio, sr)
71
 
72
+ # Étape de diarisation : détection des speakers
73
+ speaker_segments = diarize_audio(audio_path)
74
+ print(f"Speakers détectés : {list(speaker_segments.keys())}")
75
+
76
+ # Fusionner les segments de chaque speaker
77
+ merged_audio = merge_speaker_segments(audio, sr, speaker_segments)
78
 
79
+ # Transcrire chaque speaker
80
  result = []
81
+ for speaker, audio_data in merged_audio.items():
82
+ temp_filename = f"temp_{speaker}.wav"
83
+ sf.write(temp_filename, np.array(audio_data), sr)
84
 
85
+ # Transcription du segment fusionné
86
  transcription = stt_pipeline(temp_filename)
87
  text = transcription["text"].strip()
88
 
 
89
  if text:
90
+ result.append(f"{speaker}: {text}")
91
 
92
  # Supprimer le fichier temporaire
93
  os.remove(temp_filename)
 
107
  fn=process_audio,
108
  inputs=gr.Audio(type="filepath"),
109
  outputs="text",
110
+ title="Transcription avec Diarisation",
111
+ description="Upload un fichier audio pour une transcription avec détection des speakers."
112
  )
113
 
114
  iface.launch()