Video2chunks / app.py
Ahmadkhan12's picture
Update app.py
b6bb842 verified
Raw History Blame Contribute Delete
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")