File size: 5,289 Bytes
0022b73
 
 
 
940e9ee
 
0022b73
4053aa4
 
 
940e9ee
4053aa4
940e9ee
4053aa4
 
 
 
 
4164ab4
940e9ee
4053aa4
 
4164ab4
0022b73
 
4164ab4
 
 
 
 
a21271c
 
0022b73
 
 
 
4164ab4
 
0022b73
940e9ee
4164ab4
940e9ee
 
0022b73
4164ab4
 
0022b73
940e9ee
0022b73
 
940e9ee
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0022b73
940e9ee
0022b73
 
 
 
 
 
 
940e9ee
 
 
a6b40d2
0022b73
 
 
 
4164ab4
0022b73
940e9ee
4164ab4
b63d96a
 
940e9ee
4164ab4
0022b73
 
4164ab4
 
0022b73
 
4cd4045
 
 
 
4164ab4
0022b73
 
 
4164ab4
 
0022b73
 
 
4164ab4
 
0022b73
 
 
 
4164ab4
0022b73
940e9ee
0022b73
 
4164ab4
0022b73
4164ab4
0022b73
 
940e9ee
0022b73
 
 
940e9ee
4164ab4
0022b73
 
 
 
 
 
 
 
 
 
 
4164ab4
0022b73
 
 
 
 
9550f41
 
f468048
9550f41
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
144
145
146
147
148
149
150
151
152
153
154
155
import gradio as gr
import subprocess
import os
import spaces
import inference_video_w
import torch

# Download the file
subprocess.run([
    "wget",
    "https://huggingface.co/r3gm/RIFE/resolve/main/RIFEv4.26_0921.zip",
    "-O",
    "RIFEv4.26_0921.zip"
], check=True)

# Unzip the downloaded file
subprocess.run([
    "unzip",
    "-o", 
    "RIFEv4.26_0921.zip"
], check=True)

@spaces.GPU(duration=120)
def run_rife(
    input_video, 
    frame_multiplier, 
    time_exponent, 
    fixed_fps, 
    video_scale, 
    remove_duplicate_frames, 
    create_montage,
    progress=gr.Progress(track_tqdm=True),
):
    if input_video is None:
        raise gr.Error("Please upload a video first.")

    ext = "mp4"
    model_dir = "train_log"
    
    # Construct output filename pattern to match what inference_video.py expects/generates
    video_path_wo_ext = os.path.splitext(os.path.basename(input_video))[0]
    # We pass the desired output name, though the function logic tries to stick to this pattern anyway
    output_base_name = "{}_{}X_fps.{}".format(video_path_wo_ext, int(frame_multiplier), ext)
    
    if fixed_fps > 0:
        gr.Warning("Will not merge audio because using fps flag!")

    print(f"Starting Inference for: {input_video}")

    try:
        # Call the imported function directly
        result_path = inference_video_w.inference(
            video=input_video,
            output=output_base_name,
            modelDir=model_dir,
            fp16=(True if torch.cuda.is_available() else False),
            UHD=False,
            scale=video_scale,
            skip=remove_duplicate_frames,
            fps=int(fixed_fps) if fixed_fps > 0 else None,
            ext=ext,
            exp=int(time_exponent),
            multi=int(frame_multiplier),
            montage=create_montage
        )

        if result_path and os.path.exists(result_path):
            return result_path
        else:
            raise gr.Error(f"Output file not found. Expected: {result_path}")

    except Exception as e:
        raise gr.Error(f"An error occurred: {str(e)}")


# --- Gradio UI Layout ---

with gr.Blocks(title="Frame Rate Enhancer") as app:
    gr.Markdown("# ⚡ RIFE: Frame Rate Enhancer")
    gr.Markdown("Creates extra frames between the original ones to make motion in your videos smoother and more fluid.")
    gr.Markdown("⚠️ **Notice:** Keep input videos under 60 seconds for frame interpolation to prevent GPU task aborts.")

    with gr.Row():
        # --- Left Column: Inputs & Settings ---
        with gr.Column(scale=1):
            input_vid = gr.Video(label="🎬 Input Source Video", sources=["upload"])
            
            with gr.Group():                
                multi_param = gr.Dropdown(
                    choices=[2, 3, 4, 5, 6], 
                    value=2, 
                    label="🗃️ Frame Multiplier",
                    info="2X = Double FPS (e.g. 30 -> 60). Higher multipliers create more intermediate frames."
                )

            with gr.Accordion("🛠️ Advanced Configuration", open=False):
                gr.Markdown("Control rendering parameters.")
                
                with gr.Row():
                    scale_param = gr.Dropdown(
                        choices=[0.25, 0.5, 1.0, 2.0, 4.0],
                        value=1.0,
                        label="📉 Render Scale",
                        info="1.0 = Original Resolution. Reduce to 0.5 for faster processing on 4K content."
                    )
                    fps_param = gr.Number(
                        value=0, 
                        label="🎯 Force Output FPS", 
                        info="0 = Auto-calculate. Set to 30 or 60 to lock the framerate. Audio will be removed when forcing FPS"
                    )
                    exp_param = gr.Number(
                        value=1, 
                        label="🔢 Exponent Power", 
                        info="Alternative multiplier calculation (2^exp)."
                    )

                with gr.Row():
                    skip_chk = gr.Checkbox(
                        label="⏩ Skip Static Frames", 
                        value=False,
                        info="Bypass processing for static frames to save time."
                    )
                    montage_chk = gr.Checkbox(
                        label="🆚 Split-Screen Comparison", 
                        value=False,
                        info="Output video showing Original vs. Processed."
                    )

            btn_run = gr.Button("GENERATE INTERMEDIATE FRAMES", variant="primary", size="lg")

        # --- Right Column: Output ---
        with gr.Column(scale=1):
            output_vid = gr.Video(label="INTERPOLATED RESULT")
            gr.Markdown("**Status:** Rendering time depends on input resolution and duration.")

    # --- Bind Logic ---
    btn_run.click(
        fn=run_rife,
        inputs=[
            input_vid, 
            multi_param, 
            exp_param, 
            fps_param, 
            scale_param, 
            skip_chk, 
            montage_chk
        ],
        outputs=output_vid
    )

if __name__ == "__main__":
    app.launch(
        theme=gr.themes.Soft(),
        mcp_server=True,
    )