facuvillegas's picture
Update app.py
78a2505 verified
import gradio as gr
from moviepy.editor import VideoFileClip
from PIL import Image
import numpy as np
import os
import uuid
FRECUENCIA = 5 # segundos entre capturas
DURACION_MAXIMA = 30 # tope de duración a procesar (segundos)
os.makedirs("frames", exist_ok=True)
def extract_frames(video):
# 1) Guardar binario a disco
video_id = str(uuid.uuid4())[:8]
video_filename = f"{video_id}.mp4"
video_path = os.path.join("frames", video_filename)
with open(video_path, "wb") as f:
f.write(video.read())
# 2) Carpeta para frames
video_frames_dir = os.path.join("frames", video_id)
os.makedirs(video_frames_dir, exist_ok=True)
# 3) Procesar video
clip = VideoFileClip(video_path)
try:
duration = int(min(clip.duration or 0, DURACION_MAXIMA))
frame_filepaths = []
for t in range(0, max(duration, 0), FRECUENCIA):
frame = clip.get_frame(t) # numpy array (H, W, 3)
frame_path = os.path.join(video_frames_dir, f"frame_{t}s.jpg")
Image.fromarray(np.uint8(frame)).save(frame_path, quality=90)
frame_filepaths.append(frame_path)
finally:
clip.close()
# 4) Devolvemos:
# a) Files => Gradio publica y te da URLs /file=...
# b) JSON con metadatos
meta = {
"video_id": video_id,
"total_frames": len(frame_filepaths),
"frequency_seconds": FRECUENCIA,
"processed_seconds": duration
}
return frame_filepaths, meta
iface = gr.Interface(
fn=extract_frames,
inputs=gr.File(type="binary", label="Upload MP4"),
outputs=[
gr.Files(label="Frames"), # => enlaces descargables públicos
gr.JSON(label="Metadata") # => info útil
],
title="Video Frame Extractor",
allow_flagging="never"
)
iface.launch()