gnosticdev commited on
Commit
01a849d
verified
1 Parent(s): 68930cd

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +38 -22
app.py CHANGED
@@ -6,23 +6,29 @@ from PIL import Image, ImageDraw
6
  import tempfile
7
  import os
8
  import logging
 
9
 
10
  # Configuraci贸n de logging
11
- logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(message)s')
 
 
 
 
 
12
 
13
- def generate_video(audio_path, image_path):
14
  try:
15
  # 1. Cargar audio
16
- y, sr = librosa.load(audio_path, sr=None)
17
  duration = librosa.get_duration(y=y, sr=sr)
18
- logging.info(f"Audio cargado ({duration:.1f} segundos)")
19
 
20
  # 2. Cargar imagen
21
- img = Image.open(image_path).convert('RGB')
22
  img_w, img_h = img.size
23
- logging.info(f"Imagen cargada ({img_w}x{img_h})")
24
 
25
- # 3. Crear efecto de onda
26
  audio_envelope = np.abs(y) / np.max(np.abs(y)) # Normalizar
27
  audio_envelope *= img_h // 4 # Escalar al 25% de la altura
28
 
@@ -31,13 +37,11 @@ def generate_video(audio_path, image_path):
31
  frame = img.copy()
32
  draw = ImageDraw.Draw(frame)
33
 
34
- # Calcular posici贸n en el audio
35
  time_idx = int(t * sr)
36
  start = max(0, time_idx - sr//10)
37
  end = min(len(audio_envelope), time_idx + sr//10)
38
  wave_slice = audio_envelope[start:end]
39
 
40
- # Dibujar onda
41
  points = []
42
  for i, val in enumerate(wave_slice):
43
  x = int((i / len(wave_slice)) * img_w)
@@ -46,35 +50,47 @@ def generate_video(audio_path, image_path):
46
  points.extend([(x, y_pos), (x, y_neg)])
47
 
48
  if len(points) > 2:
49
- draw.polygon(points, fill=(255, 0, 0, 128)) # Rojo semitransparente
50
 
51
  return np.array(frame)
52
 
53
  # 5. Crear video
54
  video = mp.VideoClip(make_frame, duration=duration)
55
  video.fps = 24
56
- video = video.set_audio(mp.AudioFileClip(audio_path))
57
-
58
- # 6. Guardar video temporalmente
59
- temp_file = tempfile.NamedTemporaryFile(suffix=".mp4", delete=False)
60
- video.write_videofile(temp_file.name, codec="libx264", audio_codec="aac", fps=24, logger=None)
61
- logging.info(f"Video guardado temporalmente en: {temp_file.name}")
62
 
63
- # Retornar el archivo como descargable
64
- return temp_file.name
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
 
66
  except Exception as e:
67
- logging.error(f"Error: {str(e)}")
68
  return f"Error: {str(e)}"
69
 
70
  # Interfaz Gradio
71
  iface = gr.Interface(
72
  fn=generate_video,
73
  inputs=[
74
- gr.Audio(type="filepath", label="Subir Audio (WAV/MP3)"),
75
- gr.Image(type="filepath", label="Subir Imagen de Fondo")
76
  ],
77
- outputs=gr.File(label="Descargar Video"), # Cambiado a gr.File para descargar
78
  title="Generador de Video Musical",
79
  description="Crea videos con efectos de audio sincronizados. Sube un audio y una imagen."
80
  )
 
6
  import tempfile
7
  import os
8
  import logging
9
+ from tqdm import tqdm
10
 
11
  # Configuraci贸n de logging
12
+ logging.basicConfig(
13
+ level=logging.INFO,
14
+ format='%(asctime)s - %(levelname)s - %(message)s',
15
+ handlers=[logging.StreamHandler()]
16
+ )
17
+ logger = logging.getLogger("audio_to_video")
18
 
19
+ def generate_video(audio_file, image_file):
20
  try:
21
  # 1. Cargar audio
22
+ y, sr = librosa.load(audio_file)
23
  duration = librosa.get_duration(y=y, sr=sr)
24
+ logger.info(f"Audio cargado: {duration:.1f} segundos")
25
 
26
  # 2. Cargar imagen
27
+ img = Image.open(image_file).convert('RGB')
28
  img_w, img_h = img.size
29
+ logger.info(f"Imagen cargada: {img_w}x{img_h}")
30
 
31
+ # 3. Crear efecto waveform
32
  audio_envelope = np.abs(y) / np.max(np.abs(y)) # Normalizar
33
  audio_envelope *= img_h // 4 # Escalar al 25% de la altura
34
 
 
37
  frame = img.copy()
38
  draw = ImageDraw.Draw(frame)
39
 
 
40
  time_idx = int(t * sr)
41
  start = max(0, time_idx - sr//10)
42
  end = min(len(audio_envelope), time_idx + sr//10)
43
  wave_slice = audio_envelope[start:end]
44
 
 
45
  points = []
46
  for i, val in enumerate(wave_slice):
47
  x = int((i / len(wave_slice)) * img_w)
 
50
  points.extend([(x, y_pos), (x, y_neg)])
51
 
52
  if len(points) > 2:
53
+ draw.polygon(points, fill=(255, 0, 0, 128))
54
 
55
  return np.array(frame)
56
 
57
  # 5. Crear video
58
  video = mp.VideoClip(make_frame, duration=duration)
59
  video.fps = 24
60
+ video = video.set_audio(mp.AudioFileClip(audio_file))
 
 
 
 
 
61
 
62
+ # 6. Guardar video
63
+ with tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) as tmpfile:
64
+ # Mostrar barra de progreso
65
+ with tqdm(total=100, desc="Exportando") as pbar:
66
+ video.write_videofile(
67
+ tmpfile.name,
68
+ codec="libx264",
69
+ audio_codec="aac",
70
+ fps=24,
71
+ logger=None,
72
+ progress_callback=lambda gd: pbar.update(gd['percent'] - pbar.n)
73
+ )
74
+
75
+ # Asegurar que el archivo existe
76
+ if not os.path.exists(tmpfile.name):
77
+ raise Exception("Error al guardar el video temporal")
78
+
79
+ logger.info(f"Video guardado: {tmpfile.name}")
80
+ return tmpfile.name # Retornar la ruta del archivo
81
 
82
  except Exception as e:
83
+ logger.error(f"Error cr铆tico: {str(e)}")
84
  return f"Error: {str(e)}"
85
 
86
  # Interfaz Gradio
87
  iface = gr.Interface(
88
  fn=generate_video,
89
  inputs=[
90
+ gr.Audio(type="filepath", label="Audio (WAV/MP3)"),
91
+ gr.Image(type="filepath", label="Imagen de Fondo")
92
  ],
93
+ outputs=gr.File(label="Descargar Video"), # Usar File para descargar
94
  title="Generador de Video Musical",
95
  description="Crea videos con efectos de audio sincronizados. Sube un audio y una imagen."
96
  )