duongthienz commited on
Commit
6939bed
Β·
verified Β·
1 Parent(s): 8441515

Replace st.dataframe(displayDF) with a custom table

Browse files

Streamlit's dataframe widget is read-only and renders only scalar values β€” it cannot embed audio players or buttons. We have to hand-render the table using st.columns

Files changed (1) hide show
  1. app.py +60 -23
app.py CHANGED
@@ -362,28 +362,7 @@ try:
362
  "Changes apply to all matched speakers instantly."
363
  )
364
 
365
- file_clips = st.session_state.speakerClips.get(currFile, {})
366
- if file_clips:
367
- st.sidebar.caption("🎧 Listen to clips to help identify speakers:")
368
- current_renames = st.session_state.speakerRenames[currFile]
369
- for sp in speakerNames:
370
- wk = f"rename_{currFile}_{sp}"
371
- if wk not in st.session_state:
372
- st.session_state[wk] = current_renames.get(sp, "")
373
- display_label = st.session_state[wk].strip() or sp
374
- st.sidebar.markdown(f"**{display_label}**")
375
- if sp in file_clips:
376
- st.sidebar.audio(file_clips[sp], format="audio/wav")
377
- sp_segs = st.session_state.speakerSegments.get(currFile, {}).get(sp, [])
378
- has_waveform = currFile in st.session_state.speakerWaveforms
379
- if has_waveform and sp_segs:
380
- if st.sidebar.button(
381
- "πŸ”€ Try Another Clip",
382
- key=f"randomize_{currFile}_{sp}",
383
- help="Pick a random clip from a different part of this speaker's audio",
384
- ):
385
- randomize_speaker_clip(currFile, sp)
386
- st.rerun()
387
 
388
  all_speaker_tokens = [
389
  f"{fn}: {sp}"
@@ -456,7 +435,65 @@ try:
456
  f"sonogram-analysis-{currPlainName}.csv", "text/csv",
457
  key="download-csv", on_click="ignore",
458
  )
459
- st.dataframe(displayDF)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
460
 
461
  # -----------------------------------------------------------------------
462
  # Charts (pie1, pie2, sunburst, treemap, timeline, bar)
 
362
  "Changes apply to all matched speakers instantly."
363
  )
364
 
365
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
366
 
367
  all_speaker_tokens = [
368
  f"{fn}: {sp}"
 
435
  f"sonogram-analysis-{currPlainName}.csv", "text/csv",
436
  key="download-csv", on_click="ignore",
437
  )
438
+
439
+ file_clips = st.session_state.speakerClips.get(currFile, {})
440
+ has_clips = bool(file_clips)
441
+ has_waveform = currFile in st.session_state.speakerWaveforms
442
+
443
+ # Determine column layout.
444
+ # Extra columns only appear when audio clips are available.
445
+ # Widths: Resource | Start | Finish | [Clip | Randomize]
446
+ other_cols = [c for c in displayDF.columns if c != "Resource"]
447
+ has_extras = has_clips
448
+
449
+ if has_extras:
450
+ col_widths = [2] + [1] * len(other_cols) + [2, 1]
451
+ else:
452
+ col_widths = [2] + [1] * len(other_cols)
453
+
454
+ # Header row
455
+ header_cols = st.columns(col_widths)
456
+ header_cols[0].markdown("**Resource**")
457
+ for i, col_name in enumerate(other_cols):
458
+ header_cols[i + 1].markdown(f"**{col_name}**")
459
+ if has_extras:
460
+ header_cols[-2].markdown("**Clip**")
461
+ header_cols[-1].markdown("** **", unsafe_allow_html=True)
462
+
463
+ st.divider()
464
+
465
+ # Track which speakers have already had their clip rendered
466
+ # so we only show it once (on the first row for that speaker).
467
+ rendered_clip_for: set = set()
468
+
469
+ for _, row in displayDF.iterrows():
470
+ row_cols = st.columns(col_widths)
471
+ raw_sp = row["Resource"] # already display-name mapped
472
+
473
+ # Find the original raw speaker key for clip lookup
474
+ # (speakerClips is keyed by original SPEAKER_## labels)
475
+ raw_key = next(
476
+ (sp for sp in speakerNames if raw_to_display.get(sp, sp) == raw_sp),
477
+ raw_sp,
478
+ )
479
+
480
+ row_cols[0].write(raw_sp)
481
+ for i, col_name in enumerate(other_cols):
482
+ row_cols[i + 1].write(row[col_name])
483
+
484
+ if has_extras:
485
+ if raw_key in file_clips and raw_key not in rendered_clip_for:
486
+ rendered_clip_for.add(raw_key)
487
+ row_cols[-2].audio(file_clips[raw_key], format="audio/wav")
488
+ sp_segs = st.session_state.speakerSegments.get(currFile, {}).get(raw_key, [])
489
+ if has_waveform and sp_segs:
490
+ if row_cols[-1].button(
491
+ "πŸ”€",
492
+ key=f"randomize_{currFile}_{raw_key}",
493
+ help="Try a different clip for this speaker",
494
+ ):
495
+ randomize_speaker_clip(currFile, raw_key)
496
+ st.rerun()
497
 
498
  # -----------------------------------------------------------------------
499
  # Charts (pie1, pie2, sunburst, treemap, timeline, bar)