import gradio as gr import subprocess import os import zipfile import shutil import uuid def video_to_frames(video, fps): uid = str(uuid.uuid4()) out_dir = f"frames_{uid}" os.makedirs(out_dir, exist_ok=True) output_pattern = os.path.join(out_dir, "frame_%06d.png") if fps == 0: cmd = [ "ffmpeg", "-i", video, "-vsync", "0", output_pattern ] else: cmd = [ "ffmpeg", "-i", video, "-vf", f"fps={fps}", "-vsync", "0", output_pattern ] subprocess.run(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) zip_path = f"{out_dir}.zip" with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf: for root, _, files in os.walk(out_dir): for file in files: zipf.write(os.path.join(root, file), arcname=file) shutil.rmtree(out_dir) return zip_path with gr.Blocks() as demo: gr.Markdown("### video → image sequence (lossless)\nno quality loss.") video = gr.Video(label="upload video") fps = gr.Slider(0, 60, step=1, value=0, label="fps (0 = original fps)") out = gr.File(label="download frames (.zip)") btn = gr.Button("extract frames") btn.click(video_to_frames, inputs=[video, fps], outputs=out) demo.launch()