import os import subprocess import shutil import gradio as gr def check_video_size(video_path, max_size_mb=1000): size_mb = os.path.getsize(video_path) / (1024 * 1024) if size_mb > max_size_mb: raise gr.Error(f"Video is too large ({size_mb:.1f} MB). Max {max_size_mb} MB allowed.") def split_video_into_chunks(video_path, chunk_duration=6, output_dir="video_chunks"): # Clear previous chunks if directory exists, then recreate if os.path.exists(output_dir): shutil.rmtree(output_dir) os.makedirs(output_dir, exist_ok=True) # Get video duration using FFprobe cmd_duration = [ "ffprobe", "-v", "error", "-show_entries", "format=duration", "-of", "default=noprint_wrappers=1:nokey=1", video_path ] try: res = subprocess.run(cmd_duration, capture_output=True, text=True, check=True) duration = float(res.stdout.strip()) except Exception as e: raise gr.Error(f"Failed to read video duration via FFprobe: {str(e)}") num_chunks = int(duration // chunk_duration) if num_chunks == 0: raise gr.Error("Video duration is shorter than the requested chunk length.") chunk_files = [] for i in range(num_chunks): start_time = i * chunk_duration output_file = os.path.join(output_dir, f"chunk_{i+1}.mp4") # Fast seek before input file command = [ "ffmpeg", "-y", "-ss", str(start_time), "-i", video_path, "-t", str(chunk_duration), "-c", "copy", output_file ] try: subprocess.run(command, capture_output=True, check=True) chunk_files.append(output_file) except subprocess.CalledProcessError as e: print(f"Error producing chunk {i+1}: {e.stderr.decode()}") return chunk_files def gradio_interface(video, chunk_duration, progress=gr.Progress(track_tqdm=True)): if video is None: raise gr.Error("Please upload a valid video file.") progress(0.1, desc="Checking video size...") check_video_size(video, max_size_mb=1000) progress(0.3, desc="Splitting video into chunks...") chunk_files = split_video_into_chunks(video, chunk_duration=chunk_duration) progress(1.0, desc="Done!") return chunk_files # Build interface using Blocks for full API compatibility in Gradio 5 with gr.Blocks(title="Video Splitter") as demo: gr.Markdown("# Video Splitter with Custom Chunk Duration") gr.Markdown("Upload a video (max 1 GB) and choose chunk duration in seconds.") with gr.Row(): with gr.Column(): video_input = gr.Video(label="Upload Video") slider_input = gr.Slider(minimum=1, maximum=60, value=6, step=1, label="Chunk Duration (seconds)") submit_btn = gr.Button("Split Video", variant="primary") with gr.Column(): files_output = gr.Files(label="Download Chunks") submit_btn.click( fn=gradio_interface, inputs=[video_input, slider_input], outputs=files_output, api_name="predict" # Guarantees explicit API route registration ) if __name__ == "__main__": demo.queue().launch(max_file_size="1000MB")