gnosticdev commited on
Commit
5d96110
verified
1 Parent(s): dc23696

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +76 -3
app.py CHANGED
@@ -7,20 +7,24 @@ import edge_tts
7
  import gradio as gr
8
  from pydub import AudioSegment
9
 
 
10
  logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
11
 
 
12
  INTRO_VIDEO = "introvideo.mp4"
13
  OUTRO_VIDEO = "outrovideo.mp4"
14
  MUSIC_BG = "musicafondo.mp3"
15
  EJEMPLO_VIDEO = "ejemplo.mp4"
16
 
 
17
  for file in [INTRO_VIDEO, OUTRO_VIDEO, MUSIC_BG, EJEMPLO_VIDEO]:
18
  if not os.path.exists(file):
19
  logging.error(f"Falta archivo necesario: {file}")
20
  raise FileNotFoundError(f"Falta: {file}")
21
 
22
- SEGMENT_DURATION = 30
23
- TRANSITION_DURATION = 1.5
 
24
 
25
  def eliminar_archivo_tiempo(ruta, delay=1800):
26
  def eliminar():
@@ -35,6 +39,66 @@ def eliminar_archivo_tiempo(ruta, delay=1800):
35
 
36
  async def generar_tts(texto, voz, duracion_total):
37
  try:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  logging.info("Generando TTS")
39
  communicate = edge_tts.Communicate(texto, voz)
40
  with tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") as tmp_tts:
@@ -75,15 +139,21 @@ async def procesar_video(video_input, texto_tts, voz_seleccionada):
75
  logging.info("Iniciando procesamiento")
76
  video_original = VideoFileClip(video_input, target_resolution=(720, 1280))
77
  duracion_video = video_original.duration
 
 
 
 
78
  tts_audio, tts_path = await generar_tts(texto_tts, voz_seleccionada, duracion_video)
79
  bg_audio, bg_path = crear_musica_fondo(duracion_video)
80
  temp_files.extend([tts_path, bg_path])
 
81
  audio_original = video_original.audio.volumex(0.7) if video_original.audio else None
82
  audios = [bg_audio.set_duration(duracion_video)]
83
  if audio_original:
84
  audios.append(audio_original)
85
  audios.append(tts_audio.set_start(0).volumex(0.85))
86
  audio_final = CompositeAudioClip(audios).set_duration(duracion_video)
 
87
  video_final = video_original.copy()
88
  if duracion_video > SEGMENT_DURATION:
89
  clips = []
@@ -103,10 +173,12 @@ async def procesar_video(video_input, texto_tts, voz_seleccionada):
103
  clips.append(transition)
104
  clips.append(segment)
105
  video_final = concatenate_videoclips(clips, method="compose")
 
106
  video_final = video_final.set_audio(audio_final)
107
  intro = VideoFileClip(INTRO_VIDEO, target_resolution=(720, 1280))
108
  outro = VideoFileClip(OUTRO_VIDEO, target_resolution=(720, 1280))
109
  video_final = concatenate_videoclips([intro, video_final, outro], method="compose")
 
110
  with tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) as tmp:
111
  video_final.write_videofile(
112
  tmp.name,
@@ -145,6 +217,7 @@ async def procesar_video(video_input, texto_tts, voz_seleccionada):
145
  except Exception as e:
146
  logging.warning(f"Error al cerrar recursos: {str(e)}")
147
 
 
148
  with gr.Blocks() as demo:
149
  gr.Markdown("# Editor de Video con IA")
150
  with gr.Tab("Principal"):
@@ -158,7 +231,7 @@ with gr.Blocks() as demo:
158
  label="Voz",
159
  choices=[
160
  "es-ES-AlvaroNeural", "es-MX-BeatrizNeural",
161
- "es-ES-ElviraNeural", "es-MX-JavierNeural",
162
  "es-AR-ElenaNeural", "es-AR-TomasNeural",
163
  "es-CL-CatalinaNeural", "es-CL-LorenzoNeural",
164
  "es-CO-SofiaNeural", "es-CO-GonzaloNeural",
 
7
  import gradio as gr
8
  from pydub import AudioSegment
9
 
10
+ # Configuraci贸n de Logs
11
  logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
12
 
13
+ # CONSTANTES DE ARCHIVOS
14
  INTRO_VIDEO = "introvideo.mp4"
15
  OUTRO_VIDEO = "outrovideo.mp4"
16
  MUSIC_BG = "musicafondo.mp3"
17
  EJEMPLO_VIDEO = "ejemplo.mp4"
18
 
19
+ # Validar existencia de archivos
20
  for file in [INTRO_VIDEO, OUTRO_VIDEO, MUSIC_BG, EJEMPLO_VIDEO]:
21
  if not os.path.exists(file):
22
  logging.error(f"Falta archivo necesario: {file}")
23
  raise FileNotFoundError(f"Falta: {file}")
24
 
25
+ # Configuraci贸n de chunks
26
+ SEGMENT_DURATION = 30 # Duraci贸n exacta entre transiciones (sin overlap)
27
+ TRANSITION_DURATION = 1.5 # Duraci贸n del efecto slide
28
 
29
  def eliminar_archivo_tiempo(ruta, delay=1800):
30
  def eliminar():
 
39
 
40
  async def generar_tts(texto, voz, duracion_total):
41
  try:
42
+ # Validar texto
43
+ if not texto.strip():
44
+ raise ValueError("El texto para TTS no puede estar vac铆o.")
45
+ if len(texto) > 1000: # L铆mite aproximado de Edge TTS
46
+ texto = texto[:1000] # Truncar texto si es demasiado largo
47
+
48
+ # Validar voz
49
+ voces_validas = [
50
+ "es-ES-AlvaroNeural", "es-MX-BeatrizNeural",
51
+ "es-ES-ElviraNeural", "es-MX-JavierNeural",
52
+ "es-AR-ElenaNeural", "es-AR-TomasNeural",
53
+ "es-CL-CatalinaNeural", "es-CL-LorenzoNeural",
54
+ "es-CO-SofiaNeural", "es-CO-GonzaloNeural",
55
+ "es-PE-CamilaNeural", "es-PE-AlexNeural",
56
+ "es-VE-MariaNeural", "es-VE-ManuelNeural",
57
+ "es-US-AlonsoNeural", "es-US-PalomaNeural",
58
+ "es-ES-AbrilNeural", "es-ES-DarioNeural",
59
+ "es-ES-HelenaRUS", "es-ES-LauraNeural",
60
+ "es-ES-PabloNeural", "es-ES-TriniNeural",
61
+ "en-US-AriaNeural", "en-US-GuyNeural",
62
+ "en-US-JennyNeural", "en-US-AmberNeural",
63
+ "en-US-AnaNeural", "en-US-AshleyNeural",
64
+ "en-US-BrandonNeural", "en-US-ChristopherNeural",
65
+ "en-US-CoraNeural", "en-US-DavisNeural",
66
+ "en-US-ElizabethNeural", "en-US-EricNeural",
67
+ "en-US-GinaNeural", "en-US-JacobNeural",
68
+ "en-US-JaneNeural", "en-US-JasonNeural",
69
+ "en-US-MichelleNeural", "en-US-MonicaNeural",
70
+ "en-US-SaraNeural", "en-US-SteffanNeural",
71
+ "en-US-TonyNeural", "en-US-YaraNeural",
72
+ "fr-FR-AlainNeural", "fr-FR-BrigitteNeural",
73
+ "fr-FR-CelesteNeural", "fr-FR-ClaudeNeural",
74
+ "fr-FR-CoralieNeural", "fr-FR-DeniseNeural",
75
+ "fr-FR-EloiseNeural", "fr-FR-HenriNeural",
76
+ "fr-FR-JacquelineNeural", "fr-FR-JeromeNeural",
77
+ "fr-FR-JosephineNeural", "fr-FR-MauriceNeural",
78
+ "fr-FR-YvesNeural", "fr-FR-YvetteNeural",
79
+ "de-DE-AmalaNeural", "de-DE-BerndNeural",
80
+ "de-DE-ChristophNeural", "de-DE-ConradNeural",
81
+ "de-DE-ElkeNeural", "de-DE-GiselaNeural",
82
+ "de-DE-KasperNeural", "de-DE-KatjaNeural",
83
+ "de-DE-KillianNeural", "de-DE-KlarissaNeural",
84
+ "de-DE-KlausNeural", "de-DE-LouisaNeural",
85
+ "de-DE-MajaNeural", "de-DE-RalfNeural",
86
+ "de-DE-TanjaNeural", "de-DE-ViktoriaNeural",
87
+ "it-IT-BenignoNeural", "it-IT-CalimeroNeural",
88
+ "it-IT-CataldoNeural", "it-IT-DiegoNeural",
89
+ "it-IT-ElsaNeural", "it-IT-FabiolaNeural",
90
+ "it-IT-GianniNeural", "it-IT-ImeldaNeural",
91
+ "it-IT-IrmaNeural", "it-IT-IsabellaNeural",
92
+ "it-IT-LisandroNeural", "it-IT-PalmiraNeural",
93
+ "it-IT-PierinaNeural", "it-IT-RinaldoNeural",
94
+ "ja-JP-AoiNeural", "ja-JP-DaichiNeural",
95
+ "ja-JP-HarukaNeural", "ja-JP-KeitaNeural",
96
+ "ja-JP-MayuNeural", "ja-JP-NanamiNeural",
97
+ "ja-JP-NaokiNeural", "ja-JP-ShioriNeural"
98
+ ]
99
+ if voz not in voces_validas:
100
+ raise ValueError(f"La voz seleccionada '{voz}' no es v谩lida.")
101
+
102
  logging.info("Generando TTS")
103
  communicate = edge_tts.Communicate(texto, voz)
104
  with tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") as tmp_tts:
 
139
  logging.info("Iniciando procesamiento")
140
  video_original = VideoFileClip(video_input, target_resolution=(720, 1280))
141
  duracion_video = video_original.duration
142
+
143
+ if duracion_video <= 0:
144
+ raise ValueError("El video debe tener una duraci贸n mayor que cero.")
145
+
146
  tts_audio, tts_path = await generar_tts(texto_tts, voz_seleccionada, duracion_video)
147
  bg_audio, bg_path = crear_musica_fondo(duracion_video)
148
  temp_files.extend([tts_path, bg_path])
149
+
150
  audio_original = video_original.audio.volumex(0.7) if video_original.audio else None
151
  audios = [bg_audio.set_duration(duracion_video)]
152
  if audio_original:
153
  audios.append(audio_original)
154
  audios.append(tts_audio.set_start(0).volumex(0.85))
155
  audio_final = CompositeAudioClip(audios).set_duration(duracion_video)
156
+
157
  video_final = video_original.copy()
158
  if duracion_video > SEGMENT_DURATION:
159
  clips = []
 
173
  clips.append(transition)
174
  clips.append(segment)
175
  video_final = concatenate_videoclips(clips, method="compose")
176
+
177
  video_final = video_final.set_audio(audio_final)
178
  intro = VideoFileClip(INTRO_VIDEO, target_resolution=(720, 1280))
179
  outro = VideoFileClip(OUTRO_VIDEO, target_resolution=(720, 1280))
180
  video_final = concatenate_videoclips([intro, video_final, outro], method="compose")
181
+
182
  with tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) as tmp:
183
  video_final.write_videofile(
184
  tmp.name,
 
217
  except Exception as e:
218
  logging.warning(f"Error al cerrar recursos: {str(e)}")
219
 
220
+ # Interfaz Gradio
221
  with gr.Blocks() as demo:
222
  gr.Markdown("# Editor de Video con IA")
223
  with gr.Tab("Principal"):
 
231
  label="Voz",
232
  choices=[
233
  "es-ES-AlvaroNeural", "es-MX-BeatrizNeural",
234
+ "es-ES-ElviraNeural", "es-MX-JavierNeural",
235
  "es-AR-ElenaNeural", "es-AR-TomasNeural",
236
  "es-CL-CatalinaNeural", "es-CL-LorenzoNeural",
237
  "es-CO-SofiaNeural", "es-CO-GonzaloNeural",