MogensR commited on
Commit
bf00174
·
verified ·
1 Parent(s): e98a89b

Update ui.py

Browse files
Files changed (1) hide show
  1. ui.py +136 -144
ui.py CHANGED
@@ -13,9 +13,7 @@
13
  import logging
14
  from datetime import datetime
15
  import time
16
-
17
  logger = logging.getLogger("Advanced Video Background Replacer")
18
-
19
  # --- UI Helpers ---
20
  def tail_file(path: str, lines: int = 400) -> str:
21
  """Read last N lines from a text file efficiently."""
@@ -27,7 +25,6 @@ def tail_file(path: str, lines: int = 400) -> str:
27
  return "".join(content[-lines:])
28
  except Exception as e:
29
  return f"(failed to read log: {e})"
30
-
31
  def read_file_bytes(path: str) -> bytes:
32
  """Read a file as bytes; return b'' if missing/error."""
33
  try:
@@ -37,148 +34,141 @@ def read_file_bytes(path: str) -> bytes:
37
  return f.read()
38
  except Exception:
39
  return b""
40
-
41
  # --- Render UI ---
42
  def render_ui(process_video_func):
43
- # --- Sidebar: System Status & Logs ---
44
- with st.sidebar:
45
- st.subheader("System Status")
46
- st.markdown("**Log file:** `/tmp/app.log`")
47
-
48
- # Log level control
49
- log_level = st.selectbox(
50
- "Log Level",
51
- ["DEBUG", "INFO", "WARNING", "ERROR"],
52
- index=1, # Default: INFO
53
- key="log_level_select"
54
- )
55
- if log_level != st.session_state.get('log_level_name', 'INFO'):
56
- from streamlit_app import set_log_level
57
- set_log_level(log_level)
58
-
59
- if st.session_state.get('gpu_available', False):
60
- try:
61
- import torch
62
- dev = torch.cuda.get_device_name(0)
63
- except Exception:
64
- dev = "Detected (name unavailable)"
65
- st.success(f"GPU: {dev}")
66
- else:
67
- st.error("GPU: Not Available")
68
-
69
- # Log viewer controls
70
- st.checkbox("Auto-refresh log tail (every 2s)", key="auto_refresh_logs")
71
- st.number_input("Tail last N lines", min_value=50, max_value=5000, step=50, key="log_tail_lines")
72
-
73
- # Download logs button
74
- log_bytes = read_file_bytes("/tmp/app.log")
75
- st.download_button(
76
- "Download Logs",
77
- data=log_bytes if log_bytes else b"Log file not available yet.",
78
- file_name="app.log",
79
- mime="text/plain",
80
- use_container_width=True,
81
- disabled=not bool(log_bytes)
82
- )
83
-
84
- # Log tail viewer
85
- with st.expander("View Log Tail", expanded=True):
86
- if st.session_state.get('auto_refresh_logs', False):
87
- time.sleep(2)
88
- st.rerun()
89
- log_text = tail_file("/tmp/app.log", st.session_state.get('log_tail_lines', 400))
90
- st.code(log_text, language="text")
91
-
92
- # --- Main UI: Two-Column Layout ---
93
- col1, col2 = st.columns([1, 1], gap="large")
94
-
95
- # --- Column 1: Video Upload ---
96
- with col1:
97
- st.header("1. Upload Video")
98
- uploaded_video = st.file_uploader(
99
- "Upload Video",
100
- type=["mp4", "mov", "avi", "mkv", "webm"],
101
- key="video_uploader"
102
- )
103
-
104
- st.markdown("### Video Preview")
105
- video_preview_placeholder = st.empty()
106
- if uploaded_video is not None:
107
- try:
108
- uploaded_video.seek(0)
109
- video_bytes = uploaded_video.read()
110
- with video_preview_placeholder.container():
111
- st.video(video_bytes)
112
- except Exception as e:
113
- logger.error(f"[UI] Video preview error: {e}", exc_info=True)
114
- video_preview_placeholder.error(f"Cannot display video: {e}")
115
- else:
116
- video_preview_placeholder.empty()
117
-
118
- # --- Column 2: Background & Processing ---
119
- with col2:
120
- st.header("2. Background Settings")
121
- bg_type = st.radio(
122
- "Select Background Type:",
123
- ["Image", "Color"],
124
- horizontal=True,
125
- key="bg_type_radio"
126
- )
127
-
128
- # Background Image Upload
129
- if bg_type == "Image":
130
- bg_image = st.file_uploader(
131
- "Upload Background Image",
132
- type=["jpg", "png", "jpeg"],
133
- key="bg_image_uploader"
134
  )
135
- bg_preview_placeholder = st.empty()
136
- if bg_image is not None:
 
 
137
  try:
138
- bg_image_pil = Image.open(bg_image)
139
- with bg_preview_placeholder.container():
140
- st.image(bg_image_pil, caption="Selected Background", use_column_width=True)
141
- except Exception as e:
142
- logger.error(f"[UI] Background image error: {e}", exc_info=True)
143
- bg_preview_placeholder.error(f"Cannot display image: {e}")
144
  else:
145
- bg_preview_placeholder.empty()
146
-
147
- # Background Color Picker
148
- else:
149
- selected_color = st.color_picker(
150
- "Choose Background Color",
151
- st.session_state.get('bg_color', "#00FF00"),
152
- key="color_picker"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
153
  )
154
- if selected_color != st.session_state.get('cached_color'):
155
- st.session_state.bg_color = selected_color
156
- st.session_state.cached_color = selected_color
157
- color_rgb = tuple(int(selected_color.lstrip('#')[i:i+2], 16) for i in (0, 2, 4))
158
- color_display = np.zeros((100, 100, 3), dtype=np.uint8)
159
- color_display[:, :] = color_rgb
160
- st.session_state.color_display_cache = color_display
161
- color_preview_placeholder = st.empty()
162
- if st.session_state.get('color_display_cache') is not None:
163
- with color_preview_placeholder.container():
164
- st.image(st.session_state.color_display_cache, caption="Selected Color", width=200)
165
  else:
166
- color_preview_placeholder.empty()
167
-
168
- # --- Process Button ---
169
- st.header("3. Process Video")
170
- can_process = (uploaded_video is not None and not st.session_state.get('processing', False))
171
- if st.button("Process Video", disabled=not can_process, use_container_width=True):
172
- if bg_type == "Image" and bg_image is None:
173
- st.error("Please upload a background image")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
174
  else:
175
- background = bg_image if bg_type == "Image" else st.session_state.get('bg_color')
176
- success = process_video_func(uploaded_video, bg_image, background, bg_type)
177
- if success:
178
- st.success("Video processing complete!")
 
 
 
 
 
 
 
 
 
 
 
 
179
  else:
180
- st.error("Video processing failed. Check logs for details.")
181
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
182
  # --- Results Display ---
183
  if st.session_state.get('processed_video_bytes') is not None:
184
  st.markdown("---")
@@ -195,11 +185,13 @@ def render_ui(process_video_func):
195
  except Exception as e:
196
  logger.error(f"[UI] Display error: {e}", exc_info=True)
197
  st.error(f"Display error: {e}")
198
-
199
- # --- Error Display ---
200
- if st.session_state.get('last_error'):
201
- with st.expander("⚠️ Last Error", expanded=True):
202
- st.error(st.session_state.last_error)
203
- if st.button("Clear Error"):
204
- st.session_state.last_error = None
205
- st.rerun()
 
 
 
13
  import logging
14
  from datetime import datetime
15
  import time
 
16
  logger = logging.getLogger("Advanced Video Background Replacer")
 
17
  # --- UI Helpers ---
18
  def tail_file(path: str, lines: int = 400) -> str:
19
  """Read last N lines from a text file efficiently."""
 
25
  return "".join(content[-lines:])
26
  except Exception as e:
27
  return f"(failed to read log: {e})"
 
28
  def read_file_bytes(path: str) -> bytes:
29
  """Read a file as bytes; return b'' if missing/error."""
30
  try:
 
34
  return f.read()
35
  except Exception:
36
  return b""
 
37
  # --- Render UI ---
38
  def render_ui(process_video_func):
39
+ try:
40
+ # --- Sidebar: System Status & Logs ---
41
+ with st.sidebar:
42
+ st.subheader("System Status")
43
+ st.markdown("**Log file:** `/tmp/app.log`")
44
+ # Log level control
45
+ log_level = st.selectbox(
46
+ "Log Level",
47
+ ["DEBUG", "INFO", "WARNING", "ERROR"],
48
+ index=1, # Default: INFO
49
+ key="log_level_select"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  )
51
+ if log_level != st.session_state.get('log_level_name', 'INFO'):
52
+ from streamlit_app import set_log_level
53
+ set_log_level(log_level)
54
+ if st.session_state.get('gpu_available', False):
55
  try:
56
+ import torch
57
+ dev = torch.cuda.get_device_name(0)
58
+ except Exception:
59
+ dev = "Detected (name unavailable)"
60
+ st.success(f"GPU: {dev}")
 
61
  else:
62
+ st.error("GPU: Not Available")
63
+ # Log viewer controls
64
+ st.checkbox("Auto-refresh log tail (every 2s)", key="auto_refresh_logs")
65
+ st.number_input("Tail last N lines", min_value=50, max_value=5000, step=50, key="log_tail_lines")
66
+ # Download logs button
67
+ log_bytes = read_file_bytes("/tmp/app.log")
68
+ st.download_button(
69
+ "Download Logs",
70
+ data=log_bytes if log_bytes else b"Log file not available yet.",
71
+ file_name="app.log",
72
+ mime="text/plain",
73
+ use_container_width=True,
74
+ disabled=not bool(log_bytes)
75
+ )
76
+ # Log tail viewer
77
+ with st.expander("View Log Tail", expanded=True):
78
+ if st.session_state.get('auto_refresh_logs', False):
79
+ time.sleep(2)
80
+ st.rerun()
81
+ log_text = tail_file("/tmp/app.log", st.session_state.get('log_tail_lines', 400))
82
+ st.code(log_text, language="text")
83
+ # --- Main UI: Two-Column Layout ---
84
+ col1, col2 = st.columns([1, 1], gap="large")
85
+ # --- Column 1: Video Upload ---
86
+ with col1:
87
+ st.header("1. Upload Video")
88
+ uploaded_video = st.file_uploader(
89
+ "Upload Video",
90
+ type=["mp4", "mov", "avi", "mkv", "webm"],
91
+ key="video_uploader"
92
  )
93
+ st.markdown("### Video Preview")
94
+ video_preview_placeholder = st.empty()
95
+ if uploaded_video is not None:
96
+ try:
97
+ uploaded_video.seek(0)
98
+ video_bytes = uploaded_video.read()
99
+ with video_preview_placeholder.container():
100
+ st.video(video_bytes)
101
+ except Exception as e:
102
+ logger.error(f"[UI] Video preview error: {e}", exc_info=True)
103
+ video_preview_placeholder.error(f"Cannot display video: {e}")
104
  else:
105
+ video_preview_placeholder.empty()
106
+ # --- Column 2: Background & Processing ---
107
+ with col2:
108
+ st.header("2. Background Settings")
109
+ bg_type = st.radio(
110
+ "Select Background Type:",
111
+ ["Image", "Color"],
112
+ horizontal=True,
113
+ key="bg_type_radio"
114
+ )
115
+ # Background Image Upload
116
+ if bg_type == "Image":
117
+ bg_image = st.file_uploader(
118
+ "Upload Background Image",
119
+ type=["jpg", "png", "jpeg"],
120
+ key="bg_image_uploader"
121
+ )
122
+ bg_preview_placeholder = st.empty()
123
+ if bg_image is not None:
124
+ try:
125
+ bg_image_pil = Image.open(bg_image)
126
+ with bg_preview_placeholder.container():
127
+ st.image(bg_image_pil, caption="Selected Background", use_column_width=True)
128
+ except Exception as e:
129
+ logger.error(f"[UI] Background image error: {e}", exc_info=True)
130
+ bg_preview_placeholder.error(f"Cannot display image: {e}")
131
+ else:
132
+ bg_preview_placeholder.empty()
133
+ # Background Color Picker
134
  else:
135
+ selected_color = st.color_picker(
136
+ "Choose Background Color",
137
+ st.session_state.get('bg_color', "#00FF00"),
138
+ key="color_picker"
139
+ )
140
+ if selected_color != st.session_state.get('cached_color'):
141
+ st.session_state.bg_color = selected_color
142
+ st.session_state.cached_color = selected_color
143
+ color_rgb = tuple(int(selected_color.lstrip('#')[i:i+2], 16) for i in (0, 2, 4))
144
+ color_display = np.zeros((100, 100, 3), dtype=np.uint8)
145
+ color_display[:, :] = color_rgb
146
+ st.session_state.color_display_cache = color_display
147
+ color_preview_placeholder = st.empty()
148
+ if st.session_state.get('color_display_cache') is not None:
149
+ with color_preview_placeholder.container():
150
+ st.image(st.session_state.color_display_cache, caption="Selected Color", width=200)
151
  else:
152
+ color_preview_placeholder.empty()
153
+ # --- Process Button ---
154
+ st.header("3. Process Video")
155
+ can_process = (uploaded_video is not None and not st.session_state.get('processing', False))
156
+ if st.button("Process Video", disabled=not can_process, use_container_width=True):
157
+ try:
158
+ logger.info("Process Video button clicked")
159
+ if bg_type == "Image" and bg_image is None:
160
+ st.error("Please upload a background image")
161
+ else:
162
+ background = bg_image if bg_type == "Image" else st.session_state.get('bg_color')
163
+ with st.spinner("Processing video..."):
164
+ success = process_video_func(uploaded_video, bg_image, background, bg_type)
165
+ if success:
166
+ st.success("Video processing complete!")
167
+ else:
168
+ st.error("Video processing failed. Check logs for details.")
169
+ except Exception as e:
170
+ logger.error(f"[UI] Process video error: {e}", exc_info=True)
171
+ st.error(f"Processing error: {str(e)}. Check logs for details.")
172
  # --- Results Display ---
173
  if st.session_state.get('processed_video_bytes') is not None:
174
  st.markdown("---")
 
185
  except Exception as e:
186
  logger.error(f"[UI] Display error: {e}", exc_info=True)
187
  st.error(f"Display error: {e}")
188
+ # --- Error Display ---
189
+ if st.session_state.get('last_error'):
190
+ with st.expander("⚠️ Last Error", expanded=True):
191
+ st.error(st.session_state.last_error)
192
+ if st.button("Clear Error"):
193
+ st.session_state.last_error = None
194
+ st.rerun()
195
+ except Exception as e:
196
+ logger.error(f"[UI] Render UI error: {e}", exc_info=True)
197
+ st.error(f"UI rendering error: {str(e)}. Check logs for details.")