1inkusFace commited on
Commit
8cfd70e
·
verified ·
1 Parent(s): b5d6022

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +183 -0
app.py ADDED
@@ -0,0 +1,183 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+ import shutil
4
+ import subprocess
5
+ import glob
6
+ import importlib.util
7
+ import gradio as gr
8
+
9
+ # --- Constants ---
10
+ BASE_DIR = os.getcwd()
11
+ RIFE_DIR = os.path.join(BASE_DIR, "Practical-RIFE")
12
+ MODEL_URL = "https://huggingface.co/hzwer/RIFE/resolve/main/RIFEv4.26_0921.zip"
13
+
14
+ def run_command(command):
15
+ """Helper to run shell commands"""
16
+ subprocess.run(command, shell=True, check=True)
17
+
18
+ def setup_environment():
19
+ """
20
+ 1. Clones the RIFE repo.
21
+ 2. Downloads weights.
22
+ 3. Re-organizes folders (User's Fix).
23
+ 4. Patches scikit-video.
24
+ """
25
+ print("--- Starting Environment Setup ---")
26
+
27
+ # 1. Clone Repo if not exists
28
+ if not os.path.exists(RIFE_DIR):
29
+ print("Cloning Practical-RIFE...")
30
+ run_command(f"git clone https://github.com/hzwer/Practical-RIFE {RIFE_DIR}")
31
+
32
+ # 2. Download and Organize Weights
33
+ # We check if 'HDv3' exists to avoid re-downloading on restart
34
+ if not os.path.exists(os.path.join(RIFE_DIR, "HDv3")):
35
+ print("Downloading RIFE v4.26 model weights...")
36
+ zip_path = os.path.join(RIFE_DIR, "RIFEv4.26_0921.zip")
37
+
38
+ # Download
39
+ run_command(f"wget -O {zip_path} {MODEL_URL}")
40
+
41
+ # Unzip
42
+ print("Unzipping...")
43
+ run_command(f"unzip -o {zip_path} -d {RIFE_DIR}")
44
+
45
+ # --- APPLY USER'S DIRECTORY FIX ---
46
+ print("Applying directory structure fix...")
47
+
48
+ # Create train_log
49
+ train_log_dir = os.path.join(RIFE_DIR, "train_log")
50
+ os.makedirs(train_log_dir, exist_ok=True)
51
+
52
+ # Move Python files
53
+ extract_folder = os.path.join(RIFE_DIR, "RIFEv4.26_0921")
54
+ shutil.move(os.path.join(extract_folder, "RIFE_HDv3.py"), train_log_dir)
55
+ shutil.move(os.path.join(extract_folder, "IFNet_HDv3.py"), train_log_dir)
56
+
57
+ # Create __init__.py
58
+ with open(os.path.join(train_log_dir, "__init__.py"), 'w') as f:
59
+ pass
60
+
61
+ # Create HDv3 and move weights
62
+ hdv3_dir = os.path.join(RIFE_DIR, "HDv3")
63
+ os.makedirs(hdv3_dir, exist_ok=True)
64
+ shutil.move(os.path.join(extract_folder, "flownet.pkl"), hdv3_dir)
65
+
66
+ # Cleanup
67
+ shutil.rmtree(extract_folder)
68
+ if os.path.exists(zip_path):
69
+ os.remove(zip_path)
70
+
71
+ print("Files moved and directories created.")
72
+
73
+ # 3. Patch skvideo (The numpy fix)
74
+ print("Checking skvideo for necessary patches...")
75
+ try:
76
+ spec = importlib.util.find_spec('skvideo.io.abstract')
77
+ if spec and spec.origin:
78
+ abstract_path = spec.origin
79
+
80
+ # Read file to see if patching is needed
81
+ with open(abstract_path, 'r') as f:
82
+ content = f.read()
83
+
84
+ if 'np.float' in content or 'np.int' in content:
85
+ print(f"Patching {abstract_path}...")
86
+ run_command(f"sed -i 's/np.float/float/g' {abstract_path}")
87
+ run_command(f"sed -i 's/np.int/int/g' {abstract_path}")
88
+ print("skvideo patched.")
89
+ else:
90
+ print("skvideo already patched or compatible.")
91
+ except Exception as e:
92
+ print(f"Warning: Could not patch skvideo: {e}")
93
+
94
+ # 4. Patch inference_video.py for libx264
95
+ inference_script = os.path.join(RIFE_DIR, "inference_video.py")
96
+ if os.path.exists(inference_script):
97
+ # Read to check if already patched
98
+ with open(inference_script, 'r') as f:
99
+ script_content = f.read()
100
+
101
+ if "libx264" not in script_content:
102
+ print("Patching inference_video.py for libx264...")
103
+ # Replicating the sed command using python replace for safety
104
+ new_content = script_content.replace(
105
+ "-c:v', 'mpeg4', '-qscale:v', '1'",
106
+ "-c:v', 'libx264', '-preset', 'medium', '-crf', '23'"
107
+ )
108
+ with open(inference_script, 'w') as f:
109
+ f.write(new_content)
110
+
111
+ print("--- Setup Complete ---")
112
+
113
+ # Run Setup immediately upon app launch
114
+ setup_environment()
115
+
116
+ def interpolate_video(input_video_path):
117
+ if input_video_path is None:
118
+ return None
119
+
120
+ print(f"Processing video: {input_video_path}")
121
+
122
+ output_path = os.path.join(BASE_DIR, "output_rife.mp4")
123
+ final_output_path = os.path.join(BASE_DIR, "final_output.mp4")
124
+
125
+ # Clean up previous runs
126
+ if os.path.exists(output_path): os.remove(output_path)
127
+ if os.path.exists(final_output_path): os.remove(final_output_path)
128
+
129
+ # Change dir to RIFE for execution
130
+ os.chdir(RIFE_DIR)
131
+
132
+ try:
133
+ # Run RIFE inference
134
+ # Note: --multi 4 means 4x interpolation (e.g. 30fps -> 120fps)
135
+ cmd = [
136
+ 'python3', 'inference_video.py',
137
+ '--video', input_video_path,
138
+ '--output', output_path,
139
+ '--multi', '4',
140
+ '--model', 'HDv3'
141
+ ]
142
+ subprocess.run(cmd, check=True)
143
+
144
+ # Post-process for Web Compatibility (Faststart + h264)
145
+ if os.path.exists(output_path):
146
+ print("Re-encoding for web compatibility...")
147
+ ffmpeg_cmd = [
148
+ 'ffmpeg', '-i', output_path,
149
+ '-c:v', 'libx264',
150
+ '-pix_fmt', 'yuv420p',
151
+ '-preset', 'medium',
152
+ '-crf', '23',
153
+ '-movflags', '+faststart',
154
+ '-y', final_output_path
155
+ ]
156
+ subprocess.run(ffmpeg_cmd, check=True)
157
+
158
+ return final_output_path
159
+ else:
160
+ return None
161
+
162
+ except Exception as e:
163
+ print(f"Error during inference: {e}")
164
+ return None
165
+ finally:
166
+ # Reset directory
167
+ os.chdir(BASE_DIR)
168
+
169
+ # --- Gradio Interface ---
170
+ with gr.Blocks() as demo:
171
+ gr.Markdown("# 🎞️ RIFE Video Interpolation (v4.26)")
172
+ gr.Markdown("Upload a video to smoothen it (4X Frame Interpolation). **Note:** This process is slow on CPU. Using a GPU Space is recommended.")
173
+
174
+ with gr.Row():
175
+ with gr.Column():
176
+ video_input = gr.Video(label="Input Video")
177
+ submit_btn = gr.Button("Interpolate Frames", variant="primary")
178
+ with gr.Column():
179
+ video_output = gr.Video(label="Smoothed Output")
180
+
181
+ submit_btn.click(fn=interpolate_video, inputs=video_input, outputs=video_output)
182
+
183
+ demo.launch()