MogensR commited on
Commit
db66357
·
verified ·
1 Parent(s): d2a013f

Update streamlit_app.py

Browse files
Files changed (1) hide show
  1. streamlit_app.py +86 -70
streamlit_app.py CHANGED
@@ -53,7 +53,6 @@ def check_gpu():
53
  logger.info(f"Device Name: {torch.cuda.get_device_name(0)}")
54
  logger.info(f"Device Capability: {torch.cuda.get_device_capability(0)}")
55
 
56
- # Test GPU tensor
57
  try:
58
  test_tensor = torch.randn(100, 100).cuda()
59
  logger.info(f"GPU Test Tensor Created Successfully on: {test_tensor.device}")
@@ -104,20 +103,29 @@ def check_gpu():
104
  # --- Session State Initialization ---
105
  def initialize_session_state():
106
  """Initialize all session state variables"""
107
- if 'initialized' not in st.session_state:
108
- st.session_state.initialized = True
109
- st.session_state.uploaded_video = None
110
- st.session_state.video_bytes_cache = None
111
- st.session_state.bg_image_cache = None
112
- st.session_state.bg_color = "#00FF00"
113
- st.session_state.color_display_cache = None
114
- st.session_state.processed_video_bytes = None
115
- st.session_state.processing = False
116
- st.session_state.process_complete = False
117
-
118
- # Run GPU check on first init
119
- gpu_available = check_gpu()
120
- st.session_state.gpu_available = gpu_available
 
 
 
 
 
 
 
 
 
121
 
122
  # --- Video Processing ---
123
  def process_video(input_file, background, bg_type="image"):
@@ -139,13 +147,13 @@ def process_video(input_file, background, bg_type="image"):
139
  input_path = str(temp_dir / "input.mp4")
140
  logger.info(f"Writing video to {input_path}")
141
 
142
- input_file.seek(0) # Ensure we're at the start
143
  with open(input_path, "wb") as f:
144
  written = f.write(input_file.read())
145
  logger.info(f"Wrote {written/1e6:.2f}MB")
146
 
147
  if not os.path.exists(input_path) or os.path.getsize(input_path) == 0:
148
- raise FileNotFoundError(f"Input video not saved properly: {input_path}")
149
 
150
  logger.info(f"Video file verified: {os.path.getsize(input_path)} bytes")
151
 
@@ -156,7 +164,7 @@ def process_video(input_file, background, bg_type="image"):
156
  bg_cv = cv2.cvtColor(np.array(background), cv2.COLOR_RGB2BGR)
157
  bg_path = str(temp_dir / "background.jpg")
158
  cv2.imwrite(bg_path, bg_cv)
159
- logger.info(f"Background image written: {bg_path}")
160
 
161
  elif bg_type == "color":
162
  logger.info(f"Processing background COLOR: {st.session_state.bg_color}")
@@ -164,7 +172,7 @@ def process_video(input_file, background, bg_type="image"):
164
  color_rgb = tuple(int(color_hex[i:i+2], 16) for i in (0, 2, 4))
165
  bg_path = str(temp_dir / "background.jpg")
166
  cv2.imwrite(bg_path, np.ones((100, 100, 3), dtype=np.uint8) * color_rgb[::-1])
167
- logger.info(f"Background color image written: {bg_path}")
168
 
169
  # Progress tracking
170
  progress_placeholder = st.empty()
@@ -194,7 +202,7 @@ def progress_callback(progress, message):
194
 
195
  @st.cache_resource
196
  def load_processor(temp_dir_str):
197
- logger.info(f"Loading processor with temp_dir: {temp_dir_str}")
198
  return TwoStageProcessor(temp_dir=temp_dir_str)
199
 
200
  processor = load_processor(str(temp_dir))
@@ -202,9 +210,6 @@ def load_processor(temp_dir_str):
202
 
203
  try:
204
  logger.info("Calling process_video...")
205
- logger.info(f" Input: {input_path}")
206
- logger.info(f" Background: {bg_path}")
207
- logger.info(f" Output: {output_path}")
208
 
209
  success = processor.process_video(
210
  input_video=input_path,
@@ -231,25 +236,24 @@ def load_processor(temp_dir_str):
231
 
232
  # Verify output
233
  if not os.path.exists(output_path):
234
- logger.error(f"Output file does not exist: {output_path}")
235
- raise FileNotFoundError(f"Output video not created: {output_path}")
236
 
237
  output_size = os.path.getsize(output_path)
238
- logger.info(f"Output file exists: {output_size} bytes ({output_size/1e6:.2f}MB)")
239
 
240
  # Read output into memory
241
- logger.info("Reading output video into memory...")
242
  with open(output_path, 'rb') as f:
243
  video_bytes = f.read()
244
 
245
- logger.info(f"Read {len(video_bytes)/1e6:.2f}MB into memory")
246
 
247
  # Cleanup
248
  try:
249
  shutil.rmtree(temp_dir)
250
  logger.info("Temp directory cleaned")
251
  except Exception as e:
252
- logger.warning(f"Could not clean temp directory: {e}")
253
 
254
  logger.info("=" * 60)
255
  logger.info("VIDEO PROCESSING COMPLETED")
@@ -258,11 +262,9 @@ def load_processor(temp_dir_str):
258
  return video_bytes
259
 
260
  except Exception as e:
261
- logger.error("=" * 60)
262
- logger.error(f"ERROR IN VIDEO PROCESSING: {str(e)}")
263
  logger.error(traceback.format_exc())
264
- logger.error("=" * 60)
265
- st.error(f"An error occurred during processing: {str(e)}")
266
  return None
267
 
268
  # --- Main Application ---
@@ -279,9 +281,9 @@ def main():
279
  if st.session_state.gpu_available:
280
  st.success(f"GPU: {torch.cuda.get_device_name(0)}")
281
  else:
282
- st.error("GPU: Not Available (using CPU)")
283
 
284
- logger.info(f"Rerun - Processing: {st.session_state.processing}, Complete: {st.session_state.process_complete}")
285
 
286
  # Main layout
287
  col1, col2 = st.columns([1, 1], gap="large")
@@ -295,27 +297,32 @@ def main():
295
  key="video_uploader"
296
  )
297
 
298
- # Store uploaded video
299
- if uploaded is not None:
300
- if st.session_state.uploaded_video is None or uploaded.name != getattr(st.session_state.uploaded_video, 'name', ''):
301
- logger.info(f"New video: {uploaded.name} ({uploaded.size} bytes)")
302
- st.session_state.uploaded_video = uploaded
303
- st.session_state.video_bytes_cache = None
304
- st.session_state.processed_video_bytes = None
305
- st.session_state.process_complete = False
 
306
 
307
- # Video preview
308
  st.markdown("### Video Preview")
 
 
 
309
  if st.session_state.uploaded_video is not None:
310
  if st.session_state.video_bytes_cache is None:
311
- logger.info("Caching video bytes...")
312
  st.session_state.uploaded_video.seek(0)
313
  st.session_state.video_bytes_cache = st.session_state.uploaded_video.read()
314
  logger.info(f"Cached {len(st.session_state.video_bytes_cache)/1e6:.2f}MB")
315
 
316
- st.video(st.session_state.video_bytes_cache)
 
317
  else:
318
- st.info("No video uploaded yet")
319
 
320
  with col2:
321
  st.header("2. Background Settings")
@@ -334,15 +341,25 @@ def main():
334
  key="bg_image_uploader"
335
  )
336
 
337
- if bg_image is not None:
338
- if st.session_state.bg_image_cache is None or bg_image.name != getattr(st.session_state.bg_image_cache, 'name', ''):
339
- logger.info(f"New background: {bg_image.name}")
 
 
 
340
  st.session_state.bg_image_cache = Image.open(bg_image)
341
- st.session_state.bg_image_cache.name = bg_image.name
342
-
343
- st.image(st.session_state.bg_image_cache, caption="Selected Background", use_container_width=True)
 
 
 
 
 
 
 
344
  else:
345
- st.info("No background image uploaded yet")
346
 
347
  elif bg_type == "Color":
348
  selected_color = st.color_picker(
@@ -351,21 +368,27 @@ def main():
351
  key="color_picker"
352
  )
353
 
354
- if selected_color != st.session_state.bg_color:
355
- logger.info(f"Color changed to: {selected_color}")
356
  st.session_state.bg_color = selected_color
 
357
 
358
  color_rgb = tuple(int(selected_color.lstrip('#')[i:i+2], 16) for i in (0, 2, 4))
359
  color_display = np.zeros((100, 100, 3), dtype=np.uint8)
360
  color_display[:, :] = color_rgb[::-1]
361
  st.session_state.color_display_cache = color_display
362
 
 
 
 
363
  if st.session_state.color_display_cache is not None:
364
- st.image(st.session_state.color_display_cache, caption="Selected Color", width=200)
 
 
 
365
 
366
  st.header("3. Process & Download")
367
 
368
- # Simple button instead of form
369
  if st.button(
370
  "Process Video",
371
  disabled=st.session_state.uploaded_video is None or st.session_state.processing,
@@ -381,10 +404,8 @@ def main():
381
  background = None
382
  if bg_type == "Image" and st.session_state.bg_image_cache is not None:
383
  background = st.session_state.bg_image_cache
384
- logger.info("Using background IMAGE")
385
  elif bg_type == "Color":
386
  background = st.session_state.bg_color
387
- logger.info(f"Using background COLOR: {background}")
388
 
389
  video_bytes = process_video(
390
  st.session_state.uploaded_video,
@@ -395,19 +416,17 @@ def main():
395
  if video_bytes and len(video_bytes) > 0:
396
  st.session_state.processed_video_bytes = video_bytes
397
  st.session_state.process_complete = True
398
- logger.info(f"Processing complete! {len(video_bytes)/1e6:.2f}MB")
399
  st.success("Video processing complete!")
400
  else:
401
- logger.error("Processing returned empty or None")
402
  st.error("Failed to process video")
403
 
404
  except Exception as e:
405
  logger.error(f"Exception: {str(e)}")
406
- logger.error(traceback.format_exc())
407
- st.error(f"An error occurred: {str(e)}")
408
  finally:
409
  st.session_state.processing = False
410
- logger.info(f"Processing finished. Success: {st.session_state.process_complete}")
411
 
412
  # Show processed video
413
  if st.session_state.processed_video_bytes is not None and len(st.session_state.processed_video_bytes) > 0:
@@ -415,9 +434,7 @@ def main():
415
  st.markdown("### Processed Video")
416
 
417
  try:
418
- logger.info(f"Displaying video: {len(st.session_state.processed_video_bytes)/1e6:.2f}MB")
419
  st.video(st.session_state.processed_video_bytes)
420
-
421
  st.download_button(
422
  label="Download Processed Video",
423
  data=st.session_state.processed_video_bytes,
@@ -425,10 +442,9 @@ def main():
425
  mime="video/mp4",
426
  use_container_width=True
427
  )
428
-
429
  except Exception as e:
430
- logger.error(f"Error displaying video: {str(e)}")
431
- st.error(f"Error displaying video: {str(e)}")
432
 
433
  if __name__ == "__main__":
434
  main()
 
53
  logger.info(f"Device Name: {torch.cuda.get_device_name(0)}")
54
  logger.info(f"Device Capability: {torch.cuda.get_device_capability(0)}")
55
 
 
56
  try:
57
  test_tensor = torch.randn(100, 100).cuda()
58
  logger.info(f"GPU Test Tensor Created Successfully on: {test_tensor.device}")
 
103
  # --- Session State Initialization ---
104
  def initialize_session_state():
105
  """Initialize all session state variables"""
106
+ defaults = {
107
+ 'uploaded_video': None,
108
+ 'video_bytes_cache': None,
109
+ 'video_preview_placeholder': None,
110
+ 'bg_image_cache': None,
111
+ 'bg_preview_placeholder': None,
112
+ 'bg_color': "#00FF00",
113
+ 'cached_color': None,
114
+ 'color_display_cache': None,
115
+ 'processed_video_bytes': None,
116
+ 'processing': False,
117
+ 'process_complete': False,
118
+ 'last_video_id': None,
119
+ 'last_bg_image_id': None,
120
+ 'gpu_available': None
121
+ }
122
+ for key, value in defaults.items():
123
+ if key not in st.session_state:
124
+ st.session_state[key] = value
125
+
126
+ # Run GPU check on first init
127
+ if st.session_state.gpu_available is None:
128
+ st.session_state.gpu_available = check_gpu()
129
 
130
  # --- Video Processing ---
131
  def process_video(input_file, background, bg_type="image"):
 
147
  input_path = str(temp_dir / "input.mp4")
148
  logger.info(f"Writing video to {input_path}")
149
 
150
+ input_file.seek(0)
151
  with open(input_path, "wb") as f:
152
  written = f.write(input_file.read())
153
  logger.info(f"Wrote {written/1e6:.2f}MB")
154
 
155
  if not os.path.exists(input_path) or os.path.getsize(input_path) == 0:
156
+ raise FileNotFoundError(f"Input video not saved properly")
157
 
158
  logger.info(f"Video file verified: {os.path.getsize(input_path)} bytes")
159
 
 
164
  bg_cv = cv2.cvtColor(np.array(background), cv2.COLOR_RGB2BGR)
165
  bg_path = str(temp_dir / "background.jpg")
166
  cv2.imwrite(bg_path, bg_cv)
167
+ logger.info(f"Background image written")
168
 
169
  elif bg_type == "color":
170
  logger.info(f"Processing background COLOR: {st.session_state.bg_color}")
 
172
  color_rgb = tuple(int(color_hex[i:i+2], 16) for i in (0, 2, 4))
173
  bg_path = str(temp_dir / "background.jpg")
174
  cv2.imwrite(bg_path, np.ones((100, 100, 3), dtype=np.uint8) * color_rgb[::-1])
175
+ logger.info(f"Background color image written")
176
 
177
  # Progress tracking
178
  progress_placeholder = st.empty()
 
202
 
203
  @st.cache_resource
204
  def load_processor(temp_dir_str):
205
+ logger.info(f"Loading processor")
206
  return TwoStageProcessor(temp_dir=temp_dir_str)
207
 
208
  processor = load_processor(str(temp_dir))
 
210
 
211
  try:
212
  logger.info("Calling process_video...")
 
 
 
213
 
214
  success = processor.process_video(
215
  input_video=input_path,
 
236
 
237
  # Verify output
238
  if not os.path.exists(output_path):
239
+ raise FileNotFoundError(f"Output video not created")
 
240
 
241
  output_size = os.path.getsize(output_path)
242
+ logger.info(f"Output: {output_size} bytes ({output_size/1e6:.2f}MB)")
243
 
244
  # Read output into memory
245
+ logger.info("Reading output into memory...")
246
  with open(output_path, 'rb') as f:
247
  video_bytes = f.read()
248
 
249
+ logger.info(f"Read {len(video_bytes)/1e6:.2f}MB")
250
 
251
  # Cleanup
252
  try:
253
  shutil.rmtree(temp_dir)
254
  logger.info("Temp directory cleaned")
255
  except Exception as e:
256
+ logger.warning(f"Could not clean temp: {e}")
257
 
258
  logger.info("=" * 60)
259
  logger.info("VIDEO PROCESSING COMPLETED")
 
262
  return video_bytes
263
 
264
  except Exception as e:
265
+ logger.error(f"ERROR: {str(e)}")
 
266
  logger.error(traceback.format_exc())
267
+ st.error(f"An error occurred: {str(e)}")
 
268
  return None
269
 
270
  # --- Main Application ---
 
281
  if st.session_state.gpu_available:
282
  st.success(f"GPU: {torch.cuda.get_device_name(0)}")
283
  else:
284
+ st.error("GPU: Not Available")
285
 
286
+ logger.info(f"Rerun - Processing: {st.session_state.processing}")
287
 
288
  # Main layout
289
  col1, col2 = st.columns([1, 1], gap="large")
 
297
  key="video_uploader"
298
  )
299
 
300
+ # Check if video actually changed using id()
301
+ current_video_id = id(uploaded)
302
+ if current_video_id != st.session_state.last_video_id:
303
+ logger.info(f"New video: {uploaded.name if uploaded else 'None'}")
304
+ st.session_state.uploaded_video = uploaded
305
+ st.session_state.last_video_id = current_video_id
306
+ st.session_state.video_bytes_cache = None
307
+ st.session_state.processed_video_bytes = None
308
+ st.session_state.process_complete = False
309
 
310
+ # Video preview with placeholder
311
  st.markdown("### Video Preview")
312
+ if st.session_state.video_preview_placeholder is None:
313
+ st.session_state.video_preview_placeholder = st.empty()
314
+
315
  if st.session_state.uploaded_video is not None:
316
  if st.session_state.video_bytes_cache is None:
317
+ logger.info("Caching video...")
318
  st.session_state.uploaded_video.seek(0)
319
  st.session_state.video_bytes_cache = st.session_state.uploaded_video.read()
320
  logger.info(f"Cached {len(st.session_state.video_bytes_cache)/1e6:.2f}MB")
321
 
322
+ with st.session_state.video_preview_placeholder.container():
323
+ st.video(st.session_state.video_bytes_cache)
324
  else:
325
+ st.session_state.video_preview_placeholder.empty()
326
 
327
  with col2:
328
  st.header("2. Background Settings")
 
341
  key="bg_image_uploader"
342
  )
343
 
344
+ # Check if image actually changed using id()
345
+ current_bg_id = id(bg_image)
346
+ if current_bg_id != st.session_state.last_bg_image_id:
347
+ logger.info(f"New background: {bg_image.name if bg_image else 'None'}")
348
+ st.session_state.last_bg_image_id = current_bg_id
349
+ if bg_image is not None:
350
  st.session_state.bg_image_cache = Image.open(bg_image)
351
+ else:
352
+ st.session_state.bg_image_cache = None
353
+
354
+ # Background preview with placeholder
355
+ if st.session_state.bg_preview_placeholder is None:
356
+ st.session_state.bg_preview_placeholder = st.empty()
357
+
358
+ if st.session_state.bg_image_cache is not None:
359
+ with st.session_state.bg_preview_placeholder.container():
360
+ st.image(st.session_state.bg_image_cache, caption="Selected Background", use_container_width=True)
361
  else:
362
+ st.session_state.bg_preview_placeholder.empty()
363
 
364
  elif bg_type == "Color":
365
  selected_color = st.color_picker(
 
368
  key="color_picker"
369
  )
370
 
371
+ if selected_color != st.session_state.cached_color:
372
+ logger.info(f"Color: {selected_color}")
373
  st.session_state.bg_color = selected_color
374
+ st.session_state.cached_color = selected_color
375
 
376
  color_rgb = tuple(int(selected_color.lstrip('#')[i:i+2], 16) for i in (0, 2, 4))
377
  color_display = np.zeros((100, 100, 3), dtype=np.uint8)
378
  color_display[:, :] = color_rgb[::-1]
379
  st.session_state.color_display_cache = color_display
380
 
381
+ if st.session_state.bg_preview_placeholder is None:
382
+ st.session_state.bg_preview_placeholder = st.empty()
383
+
384
  if st.session_state.color_display_cache is not None:
385
+ with st.session_state.bg_preview_placeholder.container():
386
+ st.image(st.session_state.color_display_cache, caption="Selected Color", width=200)
387
+ else:
388
+ st.session_state.bg_preview_placeholder.empty()
389
 
390
  st.header("3. Process & Download")
391
 
 
392
  if st.button(
393
  "Process Video",
394
  disabled=st.session_state.uploaded_video is None or st.session_state.processing,
 
404
  background = None
405
  if bg_type == "Image" and st.session_state.bg_image_cache is not None:
406
  background = st.session_state.bg_image_cache
 
407
  elif bg_type == "Color":
408
  background = st.session_state.bg_color
 
409
 
410
  video_bytes = process_video(
411
  st.session_state.uploaded_video,
 
416
  if video_bytes and len(video_bytes) > 0:
417
  st.session_state.processed_video_bytes = video_bytes
418
  st.session_state.process_complete = True
419
+ logger.info(f"Complete! {len(video_bytes)/1e6:.2f}MB")
420
  st.success("Video processing complete!")
421
  else:
422
+ logger.error("Processing returned empty")
423
  st.error("Failed to process video")
424
 
425
  except Exception as e:
426
  logger.error(f"Exception: {str(e)}")
427
+ st.error(f"Error: {str(e)}")
 
428
  finally:
429
  st.session_state.processing = False
 
430
 
431
  # Show processed video
432
  if st.session_state.processed_video_bytes is not None and len(st.session_state.processed_video_bytes) > 0:
 
434
  st.markdown("### Processed Video")
435
 
436
  try:
 
437
  st.video(st.session_state.processed_video_bytes)
 
438
  st.download_button(
439
  label="Download Processed Video",
440
  data=st.session_state.processed_video_bytes,
 
442
  mime="video/mp4",
443
  use_container_width=True
444
  )
 
445
  except Exception as e:
446
+ logger.error(f"Display error: {str(e)}")
447
+ st.error(f"Error: {str(e)}")
448
 
449
  if __name__ == "__main__":
450
  main()