"""Tab builders for EVE-based Gradio demos. Both tabs (Offline Inference, Live Inference) follow the same pattern: - Outer ``gr.TabItem`` with the demo-supplied label. - Demo-specific feature checkboxes built via a caller-provided callable so each demo defines its own feature set (Face Detection / Person / Hand Detection / Face ID / …). - Optional ``extras_builder`` hook for demo-specific extras inside the tab (e.g. eve_hmi's Face ID summary thumbnails). The tab builders return the underlying components so the caller can wire events (``process_btn.click``, ``webrtc_stream.stream``, etc.) outside. """ from __future__ import annotations from typing import Callable, TypeVar import gradio as gr from live_inference import RtcConfigurationInput, build_webrtc_stream from video_processing import VideoLimits, build_video_constraints_accordion # The exact tuple of Checkbox components is demo-specific. We let the # caller's checkbox-builder define the shape and return it transparently. TCheckboxes = TypeVar("TCheckboxes") def build_offline_inference_tab( *, feature_checkbox_builder: Callable[..., TCheckboxes], example_videos: list, video_limits: VideoLimits, extras_builder: Callable[[], None] | None = None, tab_label: str = "Offline Inference", feature_hint: str = "applied when processing starts", ) -> tuple[ gr.TabItem, gr.Video, gr.Video, TCheckboxes, gr.Button, gr.Dataset, ]: """Build the Offline Inference tab. Must be called inside a ``gr.Tabs`` context. Args: feature_checkbox_builder: Callable that builds the demo's feature checkboxes inside the tab. Receives the keyword ``hint`` (a short string shown next to the "Features" heading). Returns a tuple of ``gr.Checkbox`` instances — the same tuple is returned unchanged so the caller can wire events. example_videos: Pre-loaded example videos (list of ``[path]`` rows). video_limits: Upload constraints rendered in the accordion. extras_builder: Optional callable invoked after the input/output video columns to add demo-specific widgets (e.g. a Face ID summary). Called inside the same row, so it shares horizontal space with the videos. tab_label: Tab label text (default ``"Offline Inference"``). feature_hint: Short hint shown next to the Features heading. Returns: ``(tab, input_video, output_video, checkboxes, process_btn, example_dataset)``. ``checkboxes`` is exactly what ``feature_checkbox_builder`` returned. """ with gr.TabItem(tab_label) as video_tab: with gr.Accordion("Instructions", open=False): gr.Markdown( "1. Select the features that will be processed on the video\n" "2. Select a video (or upload your own in the Input Video frame)\n" "3. Press the **Process Video** button\n\n" "Once the video has been processed, you can play the video in the " "Output Video frame" ) checkboxes = feature_checkbox_builder(hint=feature_hint) with gr.Accordion("Video Examples", open=True): example_dataset = gr.Dataset( components=[gr.Video(visible=False)], samples=example_videos, show_label=False, ) process_btn = gr.Button("Process Video", variant="primary", interactive=False) build_video_constraints_accordion(video_limits) with gr.Row(equal_height=True): with gr.Column(scale=5): input_video = gr.Video(label="Input Video", sources=["upload", "webcam"]) with gr.Column(scale=5): output_video = gr.Video(label="Output Video") if extras_builder is not None: extras_builder() return video_tab, input_video, output_video, checkboxes, process_btn, example_dataset def build_live_inference_tab( *, rtc_configuration: RtcConfigurationInput, feature_checkbox_builder: Callable[..., TCheckboxes], extras_builder: Callable[[], None] | None = None, max_fps: int = 15, width: int = 640, height: int = 360, tab_label: str = "Live Inference", description_html: str = ( "
Use your webcam for real-time inference. " "Select features below, then grant camera access when prompted.
" ), ) -> tuple[gr.TabItem, object, TCheckboxes]: """Build the Live Inference tab with feature checkboxes + WebRTC stream. Args: rtc_configuration: ICE configuration dict, callable that returns one, or ``None`` for direct connection. A callable is invoked per-connection by FastRTC, allowing credential refresh. feature_checkbox_builder: Callable that builds the demo's feature checkboxes (same shape as in the offline tab). extras_builder: Optional callable invoked after the WebRTC stream for demo-specific widgets (e.g. Face ID summary). max_fps: Maximum frame rate requested from the browser camera. width / height: Camera frame dimensions in pixels. tab_label: Tab label text. description_html: Optional HTML shown above the stream. Returns: ``(tab, webrtc_stream, checkboxes)``. """ with gr.TabItem(tab_label) as tab: if description_html: gr.HTML(description_html) checkboxes = feature_checkbox_builder() webrtc_stream = build_webrtc_stream( rtc_configuration, max_fps=max_fps, width=width, height=height ) if extras_builder is not None: extras_builder() return tab, webrtc_stream, checkboxes