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()