File size: 4,826 Bytes
041f44a 8452106 041f44a f539c08 041f44a 8452106 07b80ba 041f44a ae466e9 07b80ba 6948822 041f44a 07b80ba ae466e9 041f44a 6948822 041f44a 07b80ba ae466e9 041f44a 6948822 041f44a 83e05ff 041f44a c9eaf40 041f44a 83e05ff 041f44a ba4f990 041f44a ba4f990 041f44a 1ada4e6 ba4f990 1ada4e6 ba4f990 3c9c28b c9eaf40 ba4f990 3c9c28b ba4f990 c9eaf40 3c9c28b c9eaf40 3c9c28b 041f44a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | import os
import shutil
import cv2
import spaces
import gradio as gr
from handlers import frame_handler_yolo as fh
from handlers import video_handler as vh
model_path = "yolov8n.pt" # YOLOv8 model path
@spaces.GPU(duration=150)
def process_video(video_file):
"""
Processes the uploaded video file by extracting key frames, cropping them, and generating a processed video.
"""
status_message = "Processing started..."
# Define output directories
output_folder = "output_data"
all_frames_folder = os.path.join(output_folder, "all_frames")
key_frames_folder = os.path.join(output_folder, "key_frames")
nonkey_frames_folder = os.path.join(output_folder, "nonkey_frames")
cropped_frames_folder = os.path.join(output_folder, "cropped_frames")
processed_video_path = os.path.join(output_folder, "processed_video.mp4")
print("Calling process_video function: Output folder:", output_folder)
# Clear output directory before processing
if os.path.exists(output_folder):
shutil.rmtree(output_folder)
os.makedirs(output_folder, exist_ok=True)
# Save uploaded video temporarily
video_path = os.path.join(output_folder, "input_video.mp4")
with open(video_file.name, "rb") as vf:
with open(video_path, "wb") as f:
f.write(vf.read())
video = cv2.VideoCapture(video_path)
# Check if the video is opened successfully
if not video.isOpened():
print(f"Error: Cannot open video file {video_path}")
return
# Get video properties
original_fps = int(video.get(cv2.CAP_PROP_FPS)) # Frames per second
video.release()
# Step 1: Extract all frames
status_message = "Extracting frames. Please wait...!"
yield status_message, None
vh.extract_frames_by_rate(video_path, all_frames_folder, original_fps)
# Step 2 - extract key frames
status_message = "Extracting key frames. Please wait...!"
yield status_message, None
fh.extract_key_frames(all_frames_folder, key_frames_folder, original_fps, model_path)
# Step 3 - cropping key frames while reserving key objects
status_message = "Cropping key frames. Please wait...!"
yield status_message, None
target_resolution = (360, 640) # Output resolution (9:16)
fh.crop_preserve_key_objects(key_frames_folder, cropped_frames_folder, model_path, target_resolution)
status_message = "Generating final video. Please wait...!"
yield status_message, None
# Step 4: Generate short video
target_frame_rate = 24 # standard frame per second is 24
vh.create_video_from_frames(cropped_frames_folder, processed_video_path, target_frame_rate, target_resolution)
status_message = "Processing complete!"
yield status_message, processed_video_path
# Gradio Blocks UI
with gr.Blocks() as demo:
gr.Markdown("## Generate short video for your football match")
gr.Markdown("Upload a video file. The app will extract key frames, crop them to fix 9:16 aspect ratio, "
"and generate a short video.")
gr.Markdown("Test data is auto loaded. Just click Proceed video button to see the result. Click x to upload your "
"own video file")
with gr.Row():
with gr.Column():
video_input = gr.File(label="Upload Video", type="filepath", file_types=["video"], file_count="single"
, height=145)
with gr.Column():
process_button = gr.Button("Process Video", variant="primary")
status_output = gr.Textbox(label="Status", interactive=False)
with gr.Row():
with gr.Column():
input_video_preview = gr.Video(label="Input Video (16:9) Preview", width=640, height=360)
with gr.Column():
video_output = gr.Video(label="Short Video (9:16) Generated", width=360, height=640)
def update_preview(video_path):
if video_path is None:
return None
return video_path
video_input.change(
fn=update_preview,
inputs=video_input,
outputs=input_video_preview
)
def update_preview(video_path):
if video_path is None:
return None
return video_path
video_input.change(
fn=update_preview,
inputs=video_input,
outputs=input_video_preview
)
# Set default video input and update the preview when app launches
def set_default_video():
default_video_path = "./input_data/football.mp4"
return default_video_path, default_video_path
demo.load(
fn=set_default_video,
inputs=[],
outputs=[video_input, input_video_preview]
)
process_button.click(process_video, inputs=video_input, outputs=[status_output, video_output])
if __name__ == "__main__":
demo.launch()
|