Spaces:
Build error
Build error
File size: 8,261 Bytes
fa12bf7 b11067c fa12bf7 b11067c fa12bf7 b11067c fa12bf7 b11067c bfcdcb0 b11067c bfcdcb0 b11067c fa12bf7 4e360d8 b11067c fa12bf7 bfcdcb0 fa12bf7 4e360d8 fa12bf7 b11067c 5b5c232 b11067c 5b5c232 b11067c 4e360d8 b11067c fa12bf7 b11067c bfcdcb0 b11067c bfcdcb0 b11067c fa12bf7 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 | # import numpy as np
# import soundfile as sf
# import torchaudio
# from transformers import pipeline
import os
import yt_dlp
import streamlit as st
import torch
import whisper
import google.generativeai as genai
from pyannote.audio import Pipeline
from pyannote.audio.pipelines.utils.hook import ProgressHook
from moviepy.editor import AudioFileClip
from openai import Client
from dotenv import load_dotenv
load_dotenv()
hf_token = os.environ.get("HF_DIARIZATION_TOKEN")
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
st.info(f"Usando dispositivo: {device}")
pyannote_pipeline = Pipeline.from_pretrained(
"pyannote/speaker-diarization-3.1",
use_auth_token=hf_token,
)
if torch.cuda.is_available():
pyannote_pipeline.to(torch.device("cuda"))
whisper_model = whisper.load_model("turbo")
def transcribir_segmentos(diarization_segments, audio_path):
diarization_text = ""
audio_duration = get_audio_duration(audio_path)
path = 'diarization_transcription.txt'
if os.path.exists(path):
os.remove(path)
st.success("Borrado archivo diarization_transcription.txt anterior")
progress_bar = st.progress(0)
total_segments = len(diarization_segments)
with open("diarization_transcription.txt", "w", encoding="utf-8") as file:
for i, (start_time, end_time, speaker) in enumerate(diarization_segments):
if start_time < 0 or end_time > audio_duration:
st.error(f"Segmento fuera de los límites del audio: {start_time} - {end_time}")
continue
if end_time - start_time < 0.5:
continue
segment_audio_path = f"segment_{start_time}_{end_time}.wav"
extract_audio_segment(audio_path, segment_audio_path, start_time, end_time)
transcript = transcribe_audio_whisper_lib(segment_audio_path) # Cambiar aca el trancript
if transcript:
diarization_text += f"{speaker}: {transcript}\n"
file.write(f"{speaker}: {transcript}\n")
os.remove(segment_audio_path)
progress = (i + 1) / total_segments
progress_bar.progress(progress)
return diarization_text
def process_transcripts(diarization_text, speakers):
speaker_transcripts = {speaker: [] for speaker in speakers}
for line in diarization_text.split('\n'):
if line:
speaker = line.split(':')[0].split()[-1]
transcript = line.split(': ')[1]
speaker_transcripts[speaker].append(transcript)
return speaker_transcripts
def summarize_speaker_transcripts(speaker_transcripts):
gapi_key = os.environ.get("GEMINI_API_KEY")
genai.configure(api_key=gapi_key)
model = genai.GenerativeModel("gemini-1.5-flash")
for speaker, transcripts in speaker_transcripts.items():
full_text = ' '.join(transcripts)
max_tokens = 1024 # Ajusta según el modelo y tus necesidades
if len(full_text) > max_tokens:
full_text = full_text[:max_tokens]
prompt=f"Por favor, resume el siguiente texto:\n\n{full_text}"
response = model.generate_content(prompt)
st.text_area(f"Resumen del Hablante {speaker}", response.text, height=200)
def diarize_full_audio(audio_path):
try:
audio_duration = get_audio_duration(audio_path)
diarization_segments = []
diarization_text = ""
speakers = {}
speaker_counter = 0
st.info(f"Procesando el audio completo de {audio_duration} segundos...")
with StreamlitProgressHook() as hook:
diarization = pyannote_pipeline({
'audio': audio_path,
}, hook=hook)
for segment, _, speaker in diarization.itertracks(yield_label=True):
if speaker not in speakers:
speakers[speaker] = f"SPEAKER_{speaker_counter:02d}"
speaker_counter += 1
diarization_segments.append((segment.start, segment.end, speakers[speaker]))
diarization_text += f"{segment.start:.2f} - {segment.end:.2f}: {speakers[speaker]}\n"
return diarization_segments, diarization_text, speakers
except Exception as e:
st.error(f"Error al realizar la diarización del audio entero: {e}")
return None, None, 0
def extract_audio_segment(input_audio_path, output_audio_path, start_time, end_time):
try:
audio = AudioFileClip(input_audio_path)
audio_subclip = audio.subclip(start_time, end_time)
audio_subclip.write_audiofile(output_audio_path)
except Exception as e:
st.error(f"Error al extraer el segmento de audio: {e}")
finally:
if 'audio' in locals():
audio.close()
if 'audio_subclip' in locals():
audio_subclip.close()
def transcribe_audio_whisper_lib(audio_path):
try:
transcript = whisper_model.transcribe(audio_path)
return transcript["text"]
except Exception as e:
st.error(f"Error al transcribir el audio: {e}")
st.stop()
def download_youtube_audio(url, progress_bar):
# No incluyas la extensión '.wav' en el 'outtmpl'
output_path = os.path.join('temp_audio')
if os.path.exists(output_path + '.wav'):
os.remove(output_path + '.wav')
st.success("Borrado archivo temp_audio.wav anterior")
ydl_opts = {
'format': 'bestaudio/best',
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'wav',
'preferredquality': '192',
}],
'outtmpl': output_path,
'progress_hooks': [lambda d: update_progress(d, progress_bar)], # Usa la función de progreso
'noplaylist': True,
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/58.0.3029.110 Safari/537.3',
'cookiefile': 'cookies.txt', # Aquí incluyes el archivo de cookies
}
try:
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
ydl.download([url])
progress_bar.progress(1.0) # Asegúrate de que la barra de progreso llegue al 100% cuando termine
# Verifica si el archivo existe con la extensión .wav
final_output_path = output_path + '.wav'
st.write("Checking if file exists:", os.path.exists(final_output_path))
return final_output_path if os.path.exists(final_output_path) else None
except yt_dlp.utils.DownloadError as e:
st.error(f"Ocurrió un error al descargar el audio: {e}")
return None
except Exception as e:
st.error(f"Ocurrió un error: {e}")
return None
def get_audio_duration(audio_path):
try:
audio = AudioFileClip(audio_path)
return audio.duration
except Exception as e:
st.error(f"Error al obtener la duración del audio: {e}")
return 0
def update_progress(d, progress_bar):
if d['status'] == 'downloading':
total_bytes = d.get('total_bytes', None)
downloaded_bytes = d.get('downloaded_bytes', 0)
if total_bytes:
progress = downloaded_bytes / total_bytes
progress_bar.progress(progress) # Actualiza la barra de progreso con el porcentaje descargado
else:
progress_bar.progress(0.1) # Valor predeterminado si no se conoce el tamaño total
elif d['status'] == 'finished':
progress_bar.progress(0.9) # 90% cuando la descarga termina
elif d['status'] == 'postprocessing':
progress_bar.progress(0.95) # 95% durante el procesamiento de audio
class StreamlitProgressHook(ProgressHook):
def __init__(self, transient: bool = False):
super().__init__(transient)
self.progress_text = st.empty()
def __call__(self, step_name, step_artifact, file=None, total=None, completed=None):
super().__call__(step_name, step_artifact, file, total, completed)
if total is not None and completed is not None:
progress_message = f"{step_name:<20} ━ {'━' * int(30 * (completed / total))} {completed / total:.0%}"
else:
progress_message = f"{step_name:<20} ━ Progress data unavailable"
self.progress_text.text(progress_message)
|