Andro0s commited on
Commit
73f68af
·
verified ·
1 Parent(s): d034fd9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +31 -42
app.py CHANGED
@@ -2,96 +2,95 @@ import gradio as gr
2
  import whisper
3
  import os
4
  import tempfile
5
- import numpy as np
6
  from pydub import AudioSegment
7
- import torch
8
 
9
- # Cargar modelo (usa "base" para CPU, "small" o "medium" si tienes GPU)
10
  print("Cargando modelo Whisper...")
11
  model = whisper.load_model("base")
12
  print("Modelo cargado.")
13
 
14
  def extract_audio_from_video(video_path):
15
  """Extrae audio de video usando ffmpeg"""
16
- import subprocess
17
- audio_path = video_path.replace('.mp4', '.wav').replace('.avi', '.wav').replace('.mov', '.wav')
18
- audio_path = audio_path + "_audio.wav"
19
 
20
  command = [
21
  'ffmpeg',
22
  '-i', video_path,
23
- '-vn', # No video
24
  '-acodec', 'pcm_s16le',
25
- '-ar', '16000', # Whisper necesita 16kHz
26
- '-ac', '1', # Mono
 
27
  audio_path
28
  ]
29
 
30
- subprocess.run(command, capture_output=True)
 
 
 
31
  return audio_path
32
 
33
- def split_audio(audio_path, chunk_length_ms=30000): # 30 segundos por chunk
34
- """Divide el audio en chunks para procesar largos"""
35
  audio = AudioSegment.from_wav(audio_path)
36
  chunks = []
37
 
38
  for i in range(0, len(audio), chunk_length_ms):
39
  chunk = audio[i:i + chunk_length_ms]
40
- chunk_path = f"{audio_path}_chunk_{i}.wav"
41
  chunk.export(chunk_path, format="wav")
42
  chunks.append(chunk_path)
43
 
44
  return chunks
45
 
46
  def transcribir_archivo(archivo):
47
- """
48
- Función principal de transcripción
49
- """
50
  if archivo is None:
51
- return "Por favor sube un archivo"
 
52
 
53
- archivo_path = archivo.name if hasattr(archivo, 'name') else archivo
54
  texto_completo = []
55
  archivos_temp = []
56
 
57
  try:
58
- # Determinar si es video o audio
59
- extension = os.path.splitext(archivo_path)[1].lower()
60
- es_video = extension in ['.mp4', '.avi', '.mov', '.mkv', '.webm']
61
 
62
  yield "Procesando archivo...", ""
63
 
64
  # Extraer audio si es video
65
  if es_video:
66
  yield "Extrayendo audio del video...", ""
67
- audio_path = extract_audio_from_video(archivo_path)
68
  archivos_temp.append(audio_path)
69
  else:
70
- # Convertir a wav si es necesario
71
- audio = AudioSegment.from_file(archivo_path)
 
72
  audio_path = tempfile.mktemp(suffix='.wav')
73
  audio.export(audio_path, format="wav", parameters=["-ar", "16000", "-ac", "1"])
74
  archivos_temp.append(audio_path)
75
 
76
- # Dividir en chunks si es muy largo (>30 segundos)
77
  audio = AudioSegment.from_wav(audio_path)
78
- duracion_total = len(audio) / 1000 # segundos
79
 
80
  if duracion_total > 30:
81
  yield f"Dividiendo audio en partes (duración: {duracion_total:.1f}s)...", ""
82
- chunks = split_audio(audio_path, 30000) # 30s chunks
83
  archivos_temp.extend(chunks)
84
  else:
85
  chunks = [audio_path]
86
 
87
- # Transcribir cada chunk
88
  total_chunks = len(chunks)
89
  for i, chunk_path in enumerate(chunks):
90
- yield f"Transcribiendo parte {i+1} de {total_chunks}...", "\n".join(texto_completo)
91
 
92
  resultado = model.transcribe(
93
  chunk_path,
94
- language="es", # Forzar español (quita esto para autodetectar)
95
  task="transcribe"
96
  )
97
  texto_completo.append(resultado["text"])
@@ -103,7 +102,7 @@ def transcribir_archivo(archivo):
103
  yield f"Error: {str(e)}", ""
104
 
105
  finally:
106
- # Limpiar archivos temporales
107
  for temp_file in archivos_temp:
108
  try:
109
  if os.path.exists(temp_file):
@@ -111,15 +110,12 @@ def transcribir_archivo(archivo):
111
  except:
112
  pass
113
 
114
- # Interfaz de Gradio
115
  with gr.Blocks(title="Transcriptor de Video/Audio") as demo:
116
  gr.Markdown("""
117
  # 🎙️ Transcriptor de Video y Audio
118
 
119
  Sube un video o archivo de audio y obtén la transcripción en texto.
120
-
121
- **Soporta:** MP4, AVI, MOV, MP3, WAV, M4A, etc.
122
- **Idioma:** Optimizado para español (pero detecta automáticamente)
123
  """)
124
 
125
  with gr.Row():
@@ -143,13 +139,6 @@ with gr.Blocks(title="Transcriptor de Video/Audio") as demo:
143
  inputs=archivo_input,
144
  outputs=[estado, resultado]
145
  )
146
-
147
- gr.Markdown("""
148
- ### 💡 Tips:
149
- - Archivos largos se dividen automáticamente en partes
150
- - El procesamiento puede tomar varios minutos dependiendo la duración
151
- - Máximo recomendado: 1 hora de audio (puede variar según recursos del Space)
152
- """)
153
 
154
  if __name__ == "__main__":
155
  demo.launch()
 
2
  import whisper
3
  import os
4
  import tempfile
 
5
  from pydub import AudioSegment
6
+ import subprocess
7
 
8
+ # Cargar modelo
9
  print("Cargando modelo Whisper...")
10
  model = whisper.load_model("base")
11
  print("Modelo cargado.")
12
 
13
  def extract_audio_from_video(video_path):
14
  """Extrae audio de video usando ffmpeg"""
15
+ audio_path = tempfile.mktemp(suffix='.wav')
 
 
16
 
17
  command = [
18
  'ffmpeg',
19
  '-i', video_path,
20
+ '-vn',
21
  '-acodec', 'pcm_s16le',
22
+ '-ar', '16000',
23
+ '-ac', '1',
24
+ '-y', # Sobrescribir si existe
25
  audio_path
26
  ]
27
 
28
+ result = subprocess.run(command, capture_output=True, text=True)
29
+ if result.returncode != 0:
30
+ raise Exception(f"Error extrayendo audio: {result.stderr}")
31
+
32
  return audio_path
33
 
34
+ def split_audio(audio_path, chunk_length_ms=30000):
35
+ """Divide el audio en chunks"""
36
  audio = AudioSegment.from_wav(audio_path)
37
  chunks = []
38
 
39
  for i in range(0, len(audio), chunk_length_ms):
40
  chunk = audio[i:i + chunk_length_ms]
41
+ chunk_path = tempfile.mktemp(suffix=f'_chunk_{i}.wav')
42
  chunk.export(chunk_path, format="wav")
43
  chunks.append(chunk_path)
44
 
45
  return chunks
46
 
47
  def transcribir_archivo(archivo):
48
+ """Función principal de transcripción"""
 
 
49
  if archivo is None:
50
+ yield "Por favor sube un archivo", ""
51
+ return
52
 
 
53
  texto_completo = []
54
  archivos_temp = []
55
 
56
  try:
57
+ extension = os.path.splitext(archivo)[1].lower()
58
+ es_video = extension in ['.mp4', '.avi', '.mov', '.mkv', '.webm', '.mpg', '.mpeg']
 
59
 
60
  yield "Procesando archivo...", ""
61
 
62
  # Extraer audio si es video
63
  if es_video:
64
  yield "Extrayendo audio del video...", ""
65
+ audio_path = extract_audio_from_video(archivo)
66
  archivos_temp.append(audio_path)
67
  else:
68
+ # Convertir a wav
69
+ yield "Convirtiendo audio...", ""
70
+ audio = AudioSegment.from_file(archivo)
71
  audio_path = tempfile.mktemp(suffix='.wav')
72
  audio.export(audio_path, format="wav", parameters=["-ar", "16000", "-ac", "1"])
73
  archivos_temp.append(audio_path)
74
 
75
+ # Verificar duración
76
  audio = AudioSegment.from_wav(audio_path)
77
+ duracion_total = len(audio) / 1000
78
 
79
  if duracion_total > 30:
80
  yield f"Dividiendo audio en partes (duración: {duracion_total:.1f}s)...", ""
81
+ chunks = split_audio(audio_path, 30000)
82
  archivos_temp.extend(chunks)
83
  else:
84
  chunks = [audio_path]
85
 
86
+ # Transcribir
87
  total_chunks = len(chunks)
88
  for i, chunk_path in enumerate(chunks):
89
+ yield f"Transcribiendo parte {i+1} de {total_chunks}...", "\n\n".join(texto_completo)
90
 
91
  resultado = model.transcribe(
92
  chunk_path,
93
+ language="es",
94
  task="transcribe"
95
  )
96
  texto_completo.append(resultado["text"])
 
102
  yield f"Error: {str(e)}", ""
103
 
104
  finally:
105
+ # Limpiar
106
  for temp_file in archivos_temp:
107
  try:
108
  if os.path.exists(temp_file):
 
110
  except:
111
  pass
112
 
113
+ # Interfaz Gradio
114
  with gr.Blocks(title="Transcriptor de Video/Audio") as demo:
115
  gr.Markdown("""
116
  # 🎙️ Transcriptor de Video y Audio
117
 
118
  Sube un video o archivo de audio y obtén la transcripción en texto.
 
 
 
119
  """)
120
 
121
  with gr.Row():
 
139
  inputs=archivo_input,
140
  outputs=[estado, resultado]
141
  )
 
 
 
 
 
 
 
142
 
143
  if __name__ == "__main__":
144
  demo.launch()