LivanArzuaga commited on
Commit
b11067c
·
verified ·
1 Parent(s): 22060ec

Update utils_hf.py

Browse files
Files changed (1) hide show
  1. utils_hf.py +273 -286
utils_hf.py CHANGED
@@ -1,287 +1,274 @@
1
- # import numpy as np
2
- # import soundfile as sf
3
- # import torchaudio
4
-
5
- import os
6
- import yt_dlp
7
- import streamlit as st
8
- import torch
9
- import whisper
10
- from pyannote.audio import Pipeline
11
- from pyannote.audio.pipelines.utils.hook import ProgressHook
12
- from moviepy.editor import AudioFileClip
13
- from transformers import pipeline
14
- from openai import Client
15
- from dotenv import load_dotenv
16
-
17
-
18
- load_dotenv()
19
-
20
- hf_token = os.environ.get("HF_DIARIZATION_TOKEN")
21
- api_key = os.environ.get("OPENAI_API_KEY")
22
-
23
- client = Client(api_key=api_key)
24
-
25
- device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
26
- st.info(f"Usando dispositivo: {device}")
27
-
28
- pyannote_pipeline = Pipeline.from_pretrained(
29
- "pyannote/speaker-diarization-3.1",
30
- use_auth_token=hf_token,
31
- )
32
-
33
- if torch.cuda.is_available():
34
- pyannote_pipeline.to(torch.device("cuda"))
35
-
36
- sumamry_pipeline = pipeline(
37
- "summarization",
38
- model="t5-base",
39
- device=device,
40
- )
41
-
42
- whisper_model = whisper.load_model("base")
43
-
44
-
45
- def transcribir_segmentos(diarization_segments, audio_path):
46
- diarization_text = ""
47
- audio_duration = get_audio_duration(audio_path)
48
- path = 'diarization_transcription.txt'
49
- if os.path.exists(path):
50
- os.remove(path)
51
- st.success("Borrado archivo diarization_transcription.txt anterior")
52
-
53
- progress_bar = st.progress(0)
54
- total_segments = len(diarization_segments)
55
-
56
- with open("diarization_transcription.txt", "w", encoding="utf-8") as file:
57
- for i, (start_time, end_time, speaker) in enumerate(diarization_segments):
58
- if start_time < 0 or end_time > audio_duration:
59
- st.error(f"Segmento fuera de los límites del audio: {start_time} - {end_time}")
60
- continue
61
- if end_time - start_time < 0.5:
62
- continue
63
-
64
- segment_audio_path = f"segment_{start_time}_{end_time}.wav"
65
- extract_audio_segment(audio_path, segment_audio_path, start_time, end_time)
66
-
67
- transcript = transcribe_audio_whisper_lib(segment_audio_path) # Cambiar aca el trancript
68
- if transcript:
69
- diarization_text += f"{speaker}: {transcript}\n"
70
- file.write(f"{speaker}: {transcript}\n")
71
- os.remove(segment_audio_path)
72
-
73
- progress = (i + 1) / total_segments
74
- progress_bar.progress(progress)
75
-
76
- return diarization_text
77
-
78
-
79
- def process_transcripts(diarization_text, speakers):
80
- speaker_transcripts = {speaker: [] for speaker in speakers}
81
- for line in diarization_text.split('\n'):
82
- if line:
83
- speaker = line.split(':')[0].split()[-1]
84
- transcript = line.split(': ')[1]
85
- speaker_transcripts[speaker].append(transcript)
86
- return speaker_transcripts
87
-
88
-
89
- def summarize_speaker_transcripts(speaker_transcripts):
90
- summaries = {}
91
- for speaker, transcripts in speaker_transcripts.items():
92
- full_text = ' '.join(transcripts)
93
- max_tokens = 1024 # Ajusta según el modelo y tus necesidades
94
- if len(full_text) > max_tokens:
95
- full_text = full_text[:max_tokens]
96
-
97
- summary = sumamry_pipeline(full_text, max_length=150, min_length=30, do_sample=False)[0]['summary_text']
98
- summaries[speaker] = summary
99
- return summaries
100
-
101
-
102
- def diarize_full_audio(audio_path):
103
- try:
104
-
105
- audio_duration = get_audio_duration(audio_path)
106
- diarization_segments = []
107
- diarization_text = ""
108
- speakers = set()
109
-
110
- st.info(f"Procesando el audio completo de {audio_duration} segundos...")
111
-
112
- with StreamlitProgressHook() as hook:
113
- diarization = pyannote_pipeline({
114
- 'audio': audio_path,
115
- }, hook=hook)
116
-
117
- for segment, _, speaker in diarization.itertracks(yield_label=True):
118
- diarization_segments.append((segment.start, segment.end, speaker))
119
- diarization_text += f"{segment.start:.2f} - {segment.end:.2f}: {speaker}\n"
120
- speakers.add(speaker)
121
-
122
- return diarization_segments, diarization_text, speakers
123
- except Exception as e:
124
- st.error(f"Error al realizar la diarización del audio entero: {e}")
125
- return None, None, 0
126
-
127
-
128
-
129
-
130
- def extract_audio_segment(input_audio_path, output_audio_path, start_time, end_time):
131
- try:
132
- audio = AudioFileClip(input_audio_path)
133
- audio_subclip = audio.subclip(start_time, end_time)
134
- audio_subclip.write_audiofile(output_audio_path)
135
- except Exception as e:
136
- st.error(f"Error al extraer el segmento de audio: {e}")
137
- finally:
138
- if 'audio' in locals():
139
- audio.close()
140
- if 'audio_subclip' in locals():
141
- audio_subclip.close()
142
-
143
-
144
- def transcribe_audio_whisper_lib(audio_path):
145
- try:
146
- with open(audio_path, "rb") as audio_file:
147
- transcript = whisper_model.transcribe(audio_path)
148
- return transcript["text"]
149
- except Exception as e:
150
- st.error(f"Error al transcribir el audio: {e}")
151
- st.stop()
152
-
153
-
154
- def transcribe_audio_openai(audio_path):
155
- try:
156
- with open(audio_path, "rb") as audio_file:
157
- transcript = client.audio.transcriptions.create(
158
- model="whisper-1",
159
- file=audio_file,
160
- response_format="json"
161
- )
162
- return transcript.text
163
- except Exception as e:
164
- st.error(f"Error al transcribir el audio: {e}")
165
- st.stop()
166
-
167
- def download_youtube_audio(url, progress_bar):
168
- # No incluyas la extensión '.wav' en el 'outtmpl'
169
- output_path = os.path.join('temp_audio')
170
- if os.path.exists(output_path + '.wav'):
171
- os.remove(output_path + '.wav')
172
- st.success("Borrado archivo temp_audio.wav anterior")
173
-
174
- ydl_opts = {
175
- 'format': 'bestaudio/best',
176
- 'postprocessors': [{
177
- 'key': 'FFmpegExtractAudio',
178
- 'preferredcodec': 'wav',
179
- 'preferredquality': '192',
180
- }],
181
- 'outtmpl': output_path,
182
- 'progress_hooks': [lambda d: update_progress(d, progress_bar)], # Usa la función de progreso
183
- 'noplaylist': True,
184
- 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
185
- 'Chrome/58.0.3029.110 Safari/537.3',
186
- 'cookiefile': 'cookies.txt', # Aquí incluyes el archivo de cookies
187
- }
188
-
189
- try:
190
- with yt_dlp.YoutubeDL(ydl_opts) as ydl:
191
- ydl.download([url])
192
- progress_bar.progress(1.0) # Asegúrate de que la barra de progreso llegue al 100% cuando termine
193
-
194
- # Verifica si el archivo existe con la extensión .wav
195
- final_output_path = output_path + '.wav'
196
- st.write("Checking if file exists:", os.path.exists(final_output_path))
197
- return final_output_path if os.path.exists(final_output_path) else None
198
- except yt_dlp.utils.DownloadError as e:
199
- st.error(f"Ocurrió un error al descargar el audio: {e}")
200
- return None
201
- except Exception as e:
202
- st.error(f"Ocurrió un error: {e}")
203
- return None
204
-
205
-
206
- def get_audio_duration(audio_path):
207
- try:
208
- audio = AudioFileClip(audio_path)
209
- return audio.duration
210
- except Exception as e:
211
- st.error(f"Error al obtener la duración del audio: {e}")
212
- return 0
213
-
214
- def update_progress(d, progress_bar):
215
- if d['status'] == 'downloading':
216
- total_bytes = d.get('total_bytes', None)
217
- downloaded_bytes = d.get('downloaded_bytes', 0)
218
-
219
- if total_bytes:
220
- progress = downloaded_bytes / total_bytes
221
- progress_bar.progress(progress) # Actualiza la barra de progreso con el porcentaje descargado
222
- else:
223
- progress_bar.progress(0.1) # Valor predeterminado si no se conoce el tamaño total
224
-
225
- elif d['status'] == 'finished':
226
- progress_bar.progress(0.9) # 90% cuando la descarga termina
227
- elif d['status'] == 'postprocessing':
228
- progress_bar.progress(0.95) # 95% durante el procesamiento de audio
229
-
230
- class StreamlitProgressHook(ProgressHook):
231
- def __init__(self, transient: bool = False):
232
- super().__init__(transient)
233
- self.progress_text = st.empty()
234
-
235
- def __call__(self, step_name, step_artifact, file=None, total=None, completed=None):
236
- super().__call__(step_name, step_artifact, file, total, completed)
237
- if total is not None and completed is not None:
238
- progress_message = f"{step_name:<20} {'━' * int(30 * (completed / total))} {completed / total:.0%}"
239
- else:
240
- progress_message = f"{step_name:<20} Progress data unavailable"
241
- self.progress_text.text(progress_message)
242
-
243
-
244
- # def diarize_in_segments(audio_path, segment_duration=300):
245
- # try:
246
- # audio_duration = get_audio_duration(audio_path)
247
- # diarization_segments = []
248
- # diarization_text = ""
249
- # speakers = set()
250
- #
251
- # # Procesar cada segmento por separado
252
- # for start_time in range(0, int(audio_duration), segment_duration):
253
- # end_time = min(start_time + segment_duration, audio_duration)
254
- # st.info(f"Procesando segmento desde {start_time} hasta {end_time} segundos...")
255
- #
256
- # with StreamlitProgressHook() as hook:
257
- # diarization = pyannote_pipeline({
258
- # 'audio': audio_path,
259
- # 'start': start_time,
260
- # 'end': end_time
261
- # }, hook=hook)
262
- #
263
- # for segment, _, speaker in diarization.itertracks(yield_label=True):
264
- # diarization_segments.append((segment.start, segment.end, speaker))
265
- # diarization_text += f"{segment.start:.2f} - {segment.end:.2f}: {speaker}\n"
266
- # speakers.add(speaker)
267
- #
268
- # return diarization_segments, diarization_text, speakers
269
- # except Exception as e:
270
- # st.error(f"Error al realizar la diarización de un segmento: {e}")
271
- # return None, None, 0
272
-
273
- # def transcribe_audio_whisper_transformers(audio_path):
274
- # try:
275
- # # Leer el archivo de audio y convertirlo en un numpy ndarray
276
- # audio_data, _ = sf.read(audio_path)
277
- #
278
- # # Convertir a un solo canal si es necesario
279
- # if len(audio_data.shape) > 1:
280
- # audio_data = np.mean(audio_data, axis=1)
281
- #
282
- # # Transcribir el audio usando el modelo Whisper
283
- # transcript = whisper_pipeline(audio_data, return_timestamps=True)
284
- # return transcript['text']
285
- # except Exception as e:
286
- # st.error(f"Error al transcribir el audio: {e}")
287
  # st.stop()
 
1
+ # import numpy as np
2
+ # import soundfile as sf
3
+ # import torchaudio
4
+
5
+ import os
6
+ import yt_dlp
7
+ import streamlit as st
8
+ import torch
9
+ import whisper
10
+ from pyannote.audio import Pipeline
11
+ from pyannote.audio.pipelines.utils.hook import ProgressHook
12
+ from moviepy.editor import AudioFileClip
13
+ from transformers import pipeline
14
+ from openai import Client
15
+ from dotenv import load_dotenv
16
+
17
+
18
+ load_dotenv()
19
+
20
+ hf_token = os.environ.get("HF_DIARIZATION_TOKEN")
21
+ api_key = os.environ.get("OPENAI_API_KEY")
22
+
23
+
24
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
25
+ st.info(f"Usando dispositivo: {device}")
26
+
27
+ pyannote_pipeline = Pipeline.from_pretrained(
28
+ "pyannote/speaker-diarization-3.1",
29
+ use_auth_token=hf_token,
30
+ )
31
+
32
+ if torch.cuda.is_available():
33
+ pyannote_pipeline.to(torch.device("cuda"))
34
+
35
+ sumamry_pipeline = pipeline(
36
+ "summarization",
37
+ model="t5-base",
38
+ device=device,
39
+ )
40
+
41
+ whisper_model = whisper.load_model("base")
42
+
43
+
44
+ def transcribir_segmentos(diarization_segments, audio_path):
45
+ diarization_text = ""
46
+ audio_duration = get_audio_duration(audio_path)
47
+ path = 'diarization_transcription.txt'
48
+ if os.path.exists(path):
49
+ os.remove(path)
50
+ st.success("Borrado archivo diarization_transcription.txt anterior")
51
+
52
+ progress_bar = st.progress(0)
53
+ total_segments = len(diarization_segments)
54
+
55
+ with open("diarization_transcription.txt", "w", encoding="utf-8") as file:
56
+ for i, (start_time, end_time, speaker) in enumerate(diarization_segments):
57
+ if start_time < 0 or end_time > audio_duration:
58
+ st.error(f"Segmento fuera de los límites del audio: {start_time} - {end_time}")
59
+ continue
60
+ if end_time - start_time < 0.5:
61
+ continue
62
+
63
+ segment_audio_path = f"segment_{start_time}_{end_time}.wav"
64
+ extract_audio_segment(audio_path, segment_audio_path, start_time, end_time)
65
+
66
+ transcript = transcribe_audio_whisper_lib(segment_audio_path) # Cambiar aca el trancript
67
+ if transcript:
68
+ diarization_text += f"{speaker}: {transcript}\n"
69
+ file.write(f"{speaker}: {transcript}\n")
70
+ os.remove(segment_audio_path)
71
+
72
+ progress = (i + 1) / total_segments
73
+ progress_bar.progress(progress)
74
+
75
+ return diarization_text
76
+
77
+
78
+ def process_transcripts(diarization_text, speakers):
79
+ speaker_transcripts = {speaker: [] for speaker in speakers}
80
+ for line in diarization_text.split('\n'):
81
+ if line:
82
+ speaker = line.split(':')[0].split()[-1]
83
+ transcript = line.split(': ')[1]
84
+ speaker_transcripts[speaker].append(transcript)
85
+ return speaker_transcripts
86
+
87
+
88
+ def summarize_speaker_transcripts(speaker_transcripts):
89
+ summaries = {}
90
+ for speaker, transcripts in speaker_transcripts.items():
91
+ full_text = ' '.join(transcripts)
92
+ max_tokens = 1024 # Ajusta según el modelo y tus necesidades
93
+ if len(full_text) > max_tokens:
94
+ full_text = full_text[:max_tokens]
95
+
96
+ summary = sumamry_pipeline(full_text, max_length=150, min_length=30, do_sample=False)[0]['summary_text']
97
+ summaries[speaker] = summary
98
+ return summaries
99
+
100
+
101
+ def diarize_full_audio(audio_path):
102
+ try:
103
+
104
+ audio_duration = get_audio_duration(audio_path)
105
+ diarization_segments = []
106
+ diarization_text = ""
107
+ speakers = set()
108
+
109
+ st.info(f"Procesando el audio completo de {audio_duration} segundos...")
110
+
111
+ with StreamlitProgressHook() as hook:
112
+ diarization = pyannote_pipeline({
113
+ 'audio': audio_path,
114
+ }, hook=hook)
115
+
116
+ for segment, _, speaker in diarization.itertracks(yield_label=True):
117
+ diarization_segments.append((segment.start, segment.end, speaker))
118
+ diarization_text += f"{segment.start:.2f} - {segment.end:.2f}: {speaker}\n"
119
+ speakers.add(speaker)
120
+
121
+ return diarization_segments, diarization_text, speakers
122
+ except Exception as e:
123
+ st.error(f"Error al realizar la diarización del audio entero: {e}")
124
+ return None, None, 0
125
+
126
+
127
+
128
+
129
+ def extract_audio_segment(input_audio_path, output_audio_path, start_time, end_time):
130
+ try:
131
+ audio = AudioFileClip(input_audio_path)
132
+ audio_subclip = audio.subclip(start_time, end_time)
133
+ audio_subclip.write_audiofile(output_audio_path)
134
+ except Exception as e:
135
+ st.error(f"Error al extraer el segmento de audio: {e}")
136
+ finally:
137
+ if 'audio' in locals():
138
+ audio.close()
139
+ if 'audio_subclip' in locals():
140
+ audio_subclip.close()
141
+
142
+
143
+ def transcribe_audio_whisper_lib(audio_path):
144
+ try:
145
+ with open(audio_path, "rb") as audio_file:
146
+ transcript = whisper_model.transcribe(audio_path)
147
+ return transcript["text"]
148
+ except Exception as e:
149
+ st.error(f"Error al transcribir el audio: {e}")
150
+ st.stop()
151
+
152
+
153
+
154
+ def download_youtube_audio(url, progress_bar):
155
+ # No incluyas la extensión '.wav' en el 'outtmpl'
156
+ output_path = os.path.join('temp_audio')
157
+ if os.path.exists(output_path + '.wav'):
158
+ os.remove(output_path + '.wav')
159
+ st.success("Borrado archivo temp_audio.wav anterior")
160
+
161
+ ydl_opts = {
162
+ 'format': 'bestaudio/best',
163
+ 'postprocessors': [{
164
+ 'key': 'FFmpegExtractAudio',
165
+ 'preferredcodec': 'wav',
166
+ 'preferredquality': '192',
167
+ }],
168
+ 'outtmpl': output_path,
169
+ 'progress_hooks': [lambda d: update_progress(d, progress_bar)], # Usa la función de progreso
170
+ 'noplaylist': True,
171
+ 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
172
+ 'Chrome/58.0.3029.110 Safari/537.3',
173
+ 'cookiefile': 'cookies.txt', # Aquí incluyes el archivo de cookies
174
+ }
175
+
176
+ try:
177
+ with yt_dlp.YoutubeDL(ydl_opts) as ydl:
178
+ ydl.download([url])
179
+ progress_bar.progress(1.0) # Asegúrate de que la barra de progreso llegue al 100% cuando termine
180
+
181
+ # Verifica si el archivo existe con la extensión .wav
182
+ final_output_path = output_path + '.wav'
183
+ st.write("Checking if file exists:", os.path.exists(final_output_path))
184
+ return final_output_path if os.path.exists(final_output_path) else None
185
+ except yt_dlp.utils.DownloadError as e:
186
+ st.error(f"Ocurrió un error al descargar el audio: {e}")
187
+ return None
188
+ except Exception as e:
189
+ st.error(f"Ocurrió un error: {e}")
190
+ return None
191
+
192
+
193
+ def get_audio_duration(audio_path):
194
+ try:
195
+ audio = AudioFileClip(audio_path)
196
+ return audio.duration
197
+ except Exception as e:
198
+ st.error(f"Error al obtener la duración del audio: {e}")
199
+ return 0
200
+
201
+ def update_progress(d, progress_bar):
202
+ if d['status'] == 'downloading':
203
+ total_bytes = d.get('total_bytes', None)
204
+ downloaded_bytes = d.get('downloaded_bytes', 0)
205
+
206
+ if total_bytes:
207
+ progress = downloaded_bytes / total_bytes
208
+ progress_bar.progress(progress) # Actualiza la barra de progreso con el porcentaje descargado
209
+ else:
210
+ progress_bar.progress(0.1) # Valor predeterminado si no se conoce el tamaño total
211
+
212
+ elif d['status'] == 'finished':
213
+ progress_bar.progress(0.9) # 90% cuando la descarga termina
214
+ elif d['status'] == 'postprocessing':
215
+ progress_bar.progress(0.95) # 95% durante el procesamiento de audio
216
+
217
+ class StreamlitProgressHook(ProgressHook):
218
+ def __init__(self, transient: bool = False):
219
+ super().__init__(transient)
220
+ self.progress_text = st.empty()
221
+
222
+ def __call__(self, step_name, step_artifact, file=None, total=None, completed=None):
223
+ super().__call__(step_name, step_artifact, file, total, completed)
224
+ if total is not None and completed is not None:
225
+ progress_message = f"{step_name:<20} ━ {'' * int(30 * (completed / total))} {completed / total:.0%}"
226
+ else:
227
+ progress_message = f"{step_name:<20} ━ Progress data unavailable"
228
+ self.progress_text.text(progress_message)
229
+
230
+
231
+ # def diarize_in_segments(audio_path, segment_duration=300):
232
+ # try:
233
+ # audio_duration = get_audio_duration(audio_path)
234
+ # diarization_segments = []
235
+ # diarization_text = ""
236
+ # speakers = set()
237
+ #
238
+ # # Procesar cada segmento por separado
239
+ # for start_time in range(0, int(audio_duration), segment_duration):
240
+ # end_time = min(start_time + segment_duration, audio_duration)
241
+ # st.info(f"Procesando segmento desde {start_time} hasta {end_time} segundos...")
242
+ #
243
+ # with StreamlitProgressHook() as hook:
244
+ # diarization = pyannote_pipeline({
245
+ # 'audio': audio_path,
246
+ # 'start': start_time,
247
+ # 'end': end_time
248
+ # }, hook=hook)
249
+ #
250
+ # for segment, _, speaker in diarization.itertracks(yield_label=True):
251
+ # diarization_segments.append((segment.start, segment.end, speaker))
252
+ # diarization_text += f"{segment.start:.2f} - {segment.end:.2f}: {speaker}\n"
253
+ # speakers.add(speaker)
254
+ #
255
+ # return diarization_segments, diarization_text, speakers
256
+ # except Exception as e:
257
+ # st.error(f"Error al realizar la diarización de un segmento: {e}")
258
+ # return None, None, 0
259
+
260
+ # def transcribe_audio_whisper_transformers(audio_path):
261
+ # try:
262
+ # # Leer el archivo de audio y convertirlo en un numpy ndarray
263
+ # audio_data, _ = sf.read(audio_path)
264
+ #
265
+ # # Convertir a un solo canal si es necesario
266
+ # if len(audio_data.shape) > 1:
267
+ # audio_data = np.mean(audio_data, axis=1)
268
+ #
269
+ # # Transcribir el audio usando el modelo Whisper
270
+ # transcript = whisper_pipeline(audio_data, return_timestamps=True)
271
+ # return transcript['text']
272
+ # except Exception as e:
273
+ # st.error(f"Error al transcribir el audio: {e}")
 
 
 
 
 
 
 
 
 
 
 
 
 
274
  # st.stop()