Skip to content

Streamcatcher

A cross-platform Python CLI that connects to an RTSP or RTMP video stream and views it in a small desktop window — including 360° panoramic cameras, which it reprojects into a flat pan/tilt/zoom "look-around" viewport. Pure Python, powered by OpenCV.

The same control core is importable, so another program — or an AI agent — can open a stream headlessly, drive the look-around, and pull frames over an HTTP API.

Status

Early development, built in small, tested vertical slices. Live playback, the 360° equirectangular look-around viewport, snapshots, auto-reconnect, and the HTTP control API all work today. Video only — OpenCV decodes video only.

What you can do

  • View any RTSP/RTMP stream

    Open a live stream in a native window on macOS, Linux, or Windows — no external media player required.

    CLI usage

  • Look around a 360° camera

    Reproject an equirectangular 360° panorama into a flat viewport you steer with the keyboard.

    360° & cameras

  • Drive it from Python

    StreamSession gives you open / read / render / look-around / snapshot with no window and no keyboard loop.

    Python API

  • Serve it over HTTP

    Run a localhost control API so another program or an AI agent can open sessions, aim the camera, and grab frames.

    HTTP control API

Quick start

pip install streamcatcher

# View a plain 2D stream
streamcatcher play rtsp://camera.local:554/stream1 -b opencv

# View a 360° camera with a look-around viewport
streamcatcher play rtsp://camera.local/live -b opencv -p equirect

In the viewer window: W/A/S/D aim · +/- zoom · p snapshot · q quit.

Design in one breath

  • Offline-first. The package and the whole test suite run with no network, no credentials, and no live stream. OpenCV is imported lazily, only on the live path.
  • Secrets-safe. Stream URLs (which may embed user:pass@host) are wrapped in SecretStr and scrubbed from logs by a redacting filter — and never returned by the HTTP API.
  • One control core. The GUI window and the HTTP server both drive the same headless StreamSession, so the controls live in exactly one place.

See Architecture for the full picture.