MogensR commited on
Commit
8299fd5
·
verified ·
1 Parent(s): f56676e

Update streamlit_app.py

Browse files
Files changed (1) hide show
  1. streamlit_app.py +61 -32
streamlit_app.py CHANGED
@@ -11,6 +11,7 @@
11
  import traceback
12
  import uuid
13
  from tempfile import NamedTemporaryFile
 
14
  import streamlit as st
15
 
16
  from ui import render_ui
@@ -21,6 +22,7 @@
21
  check_gpu
22
  )
23
  from models.model_loaders import load_sam2, load_matanyone
 
24
 
25
  APP_NAME = "Advanced Video Background Replacer"
26
  LOG_FILE = "/tmp/app.log"
@@ -31,7 +33,6 @@ def setup_logging(level: int = logging.INFO) -> logging.Logger:
31
  logger = logging.getLogger(APP_NAME)
32
  logger.setLevel(level)
33
  logger.propagate = False
34
- # Remove previous handlers (Streamlit reruns)
35
  for h in list(logger.handlers):
36
  logger.removeHandler(h)
37
  ch = logging.StreamHandler(sys.stdout)
@@ -52,7 +53,6 @@ def custom_excepthook(type, value, tb):
52
  logger.error(f"Unhandled: {type.__name__}: {value}\n{''.join(traceback.format_tb(tb))}", exc_info=True)
53
  sys.excepthook = custom_excepthook
54
 
55
- # Only load once
56
  sam2_predictor = load_sam2()
57
  matanyone_processor = load_matanyone()
58
 
@@ -83,19 +83,17 @@ def initialize_session_state():
83
  if st.session_state.gpu_available is None:
84
  st.session_state.gpu_available = check_gpu(logger)
85
 
86
- def process_video(uploaded_video, background, bg_type, progress_callback=None):
 
87
  run_id = uuid.uuid4().hex[:8]
88
  logger.info("=" * 80)
89
  logger.info(f"[RUN {run_id}] VIDEO PROCESSING STARTED at {time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime())}")
90
- logger.info(f"[RUN {run_id}] Video size={len(uploaded_video.read()) / 1e6:.2f}MB, BG type={bg_type}")
91
- uploaded_video.seek(0)
92
- st.session_state.processing = True
93
- st.session_state.processed_video_bytes = None
94
- st.session_state.last_error = None
95
  t0 = time.time()
96
  try:
97
- if progress_callback:
98
- progress_callback("📥 Uploading video...")
 
99
  suffix = Path(uploaded_video.name).suffix or ".mp4"
100
  with NamedTemporaryFile(delete=False, suffix=suffix) as tmp_vid:
101
  uploaded_video.seek(0)
@@ -103,49 +101,81 @@ def process_video(uploaded_video, background, bg_type, progress_callback=None):
103
  tmp_vid_path = tmp_vid.name
104
  logger.info(f"[RUN {run_id}] Temporary video path: {tmp_vid_path}")
105
 
106
- if progress_callback:
107
- progress_callback("🚀 Stage 1: Creating transparent video (matting & segmentation)...")
108
- # >>> CHANGE: pass a short watchdog timeout so hangs surface quickly
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
  transparent_path, audio_path = stage1_create_transparent_video(
110
  tmp_vid_path,
111
  sam2_predictor=sam2_predictor,
112
  matanyone_processor=matanyone_processor,
113
- mat_timeout_sec=300
 
114
  )
 
115
  if not transparent_path or not os.path.exists(transparent_path):
116
  raise RuntimeError("Stage 1 failed: Transparent video not created")
117
- logger.info(f"[RUN {run_id}] Stage 1 completed: Transparent path={transparent_path}, Audio path={audio_path}")
118
 
119
- if progress_callback:
120
- progress_callback("🎨 Stage 2: Compositing with background and restoring audio...")
121
  final_path = stage2_composite_background(
122
  transparent_path,
123
  audio_path,
124
  background,
125
- bg_type.lower()
 
126
  )
 
127
  if not final_path or not os.path.exists(final_path):
128
  raise RuntimeError("Stage 2 failed: Final video not created")
129
- logger.info(f"[RUN {run_id}] Stage 2 completed: Final path={final_path}")
130
 
131
- if progress_callback:
132
- progress_callback("📤 Loading final video for download...")
133
  with open(final_path, 'rb') as f:
134
  st.session_state.processed_video_bytes = f.read()
 
135
  total = time.time() - t0
136
- logger.info(f"[RUN {run_id}] SUCCESS size={len(st.session_state.processed_video_bytes)/1e6:.2f}MB, total Δ={total:.2f}s")
137
- if progress_callback:
138
- progress_callback("✅ All done!")
139
- return True
140
  except Exception as e:
141
  total = time.time() - t0
142
- error_msg = f"[RUN {run_id}] Processing Error: {str(e)} (Δ {total:.2f}s)\n\nCheck logs for details."
143
  logger.error(error_msg)
144
  logger.error(traceback.format_exc())
145
  st.session_state.last_error = error_msg
146
- if progress_callback:
147
- progress_callback(f"❌ ERROR: {str(e)}")
148
- return False
149
  finally:
150
  st.session_state.processing = False
151
  logger.info(f"[RUN {run_id}] Processing finished")
@@ -159,12 +189,11 @@ def main():
159
  initial_sidebar_state="expanded"
160
  )
161
  initialize_session_state()
162
- render_ui(process_video)
163
  except Exception as e:
164
  logger.error(f"Main app error: {e}", exc_info=True)
165
  st.error(f"App startup failed: {str(e)}. Check logs for details.")
166
 
167
  if __name__ == "__main__":
168
  setup_t4_environment()
169
- main()
170
-
 
11
  import traceback
12
  import uuid
13
  from tempfile import NamedTemporaryFile
14
+ import threading
15
  import streamlit as st
16
 
17
  from ui import render_ui
 
22
  check_gpu
23
  )
24
  from models.model_loaders import load_sam2, load_matanyone
25
+ from utils.progress_tracker import init_progress, update_progress, mark_complete, get_progress
26
 
27
  APP_NAME = "Advanced Video Background Replacer"
28
  LOG_FILE = "/tmp/app.log"
 
33
  logger = logging.getLogger(APP_NAME)
34
  logger.setLevel(level)
35
  logger.propagate = False
 
36
  for h in list(logger.handlers):
37
  logger.removeHandler(h)
38
  ch = logging.StreamHandler(sys.stdout)
 
53
  logger.error(f"Unhandled: {type.__name__}: {value}\n{''.join(traceback.format_tb(tb))}", exc_info=True)
54
  sys.excepthook = custom_excepthook
55
 
 
56
  sam2_predictor = load_sam2()
57
  matanyone_processor = load_matanyone()
58
 
 
83
  if st.session_state.gpu_available is None:
84
  st.session_state.gpu_available = check_gpu(logger)
85
 
86
+ def process_video_background(uploaded_video, background, bg_type):
87
+ """Background thread for video processing"""
88
  run_id = uuid.uuid4().hex[:8]
89
  logger.info("=" * 80)
90
  logger.info(f"[RUN {run_id}] VIDEO PROCESSING STARTED at {time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime())}")
91
+
 
 
 
 
92
  t0 = time.time()
93
  try:
94
+ init_progress()
95
+ update_progress("Starting video processing...", 0, "Initialization")
96
+
97
  suffix = Path(uploaded_video.name).suffix or ".mp4"
98
  with NamedTemporaryFile(delete=False, suffix=suffix) as tmp_vid:
99
  uploaded_video.seek(0)
 
101
  tmp_vid_path = tmp_vid.name
102
  logger.info(f"[RUN {run_id}] Temporary video path: {tmp_vid_path}")
103
 
104
+ def progress_cb(msg):
105
+ # Map messages to progress percentages and stages
106
+ progress = 0
107
+ stage = "Processing"
108
+
109
+ if "Stage 1 initiated" in msg:
110
+ progress, stage = 5, "Stage 1"
111
+ elif "GPU engaged" in msg:
112
+ progress, stage = 10, "Stage 1 - SAM2"
113
+ elif "SAM2 processing frame" in msg:
114
+ progress, stage = 15, "Stage 1 - SAM2"
115
+ elif "SAM2 complete" in msg:
116
+ progress, stage = 25, "Stage 1 - SAM2"
117
+ elif "MatAnyone starting" in msg:
118
+ progress, stage = 30, "Stage 1 - MatAnyone"
119
+ elif "MatAnyone processing" in msg:
120
+ progress, stage = 50, "Stage 1 - MatAnyone"
121
+ elif "MatAnyone complete" in msg:
122
+ progress, stage = 70, "Stage 1 - MatAnyone"
123
+ elif "Smoothing" in msg:
124
+ progress, stage = 75, "Stage 1 - Smoothing"
125
+ elif "transparent video" in msg:
126
+ progress, stage = 80, "Stage 1 - Finalizing"
127
+ elif "Stage 1 complete" in msg:
128
+ progress, stage = 85, "Stage 1 Complete"
129
+ elif "Stage 2 begun" in msg:
130
+ progress, stage = 86, "Stage 2"
131
+ elif "Compositing" in msg:
132
+ progress, stage = 90, "Stage 2 - Compositing"
133
+ elif "Restoring audio" in msg:
134
+ progress, stage = 95, "Stage 2 - Audio"
135
+ elif "Stage 2 complete" in msg:
136
+ progress, stage = 98, "Stage 2 Complete"
137
+
138
+ update_progress(msg, progress, stage)
139
+ logger.info(f"[PROGRESS] {msg}")
140
+
141
  transparent_path, audio_path = stage1_create_transparent_video(
142
  tmp_vid_path,
143
  sam2_predictor=sam2_predictor,
144
  matanyone_processor=matanyone_processor,
145
+ mat_timeout_sec=300,
146
+ progress_callback=progress_cb
147
  )
148
+
149
  if not transparent_path or not os.path.exists(transparent_path):
150
  raise RuntimeError("Stage 1 failed: Transparent video not created")
151
+ logger.info(f"[RUN {run_id}] Stage 1 completed")
152
 
 
 
153
  final_path = stage2_composite_background(
154
  transparent_path,
155
  audio_path,
156
  background,
157
+ bg_type.lower(),
158
+ progress_callback=progress_cb
159
  )
160
+
161
  if not final_path or not os.path.exists(final_path):
162
  raise RuntimeError("Stage 2 failed: Final video not created")
163
+ logger.info(f"[RUN {run_id}] Stage 2 completed")
164
 
 
 
165
  with open(final_path, 'rb') as f:
166
  st.session_state.processed_video_bytes = f.read()
167
+
168
  total = time.time() - t0
169
+ logger.info(f"[RUN {run_id}] SUCCESS total Δ={total:.2f}s")
170
+ mark_complete(success=True)
171
+
 
172
  except Exception as e:
173
  total = time.time() - t0
174
+ error_msg = f"Processing Error: {str(e)} (Δ {total:.2f}s)"
175
  logger.error(error_msg)
176
  logger.error(traceback.format_exc())
177
  st.session_state.last_error = error_msg
178
+ mark_complete(success=False, error=str(e))
 
 
179
  finally:
180
  st.session_state.processing = False
181
  logger.info(f"[RUN {run_id}] Processing finished")
 
189
  initial_sidebar_state="expanded"
190
  )
191
  initialize_session_state()
192
+ render_ui(process_video_background)
193
  except Exception as e:
194
  logger.error(f"Main app error: {e}", exc_info=True)
195
  st.error(f"App startup failed: {str(e)}. Check logs for details.")
196
 
197
  if __name__ == "__main__":
198
  setup_t4_environment()
199
+ main()