Spaces:
Runtime error
Runtime error
| """Whisper Speaker Diarization — Neobrutalism Gradio app (event wiring only).""" | |
| import logging | |
| import os | |
| from pathlib import Path | |
| def load_env_file(env_path=".env"): | |
| path = Path(env_path) | |
| if not path.exists(): | |
| return | |
| for line in path.read_text(encoding="utf-8").splitlines(): | |
| line = line.strip() | |
| if not line or line.startswith("#") or "=" not in line: | |
| continue | |
| key, value = line.split("=", 1) | |
| os.environ.setdefault(key.strip(), value.strip().strip('"').strip("'")) | |
| load_env_file() | |
| from core import cache_manager # noqa: E402 | |
| cache_manager.get_model_cache_dir() | |
| cache_manager.ensure_dirs() | |
| cache_manager.cleanup_old_videos() | |
| import gradio as gr # noqa: E402 | |
| import gradio_client.utils as _gcu # noqa: E402 | |
| # gradio_client 1.5–1.7 raises TypeError on plain bool JSON-schema nodes. | |
| # Guard against double-patching: `gradio app.py` reload re-executes this module, | |
| # and lambdas resolve their free vars at call time — without the guard, | |
| # `_orig_to_py` gets rebound to the previously-installed lambda, causing | |
| # infinite recursion when /info is requested. | |
| if not getattr(_gcu, "_brut_bool_schema_patched", False): | |
| _orig_get_type = _gcu.get_type | |
| _orig_to_py = _gcu._json_schema_to_python_type | |
| _gcu.get_type = lambda s: "Any" if isinstance(s, bool) else _orig_get_type(s) | |
| _gcu._json_schema_to_python_type = lambda s, d=None: ("Any" if s else "None") if isinstance(s, bool) else _orig_to_py(s, d) | |
| _gcu._brut_bool_schema_patched = True | |
| from core.pipeline_runner import OUTPUT_DIR # noqa: E402 | |
| from core.ui import handlers # noqa: E402 | |
| from core.ui.layout import build_results_dock, build_stepper # noqa: E402 | |
| logging.basicConfig(level=logging.INFO) | |
| _STYLES_DIR = Path(__file__).parent / "core" / "styles" | |
| _THEME_CSS = (_STYLES_DIR / "neobrutalism.css").read_text(encoding="utf-8") | |
| _SEEK_JS = (_STYLES_DIR / "seek.js").read_text(encoding="utf-8") | |
| _HEAD = ( | |
| '<link rel="preconnect" href="https://fonts.googleapis.com">' | |
| '<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>' | |
| '<link href="https://fonts.googleapis.com/css2?family=Archivo+Black&family=JetBrains+Mono&family=Space+Grotesk:wght@500;700&display=swap" rel="stylesheet">' | |
| f'<script>{_SEEK_JS}</script>' | |
| ) | |
| _THEME = gr.themes.Base(primary_hue="yellow", neutral_hue="stone").set( | |
| body_background_fill="#FFF8E7", | |
| body_background_fill_dark="#FFF8E7", | |
| body_text_color="#000000", | |
| body_text_color_dark="#000000", | |
| button_primary_background_fill="#FFD23F", | |
| button_primary_background_fill_dark="#FFD23F", | |
| button_primary_text_color="#000000", | |
| button_primary_text_color_dark="#000000", | |
| button_secondary_background_fill="#FFFFFF", | |
| button_secondary_background_fill_dark="#FFFFFF", | |
| button_secondary_text_color="#000000", | |
| button_secondary_text_color_dark="#000000", | |
| background_fill_primary="#FFFFFF", | |
| background_fill_primary_dark="#FFFFFF", | |
| background_fill_secondary="#FFF8E7", | |
| background_fill_secondary_dark="#FFF8E7", | |
| block_background_fill="#FFFFFF", | |
| block_background_fill_dark="#FFFFFF", | |
| block_label_text_color="#000000", | |
| block_label_text_color_dark="#000000", | |
| block_title_text_color="#000000", | |
| block_title_text_color_dark="#000000", | |
| input_background_fill="#FFFFFF", | |
| input_background_fill_dark="#FFFFFF", | |
| panel_background_fill="#FFFFFF", | |
| panel_background_fill_dark="#FFFFFF", | |
| border_color_primary="#000000", | |
| border_color_primary_dark="#000000", | |
| ) | |
| # Force light variant always — drop .dark class on root + add .neobrut for CSS scoping | |
| _NEOBRUT_BOOTSTRAP = ( | |
| "<script>" | |
| "(function(){" | |
| "function fix(){" | |
| "var roots=[document.documentElement, document.body, document.querySelector('.gradio-container')];" | |
| "roots.forEach(function(el){if(el){el.classList.remove('dark');el.classList.add('neobrut');}});" | |
| "}" | |
| "fix();" | |
| "document.addEventListener('DOMContentLoaded',fix);" | |
| "var mo=new MutationObserver(fix);" | |
| "mo.observe(document.documentElement,{attributes:true,attributeFilter:['class']});" | |
| "})();" | |
| "</script>" | |
| ) | |
| with gr.Blocks(title="Whisper Speaker Diarization", css=_THEME_CSS, head=_HEAD, theme=_THEME) as demo: | |
| gr.HTML(_NEOBRUT_BOOTSTRAP) | |
| gr.HTML('<div class="neobrut-brand">WHISPER × DIARIZE <span class="neobrut-brand-tag">v3.1</span></div>') | |
| with gr.Row(elem_classes="brut-workspace"): | |
| with gr.Column(scale=1): | |
| stepper = build_stepper() | |
| with gr.Column(scale=2): | |
| dock = build_results_dock() | |
| stepper["yt_btn"].click( | |
| handlers.download_youtube_for_ui, [stepper["yt_url"]], | |
| [stepper["video_in"], stepper["yt_status"]], | |
| ) | |
| stepper["run_btn"].click( | |
| handlers.run_unified, | |
| [stepper["yt_url"], stepper["video_in"], stepper["language"], stepper["num_speakers"]], | |
| [ | |
| dock["df_out"], dock["csv_out"], dock["srt_out"], dock["sysinfo"], | |
| stepper["progress_log"], stepper["error_card"], | |
| dock["merged_state"], dock["wav_state"], | |
| dock["audio_player"], dock["seek_bus"], stepper["video_in"], | |
| ], | |
| show_progress="minimal", | |
| show_progress_on=[stepper["progress_log"]], | |
| ) | |
| dock["edit_btn"].click( | |
| handlers.enter_edit_mode, [dock["merged_state"]], | |
| [dock["df_out"], dock["edit_btn"], dock["apply_btn"], dock["cancel_btn"], dock["edit_mode_state"]], | |
| ) | |
| dock["cancel_btn"].click( | |
| handlers.cancel_edit, [dock["merged_state"]], | |
| [dock["df_out"], dock["edit_btn"], dock["apply_btn"], dock["cancel_btn"], dock["edit_mode_state"]], | |
| ) | |
| dock["apply_btn"].click( | |
| handlers.apply_renames, [dock["df_out"], dock["merged_state"]], | |
| [dock["df_out"], dock["csv_out"], dock["srt_out"], | |
| dock["edit_btn"], dock["apply_btn"], dock["cancel_btn"], | |
| dock["edit_mode_state"], dock["merged_state"]], | |
| ) | |
| dock["df_out"].select( | |
| handlers.on_row_select, [dock["merged_state"], dock["edit_mode_state"]], [dock["seek_bus"]], | |
| ) | |
| demo.queue(default_concurrency_limit=1) | |
| if __name__ == "__main__": | |
| demo.launch(debug=False, ssr_mode=False, allowed_paths=[str(OUTPUT_DIR)]) | |