capture_helper.api module
Capture Helper — FastAPI HTTP surface.
Exposes every public function in capture_helper as an HTTP
endpoint so capture-helper can be dropped behind any reverse proxy
and consumed by other services. Kept intentionally minimal:
Query / form parameters for device selection.
JSONResponsefor device enumeration / picking / input-args (small structured payloads).StreamingResponse(ZIP) for camera snapshots — one download per call with the raw.bgr24frames inside.FileResponsefor the WAV output from/capture/mic.BackgroundTaskscleans temp files after the response has been streamed — no leftover garbage on disk.
Install the extra to get the runtime dependencies:
pip install 'capture-helper[api]'
Then run the app with any ASGI server:
uvicorn capture_helper.api:app --host 0.0.0.0 --port 8000
Usage Example
>>> # Start the server:
>>> # uvicorn capture_helper.api:app --reload
>>> # List devices:
>>> # curl http://localhost:8000/sources
>>> # Pick a camera by name:
>>> # curl 'http://localhost:8000/pick?kind=camera&name=FaceTime'
>>> # Grab 10 frames at 320x240 into a ZIP:
>>> # curl -o frames.zip \
>>> # 'http://localhost:8000/capture/camera?output_width=320&output_height=240&max_frames=10'
>>> # Record 3s of mic PCM to a WAV:
>>> # curl -o mic.wav 'http://localhost:8000/capture/mic?seconds=3'
>>> # Full OpenAPI docs at http://localhost:8000/docs
- capture_helper.api.capture_camera(background, name=fastapi.Query, index=fastapi.Query, width=fastapi.Query, height=fastapi.Query, fps=fastapi.Query, output_width=fastapi.Query, output_height=fastapi.Query, pad_color=fastapi.Query, max_frames=fastapi.Query)
Grab
max_framesframes from the selected camera. Response is a ZIP.
- capture_helper.api.capture_mic(background, name=fastapi.Query, index=fastapi.Query, seconds=fastapi.Query, sample_rate=fastapi.Query, frame_ms=fastapi.Query, mono=fastapi.Query)
Record
secondss of PCM from the selected microphone into a WAV file.
- capture_helper.api.gui()
Serve the self-contained single-page scene-configurator GUI.
The page (defined in
capture_helper.gui) is a build-step-free HTML + Tailwind-CDN + vanilla-JS client that calls the very same/sources//preview/...//scene/...endpoints defined here. It adds no server-side logic — it is purely a friendlier front door to the API.- Returns:
The complete HTML document (status 200,
text/html).- Return type:
HTMLResponse
- capture_helper.api.health()
Simple liveness probe — no dependency check, just proves the app is up.
- Return type:
- capture_helper.api.input_args(kind=fastapi.Query, name=fastapi.Query, index=fastapi.Query)
Print the ffmpeg
-f DRIVER -i SPECargv fragment for a resolved device.
- capture_helper.api.pick(kind=fastapi.Query, name=fastapi.Query, index=fastapi.Query)
Resolve a single capture device by kind / name / index.
- capture_helper.api.preview_camera_jpg(name=fastapi.Query, index=fastapi.Query, output_width=fastapi.Query, output_height=fastapi.Query)
Return a single live JPEG snapshot from the selected camera.
- Parameters:
name (optional) – Device selectors forwarded to
capture_helper.pick_source().index (optional) – Device selectors forwarded to
capture_helper.pick_source().output_width (int) – Preview size (aspect-preserving fit-and-pad).
output_height (int) – Preview size (aspect-preserving fit-and-pad).
- Returns:
A
image/jpegbody (200), or HTTP 404 when no matching camera exists, or HTTP 503 when a frame cannot be captured (permission / busy device).- Return type:
Response
- capture_helper.api.preview_camera_mjpeg(name=fastapi.Query, index=fastapi.Query, output_width=fastapi.Query, output_height=fastapi.Query, fps=fastapi.Query, max_frames=fastapi.Query)
Stream the selected camera as
multipart/x-mixed-replaceMJPEG.The browser renders this directly in an
<img>tag, giving a live preview tile with no client-side decoding. The stream ends when the client disconnects (or aftermax_framesif given).- Parameters:
name (optional) – Device selectors forwarded to
capture_helper.pick_source().index (optional) – Device selectors forwarded to
capture_helper.pick_source().output_width (int) – Per-frame preview size.
output_height (int) – Per-frame preview size.
fps (float) – Preview frame rate (kept low by default to stay cheap).
max_frames (int, optional) – Bound the stream length.
- Returns:
A
multipart/x-mixed-replacebody, or HTTP 404 when no camera matches.- Return type:
StreamingResponse
- capture_helper.api.preview_mic_level(name=fastapi.Query, index=fastapi.Query, sample_rate=fastapi.Query, window_ms=fastapi.Query)
Capture a short slice of live audio and return its level (for a VU meter).
- Parameters:
name (optional) – Device selectors forwarded to
capture_helper.pick_source().index (optional) – Device selectors forwarded to
capture_helper.pick_source().sample_rate (int) – Capture sample rate.
window_ms (int) – Approximate capture window used to compute the level.
- Returns:
{"rms", "rms_dbfs", "peak", "peak_dbfs"}, or HTTP 404 when no matching microphone exists.- Return type:
JSONResponse
- capture_helper.api.root()
Redirect the bare root to the GUI so opening the server just works.
- Returns:
A 307 redirect to
/gui. A human hittinghttp://host:port/almost always wants the scene configurator, not a 404; machines call the documented endpoints directly, so this is safe.- Return type:
RedirectResponse
- capture_helper.api.scene_auto()
Return a starter scene auto-populated from this host’s live devices.
- Returns:
A valid scene (first camera full-canvas + first microphone, if any). Empty of sources on a headless host with no devices.
- Return type:
JSONResponse
- async capture_helper.api.scene_load(file=fastapi.File)
Validate an uploaded scene file and echo it back as JSON.
Lets the GUI round-trip a scene through the server’s own validator (so a hand-edited file is rejected with a clear message before the front-end adopts it).
- Parameters:
file (UploadFile) – The uploaded
.scene.jsonfile.- Returns:
The validated scene, or HTTP 400 when the file is not a valid scene.
- Return type:
JSONResponse
- async capture_helper.api.scene_save(background, request)
Validate a posted scene and return it as a downloadable JSON artifact.
The request body is the scene JSON (as produced by the GUI). It is validated server-side (the same validation the CLI uses) and written to a temp file, then streamed back as a
.scene.jsondownload.- Parameters:
background (BackgroundTasks) – Used to clean the temp file after the response is sent.
request (Request) – Carries the raw scene JSON body.
- Returns:
The validated scene as a downloadable file, or HTTP 400 on a bad scene.
- Return type:
FileResponse