Hug0endob commited on
Commit
376a1ee
·
verified ·
1 Parent(s): 519e91d

Update streamlit_app.py

Browse files
Files changed (1) hide show
  1. streamlit_app.py +72 -71
streamlit_app.py CHANGED
@@ -255,51 +255,54 @@ def _strip_prompt_echo(prompt: str, text: str, threshold: float = 0.68) -> str:
255
  def main() -> None:
256
  st.set_page_config(page_title="Video Analysis", layout="wide")
257
 
 
 
 
258
  # ---------- Sidebar ----------
259
- st.sidebar.header("Video Input")
260
- st.sidebar.text_input("Video URL", key="url", placeholder="https://")
 
261
 
262
- with st.sidebar.expander("Settings", expanded=False):
263
- model = st.selectbox(
264
- "Model", MODEL_OPTIONS, index=MODEL_OPTIONS.index(DEFAULT_MODEL)
265
- )
266
- if model == "custom":
267
- model = st.text_input("Custom model ID", value=DEFAULT_MODEL, key="custom_model")
268
- st.session_state["model_input"] = model
269
-
270
- # API key handling
271
- secret_key = os.getenv("GOOGLE_API_KEY", "")
272
- if secret_key:
273
- st.session_state["api_key"] = secret_key
274
- st.text_input("Google API Key", key="api_key", type="password")
275
-
276
- st.text_area(
277
- "Analysis prompt", value=DEFAULT_PROMPT, key="prompt", height=140
278
- )
279
- st.text_input("Video password (if needed)", key="video_password", type="password")
280
-
281
- st.number_input(
282
- "Compress if > (MB)",
283
- min_value=10,
284
- max_value=2000,
285
- value=st.session_state["compress_mb"],
286
- step=10,
287
- key="compress_mb",
288
- )
289
 
290
  # ---------- Load video ----------
291
- if st.sidebar.button("Load Video"):
292
- try:
293
- with st.spinner("Downloading video…"):
294
- path = download_video(
295
- st.session_state["url"], DATA_DIR, st.session_state["video_password"]
296
- )
297
- st.session_state["video_path"] = str(path)
298
- st.session_state["last_error"] = ""
299
- st.success("Video loaded successfully.")
300
- except Exception as e:
301
- st.session_state["last_error"] = f"Download failed: {e}"
302
- st.sidebar.error(st.session_state["last_error"])
 
 
303
 
304
  # ---------- Preview & clear ----------
305
  if st.session_state["video_path"]:
@@ -309,14 +312,14 @@ def main() -> None:
309
  except Exception:
310
  st.sidebar.write("Preview unavailable")
311
 
312
- if st.sidebar.button("Clear Video"):
313
- # delete files
314
  for f in DATA_DIR.iterdir():
315
  try:
316
  f.unlink()
317
  except Exception:
318
  pass
319
- # reset state, including URL field
320
  st.session_state.update(
321
  {
322
  "url": "",
@@ -324,19 +327,22 @@ def main() -> None:
324
  "analysis_out": "",
325
  "last_error": "",
326
  "busy": False,
 
327
  }
328
  )
329
  st.success("Session cleared.")
330
 
331
  # ---------- Generation ----------
332
- col1, col2 = st.columns([1, 3])
333
- with col1:
334
- generate_now = st.button(
335
- "Generate analysis", type="primary", disabled=st.session_state["busy"]
336
- )
337
- with col2:
338
- if not st.session_state["video_path"]:
339
- st.info("Load a video first.", icon="ℹ️")
 
 
340
 
341
  if generate_now and not st.session_state["busy"]:
342
  api_key = st.session_state["api_key"] or os.getenv("GOOGLE_API_KEY")
@@ -389,25 +395,20 @@ if generate_now and not st.session_state["busy"]:
389
  finally:
390
  st.session_state["busy"] = False
391
 
392
- # ---------- Results ----------
393
- if st.session_state["analysis_out"]:
394
- st.subheader("📝 Analysis")
395
- st.markdown(st.session_state["analysis_out"])
396
-
397
- # Show raw Gemini output **above** the error expander when:
398
- # • we have a normal analysis (so user can compare) OR
399
- # • an error occurred (flag set)
400
- if st.session_state["raw_output"] and (
401
- st.session_state["analysis_out"] or st.session_state["show_raw_on_error"]
402
- ):
403
- with st.expander("🔎 Full Gemini output (debug)"):
404
- st.code(st.session_state["raw_output"], language="text")
405
-
406
- # ---------- Errors ----------
407
- if st.session_state["last_error"]:
408
- with st.expander("❗️ Error details"):
409
- # only the traceback – raw output already shown above
410
- st.code(st.session_state["last_error_detail"], language="text")
411
 
412
  if __name__ == "__main__":
413
  main()
 
255
  def main() -> None:
256
  st.set_page_config(page_title="Video Analysis", layout="wide")
257
 
258
+ # Two‑column layout: left = “pseudo‑sidebar”, right = main content
259
+ col_sidebar, col_main = st.columns([1, 3])
260
+
261
  # ---------- Sidebar ----------
262
+ with col_sidebar:
263
+ st.header("Video Input")
264
+ st.text_input("Video URL", key="url", placeholder="https://")
265
 
266
+ with st.expander("Settings", expanded=False):
267
+ model = st.selectbox(
268
+ "Model", MODEL_OPTIONS, index=MODEL_OPTIONS.index(DEFAULT_MODEL)
269
+ )
270
+ if model == "custom":
271
+ model = st.text_input("Custom model ID", value=DEFAULT_MODEL, key="custom_model")
272
+ st.session_state["model_input"] = model
273
+
274
+ # API key handling
275
+ secret_key = os.getenv("GOOGLE_API_KEY", "")
276
+ if secret_key:
277
+ st.session_state["api_key"] = secret_key
278
+ st.text_input("Google API Key", key="api_key", type="password")
279
+
280
+ st.text_area("Analysis prompt", value=DEFAULT_PROMPT, key="prompt", height=140)
281
+ st.text_input("Video password (if needed)", key="video_password", type="password")
282
+ st.number_input(
283
+ "Compress if > (MB)",
284
+ min_value=10,
285
+ max_value=2000,
286
+ value=st.session_state["compress_mb"],
287
+ step=10,
288
+ key="compress_mb",
289
+ )
 
 
 
290
 
291
  # ---------- Load video ----------
292
+ if st.button("Load Video"):
293
+ try:
294
+ with st.spinner("Downloading video…"):
295
+ raw_path = download_video(
296
+ st.session_state["url"], DATA_DIR, st.session_state["video_password"]
297
+ )
298
+ # ALWAYS convert to MP4 before storing
299
+ mp4_path = _convert_to_mp4(Path(raw_path))
300
+ st.session_state["video_path"] = str(mp4_path) # <-- guaranteed MP4
301
+ st.session_state["last_error"] = ""
302
+ st.success("Video loaded successfully.")
303
+ except Exception as e:
304
+ st.session_state["last_error"] = f"Download failed: {e}"
305
+ st.sidebar.error(st.session_state["last_error"])
306
 
307
  # ---------- Preview & clear ----------
308
  if st.session_state["video_path"]:
 
312
  except Exception:
313
  st.sidebar.write("Preview unavailable")
314
 
315
+ if st.button("Clear Video"):
316
+ # delete every file in DATA_DIR (both raw and converted)
317
  for f in DATA_DIR.iterdir():
318
  try:
319
  f.unlink()
320
  except Exception:
321
  pass
322
+ # reset session state, including the URL field
323
  st.session_state.update(
324
  {
325
  "url": "",
 
327
  "analysis_out": "",
328
  "last_error": "",
329
  "busy": False,
330
+ "show_raw_on_error": False,
331
  }
332
  )
333
  st.success("Session cleared.")
334
 
335
  # ---------- Generation ----------
336
+ with col_main:
337
+ # ---------- Generation ----------
338
+ col1, col2 = st.columns([1, 3])
339
+ with col1:
340
+ generate_now = st.button(
341
+ "Generate analysis", type="primary", disabled=st.session_state["busy"]
342
+ )
343
+ with col2:
344
+ if not st.session_state["video_path"]:
345
+ st.info("Load a video first.", icon="ℹ️")
346
 
347
  if generate_now and not st.session_state["busy"]:
348
  api_key = st.session_state["api_key"] or os.getenv("GOOGLE_API_KEY")
 
395
  finally:
396
  st.session_state["busy"] = False
397
 
398
+ # ---------- Results ----------
399
+ if st.session_state["analysis_out"]:
400
+ st.subheader("📝 Analysis")
401
+ st.markdown(st.session_state["analysis_out"])
402
+
403
+ # Show raw Gemini output only when it exists (no extra expander)
404
+ if st.session_state["raw_output"]:
405
+ st.subheader("🔎 Full Gemini output")
406
+ st.code(st.session_state["raw_output"], language="text")
407
+
408
+ # ---------- Errors ----------
409
+ if st.session_state["last_error"]:
410
+ with st.expander("❗️ Error details"):
411
+ st.code(st.session_state["last_error_detail"], language="text")
 
 
 
 
 
412
 
413
  if __name__ == "__main__":
414
  main()