Update ui_components.py
Browse files- ui_components.py +67 -62
ui_components.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
#!/usr/bin/env python3
|
| 2 |
"""
|
| 3 |
-
|
| 4 |
-
|
| 5 |
"""
|
| 6 |
|
| 7 |
import gradio as gr
|
|
@@ -13,7 +13,7 @@
|
|
| 13 |
import traceback
|
| 14 |
from typing import Optional
|
| 15 |
|
| 16 |
-
# Import
|
| 17 |
from app import load_models_with_validation, process_video_fixed, get_model_status, get_cache_status
|
| 18 |
from utilities import PROFESSIONAL_BACKGROUNDS, create_procedural_background
|
| 19 |
|
|
@@ -106,22 +106,10 @@ def on_two_stage_change(value):
|
|
| 106 |
def get_progress_info():
|
| 107 |
"""Read progress info from temporary file"""
|
| 108 |
try:
|
| 109 |
-
with open("/tmp/
|
| 110 |
return f.read()
|
| 111 |
except:
|
| 112 |
-
return ""
|
| 113 |
-
|
| 114 |
-
# ============================================================================ #
|
| 115 |
-
# PROGRESS WRAPPER
|
| 116 |
-
# ============================================================================ #
|
| 117 |
-
def gradio_progress_wrapper(progress_obj, pct, desc):
|
| 118 |
-
"""Wrapper to safely call Gradio progress"""
|
| 119 |
-
try:
|
| 120 |
-
if progress_obj is not None:
|
| 121 |
-
progress_obj(pct, desc=desc)
|
| 122 |
-
add_debug_log(f"Progress: {pct:.1%} - {desc}")
|
| 123 |
-
except Exception:
|
| 124 |
-
pass
|
| 125 |
|
| 126 |
# ============================================================================ #
|
| 127 |
# MAIN PROCESSING FUNCTION WITH ENHANCED ERROR HANDLING
|
|
@@ -137,7 +125,7 @@ def process_video_enhanced_fixed(
|
|
| 137 |
add_debug_log("ERROR: No video file provided")
|
| 138 |
return None, "No video file provided.", get_debug_log()
|
| 139 |
|
| 140 |
-
#
|
| 141 |
add_debug_log(f"CHECKBOX RAW VALUE: use_two_stage = {use_two_stage}")
|
| 142 |
add_debug_log(f"CHECKBOX TYPE: {type(use_two_stage)}")
|
| 143 |
add_debug_log(f"CHECKBOX BOOL CONVERSION: {bool(use_two_stage)}")
|
|
@@ -146,20 +134,15 @@ def process_video_enhanced_fixed(
|
|
| 146 |
use_two_stage = bool(use_two_stage)
|
| 147 |
add_debug_log(f"FINAL use_two_stage value: {use_two_stage}")
|
| 148 |
|
| 149 |
-
# Store progress info for display
|
| 150 |
-
progress_info = {"message": "Starting..."}
|
| 151 |
-
|
| 152 |
def progress_callback(pct, desc):
|
| 153 |
-
# Update progress
|
| 154 |
-
progress_info["message"] = desc
|
| 155 |
-
# Try to update Gradio progress (percentage only)
|
| 156 |
if progress:
|
| 157 |
try:
|
| 158 |
progress(pct)
|
| 159 |
except:
|
| 160 |
pass
|
| 161 |
-
#
|
| 162 |
-
|
| 163 |
|
| 164 |
try:
|
| 165 |
# Clear old logs for new processing
|
|
@@ -173,6 +156,9 @@ def progress_callback(pct, desc):
|
|
| 173 |
mode_msg = "TWO-STAGE Green Screen" if use_two_stage else "Single-Stage"
|
| 174 |
add_debug_log(f"Processing mode: {mode_msg}")
|
| 175 |
|
|
|
|
|
|
|
|
|
|
| 176 |
if bg_method == "upload":
|
| 177 |
if custom_img and os.path.exists(custom_img):
|
| 178 |
add_debug_log(f"Using uploaded image: {custom_img}")
|
|
@@ -182,7 +168,9 @@ def progress_callback(pct, desc):
|
|
| 182 |
use_two_stage=use_two_stage,
|
| 183 |
chroma_preset=chroma_preset
|
| 184 |
)
|
| 185 |
-
|
|
|
|
|
|
|
| 186 |
return None, "No image uploaded. Please upload a background image.", get_debug_log()
|
| 187 |
|
| 188 |
elif bg_method == "professional":
|
|
@@ -194,7 +182,8 @@ def progress_callback(pct, desc):
|
|
| 194 |
use_two_stage=use_two_stage,
|
| 195 |
chroma_preset=chroma_preset
|
| 196 |
)
|
| 197 |
-
|
|
|
|
| 198 |
return None, f"Invalid professional background: {prof_choice}", get_debug_log()
|
| 199 |
|
| 200 |
elif bg_method == "colors":
|
|
@@ -221,7 +210,8 @@ def progress_callback(pct, desc):
|
|
| 221 |
use_two_stage=use_two_stage,
|
| 222 |
chroma_preset=chroma_preset
|
| 223 |
)
|
| 224 |
-
|
|
|
|
| 225 |
except Exception as e:
|
| 226 |
error_msg = f"Error creating gradient: {str(e)}"
|
| 227 |
add_debug_log(f"ERROR: {error_msg}")
|
|
@@ -236,7 +226,8 @@ def progress_callback(pct, desc):
|
|
| 236 |
use_two_stage=use_two_stage,
|
| 237 |
chroma_preset=chroma_preset
|
| 238 |
)
|
| 239 |
-
|
|
|
|
| 240 |
return None, "No AI background generated. Click 'Generate Background' first.", get_debug_log()
|
| 241 |
|
| 242 |
else:
|
|
@@ -250,13 +241,25 @@ def progress_callback(pct, desc):
|
|
| 250 |
def load_models_with_progress_fixed(progress: Optional[gr.Progress] = None):
|
| 251 |
"""Model loading with debug logging"""
|
| 252 |
def progress_callback(pct, desc):
|
| 253 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 254 |
|
| 255 |
add_debug_log("Starting model loading...")
|
| 256 |
result = load_models_with_validation(progress_callback)
|
| 257 |
add_debug_log(f"Model loading result: {result}")
|
| 258 |
return result, get_debug_log()
|
| 259 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 260 |
# ============================================================================ #
|
| 261 |
# MAIN INTERFACE CREATION WITH DEBUG PANEL
|
| 262 |
# ============================================================================ #
|
|
@@ -287,6 +290,13 @@ def create_interface():
|
|
| 287 |
border-radius: 8px;
|
| 288 |
margin: 10px 0;
|
| 289 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 290 |
"""
|
| 291 |
) as demo:
|
| 292 |
gr.Markdown("# π¬ Video Background Replacement")
|
|
@@ -407,15 +417,21 @@ def create_interface():
|
|
| 407 |
gr.Markdown("### π₯ Result")
|
| 408 |
video_output = gr.Video(label="Processed Video", height=400)
|
| 409 |
|
|
|
|
| 410 |
result_text = gr.Textbox(
|
| 411 |
-
label="Processing Info",
|
| 412 |
interactive=False,
|
| 413 |
-
lines=
|
| 414 |
-
placeholder="
|
|
|
|
| 415 |
)
|
| 416 |
|
| 417 |
-
#
|
| 418 |
-
with gr.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 419 |
debug_output = gr.Textbox(
|
| 420 |
label="Debug Output",
|
| 421 |
value=get_debug_log(),
|
|
@@ -434,29 +450,7 @@ def create_interface():
|
|
| 434 |
outputs=[status_text, debug_output]
|
| 435 |
)
|
| 436 |
|
| 437 |
-
#
|
| 438 |
-
def update_progress_display():
|
| 439 |
-
"""Update result_text with current progress"""
|
| 440 |
-
progress_info = get_progress_info()
|
| 441 |
-
if progress_info:
|
| 442 |
-
return progress_info
|
| 443 |
-
return gr.update()
|
| 444 |
-
|
| 445 |
-
# Timer that updates every second during processing
|
| 446 |
-
timer = gr.Timer(1.0, active=False)
|
| 447 |
-
timer.tick(
|
| 448 |
-
fn=update_progress_display,
|
| 449 |
-
outputs=[result_text]
|
| 450 |
-
)
|
| 451 |
-
|
| 452 |
-
# Main processing - ensure all inputs are connected
|
| 453 |
-
def process_with_timer(*args):
|
| 454 |
-
"""Wrapper to activate timer during processing"""
|
| 455 |
-
timer.active = True
|
| 456 |
-
result = process_video_enhanced_fixed(*args)
|
| 457 |
-
timer.active = False
|
| 458 |
-
return result
|
| 459 |
-
|
| 460 |
process_btn.click(
|
| 461 |
fn=process_video_enhanced_fixed,
|
| 462 |
inputs=[
|
|
@@ -472,13 +466,19 @@ def process_with_timer(*args):
|
|
| 472 |
ai_prompt, # ai_prompt
|
| 473 |
ai_style, # ai_style
|
| 474 |
ai_generated_image, # ai_img
|
| 475 |
-
use_two_stage, # use_two_stage
|
| 476 |
chroma_preset # chroma_preset
|
| 477 |
],
|
| 478 |
outputs=[video_output, result_text, debug_output],
|
| 479 |
show_progress=True
|
| 480 |
)
|
| 481 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 482 |
# Debug controls
|
| 483 |
refresh_debug_btn.click(
|
| 484 |
fn=get_debug_log,
|
|
@@ -497,10 +497,15 @@ def process_with_timer(*args):
|
|
| 497 |
- **Single-Stage**: Fast, good quality for most videos
|
| 498 |
- **Two-Stage**: Slower but cinema-quality edges using green screen
|
| 499 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 500 |
### Tips:
|
| 501 |
-
- Start with
|
| 502 |
- Two-stage mode works best with clear subjects
|
| 503 |
-
-
|
| 504 |
""")
|
| 505 |
|
| 506 |
return demo
|
|
|
|
| 1 |
#!/usr/bin/env python3
|
| 2 |
"""
|
| 3 |
+
Final UI Components for Video Background Replacement
|
| 4 |
+
Removed non-working timer code, kept progress display functionality
|
| 5 |
"""
|
| 6 |
|
| 7 |
import gradio as gr
|
|
|
|
| 13 |
import traceback
|
| 14 |
from typing import Optional
|
| 15 |
|
| 16 |
+
# Import core processing functions
|
| 17 |
from app import load_models_with_validation, process_video_fixed, get_model_status, get_cache_status
|
| 18 |
from utilities import PROFESSIONAL_BACKGROUNDS, create_procedural_background
|
| 19 |
|
|
|
|
| 106 |
def get_progress_info():
|
| 107 |
"""Read progress info from temporary file"""
|
| 108 |
try:
|
| 109 |
+
with open("/tmp/processing_info.txt", 'r') as f:
|
| 110 |
return f.read()
|
| 111 |
except:
|
| 112 |
+
return "Processing..."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 113 |
|
| 114 |
# ============================================================================ #
|
| 115 |
# MAIN PROCESSING FUNCTION WITH ENHANCED ERROR HANDLING
|
|
|
|
| 125 |
add_debug_log("ERROR: No video file provided")
|
| 126 |
return None, "No video file provided.", get_debug_log()
|
| 127 |
|
| 128 |
+
# Log checkbox value for debugging
|
| 129 |
add_debug_log(f"CHECKBOX RAW VALUE: use_two_stage = {use_two_stage}")
|
| 130 |
add_debug_log(f"CHECKBOX TYPE: {type(use_two_stage)}")
|
| 131 |
add_debug_log(f"CHECKBOX BOOL CONVERSION: {bool(use_two_stage)}")
|
|
|
|
| 134 |
use_two_stage = bool(use_two_stage)
|
| 135 |
add_debug_log(f"FINAL use_two_stage value: {use_two_stage}")
|
| 136 |
|
|
|
|
|
|
|
|
|
|
| 137 |
def progress_callback(pct, desc):
|
| 138 |
+
# Update Gradio progress bar
|
|
|
|
|
|
|
| 139 |
if progress:
|
| 140 |
try:
|
| 141 |
progress(pct)
|
| 142 |
except:
|
| 143 |
pass
|
| 144 |
+
# Log progress
|
| 145 |
+
add_debug_log(f"Progress: {pct:.1%} - {desc}")
|
| 146 |
|
| 147 |
try:
|
| 148 |
# Clear old logs for new processing
|
|
|
|
| 156 |
mode_msg = "TWO-STAGE Green Screen" if use_two_stage else "Single-Stage"
|
| 157 |
add_debug_log(f"Processing mode: {mode_msg}")
|
| 158 |
|
| 159 |
+
# Initial status for Processing Info box
|
| 160 |
+
initial_status = "π¬ PROCESSING STARTED\nβββββββββββββββββββ\nβ³ Initializing...\nPlease wait..."
|
| 161 |
+
|
| 162 |
if bg_method == "upload":
|
| 163 |
if custom_img and os.path.exists(custom_img):
|
| 164 |
add_debug_log(f"Using uploaded image: {custom_img}")
|
|
|
|
| 168 |
use_two_stage=use_two_stage,
|
| 169 |
chroma_preset=chroma_preset
|
| 170 |
)
|
| 171 |
+
# Check for progress info file to display
|
| 172 |
+
final_info = get_progress_info()
|
| 173 |
+
return result[0], result[1] if result[1] else final_info, get_debug_log()
|
| 174 |
return None, "No image uploaded. Please upload a background image.", get_debug_log()
|
| 175 |
|
| 176 |
elif bg_method == "professional":
|
|
|
|
| 182 |
use_two_stage=use_two_stage,
|
| 183 |
chroma_preset=chroma_preset
|
| 184 |
)
|
| 185 |
+
final_info = get_progress_info()
|
| 186 |
+
return result[0], result[1] if result[1] else final_info, get_debug_log()
|
| 187 |
return None, f"Invalid professional background: {prof_choice}", get_debug_log()
|
| 188 |
|
| 189 |
elif bg_method == "colors":
|
|
|
|
| 210 |
use_two_stage=use_two_stage,
|
| 211 |
chroma_preset=chroma_preset
|
| 212 |
)
|
| 213 |
+
final_info = get_progress_info()
|
| 214 |
+
return result[0], result[1] if result[1] else final_info, get_debug_log()
|
| 215 |
except Exception as e:
|
| 216 |
error_msg = f"Error creating gradient: {str(e)}"
|
| 217 |
add_debug_log(f"ERROR: {error_msg}")
|
|
|
|
| 226 |
use_two_stage=use_two_stage,
|
| 227 |
chroma_preset=chroma_preset
|
| 228 |
)
|
| 229 |
+
final_info = get_progress_info()
|
| 230 |
+
return result[0], result[1] if result[1] else final_info, get_debug_log()
|
| 231 |
return None, "No AI background generated. Click 'Generate Background' first.", get_debug_log()
|
| 232 |
|
| 233 |
else:
|
|
|
|
| 241 |
def load_models_with_progress_fixed(progress: Optional[gr.Progress] = None):
|
| 242 |
"""Model loading with debug logging"""
|
| 243 |
def progress_callback(pct, desc):
|
| 244 |
+
if progress:
|
| 245 |
+
try:
|
| 246 |
+
progress(pct)
|
| 247 |
+
except:
|
| 248 |
+
pass
|
| 249 |
+
add_debug_log(f"Model loading: {pct:.1%} - {desc}")
|
| 250 |
|
| 251 |
add_debug_log("Starting model loading...")
|
| 252 |
result = load_models_with_validation(progress_callback)
|
| 253 |
add_debug_log(f"Model loading result: {result}")
|
| 254 |
return result, get_debug_log()
|
| 255 |
|
| 256 |
+
# ============================================================================ #
|
| 257 |
+
# REFRESH PROCESSING INFO
|
| 258 |
+
# ============================================================================ #
|
| 259 |
+
def refresh_processing_info():
|
| 260 |
+
"""Refresh the processing info display"""
|
| 261 |
+
return get_progress_info()
|
| 262 |
+
|
| 263 |
# ============================================================================ #
|
| 264 |
# MAIN INTERFACE CREATION WITH DEBUG PANEL
|
| 265 |
# ============================================================================ #
|
|
|
|
| 290 |
border-radius: 8px;
|
| 291 |
margin: 10px 0;
|
| 292 |
}
|
| 293 |
+
.processing-info-box {
|
| 294 |
+
font-family: monospace;
|
| 295 |
+
background: #f0f0f0;
|
| 296 |
+
border: 2px solid #3498db;
|
| 297 |
+
border-radius: 8px;
|
| 298 |
+
padding: 12px;
|
| 299 |
+
}
|
| 300 |
"""
|
| 301 |
) as demo:
|
| 302 |
gr.Markdown("# π¬ Video Background Replacement")
|
|
|
|
| 417 |
gr.Markdown("### π₯ Result")
|
| 418 |
video_output = gr.Video(label="Processed Video", height=400)
|
| 419 |
|
| 420 |
+
# Processing Info box with better styling
|
| 421 |
result_text = gr.Textbox(
|
| 422 |
+
label="π Processing Info",
|
| 423 |
interactive=False,
|
| 424 |
+
lines=10,
|
| 425 |
+
placeholder="Processing statistics will appear here...\n\nWhen processing starts, you'll see:\nβ’ Frame count\nβ’ Processing speed (fps)\nβ’ Time elapsed\nβ’ ETA\n\nFinal results will show total time and performance stats.",
|
| 426 |
+
elem_classes=["processing-info-box"]
|
| 427 |
)
|
| 428 |
|
| 429 |
+
# Manual refresh button for processing info
|
| 430 |
+
with gr.Row():
|
| 431 |
+
refresh_info_btn = gr.Button("π Refresh Progress", size="sm", visible=False)
|
| 432 |
+
|
| 433 |
+
# Debug panel - can be closed
|
| 434 |
+
with gr.Accordion("π§ Debug Log", open=False):
|
| 435 |
debug_output = gr.Textbox(
|
| 436 |
label="Debug Output",
|
| 437 |
value=get_debug_log(),
|
|
|
|
| 450 |
outputs=[status_text, debug_output]
|
| 451 |
)
|
| 452 |
|
| 453 |
+
# Main processing
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 454 |
process_btn.click(
|
| 455 |
fn=process_video_enhanced_fixed,
|
| 456 |
inputs=[
|
|
|
|
| 466 |
ai_prompt, # ai_prompt
|
| 467 |
ai_style, # ai_style
|
| 468 |
ai_generated_image, # ai_img
|
| 469 |
+
use_two_stage, # use_two_stage
|
| 470 |
chroma_preset # chroma_preset
|
| 471 |
],
|
| 472 |
outputs=[video_output, result_text, debug_output],
|
| 473 |
show_progress=True
|
| 474 |
)
|
| 475 |
|
| 476 |
+
# Refresh processing info manually
|
| 477 |
+
refresh_info_btn.click(
|
| 478 |
+
fn=refresh_processing_info,
|
| 479 |
+
outputs=[result_text]
|
| 480 |
+
)
|
| 481 |
+
|
| 482 |
# Debug controls
|
| 483 |
refresh_debug_btn.click(
|
| 484 |
fn=get_debug_log,
|
|
|
|
| 497 |
- **Single-Stage**: Fast, good quality for most videos
|
| 498 |
- **Two-Stage**: Slower but cinema-quality edges using green screen
|
| 499 |
|
| 500 |
+
### Performance:
|
| 501 |
+
- **720p videos**: ~2-3 fps processing speed
|
| 502 |
+
- **1080p videos**: ~1-2 fps processing speed
|
| 503 |
+
- **1-minute video**: Takes approximately 5-10 minutes
|
| 504 |
+
|
| 505 |
### Tips:
|
| 506 |
+
- Start with shorter clips (10-30 seconds) for testing
|
| 507 |
- Two-stage mode works best with clear subjects
|
| 508 |
+
- Check debug log if issues occur
|
| 509 |
""")
|
| 510 |
|
| 511 |
return demo
|