Spaces:
Sleeping
Sleeping
Download app.py from Ahmadkhan12/Video2chunks: direct link, hf CLI and curl.
- Browser
- Download file 3.24 kB
-
https://huggingface.co/spaces/Ahmadkhan12/Video2chunks/resolve/main/app.py
- Command line
-
hf download hf://spaces/Ahmadkhan12/Video2chunks/app.py
-
curl -L -o app.py https://huggingface.co/spaces/Ahmadkhan12/Video2chunks/resolve/main/app.py
3.24 kB
| 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") |