import os from typing import Optional import streamlit as st def _get_music_dir() -> str: return os.path.join(os.path.dirname(__file__), "assets", "audio", "music") def _get_effects_dir() -> str: return os.path.join(os.path.dirname(__file__), "assets", "audio", "effects") def get_audio_tracks() -> list[tuple[str, str]]: """Return list of (label, absolute_path) for .mp3 files in assets/audio/music.""" audio_dir = _get_music_dir() if not os.path.isdir(audio_dir): return [] tracks = [] for fname in os.listdir(audio_dir): if fname.lower().endswith('.mp3'): path = os.path.join(audio_dir, fname) # Use the filename without extension as the display name name = os.path.splitext(fname)[0] tracks.append((name, path)) return tracks @st.cache_data(show_spinner=False) def _load_audio_data_url(path: str) -> str: """Return a data: URL for the given audio file so the browser can play it.""" import base64, mimetypes mime, _ = mimetypes.guess_type(path) if not mime: # Default to mp3 to avoid blocked playback if unknown mime = "audio/mpeg" with open(path, "rb") as fp: encoded = base64.b64encode(fp.read()).decode("ascii") return f"data:{mime};base64,{encoded}" def _mount_background_audio(enabled: bool, src_data_url: Optional[str], volume: float, loop: bool = True) -> None: """Create/update a single hidden