Skip to content

rtsp: serve a scene as N fake RTSP cameras (sim side of #62)#54

Merged
bamdadd merged 2 commits into
mainfrom
feat/rtsp-server
Jul 20, 2026
Merged

rtsp: serve a scene as N fake RTSP cameras (sim side of #62)#54
bamdadd merged 2 commits into
mainfrom
feat/rtsp-server

Conversation

@bamdadd

@bamdadd bamdadd commented Jul 20, 2026

Copy link
Copy Markdown
Owner

The multicam-sim side of the RTSP fake-camera work (#62). Turns the simulator into a rig of fake IP cameras so multicam-rt can consume streamed video like real network cameras.

What it does

scripts/serve-rtsp.sh renders each camera of a domain-neutral scene with the pure-numpy software rasterizer (no GPU, dsl/raster.py) and publishes it as its own live rtsp:// stream:

scene ── rasterizer ──▶ ffmpeg (H.264) ──▶ mediamtx ──▶ rtsp://host:8554/cam0 …camN

One ffmpeg H.264 encoder per camera, a local mediamtx RTSP server, URLs printed on start. The scene is deterministic (rendered once, looped in real time). Verified end to end: serve-rtsp.sh --cameras 2 → pulled real rendered frames back over RTSP.

Honest scoping (documented in docs/rtsp.md)

Pixels only, no ground truth. RTSP carries encoded video, not the analytic manifest — the uv/visible/xyz_gt labels do not travel over the wire. So this is the realism / network-path test (and a rig-free way to exercise the distributed path later), NOT the eval path: MOTA/IDF1/pose scoring stays on the offline manifest. Said plainly in the docs.

Dependencies (documented)

brew install mediamtx        # zero-dependency RTSP server
brew install ffmpeg@7        # H.264 encode; @7 matches multicam-rt's ffmpeg-next consumer

ffmpeg@7 is pinned because the Rust consumer links FFmpeg 7 (FFmpeg 8 removed headers ffmpeg-next needs); the script prefers /opt/homebrew/opt/ffmpeg@7/bin/ffmpeg automatically.

Files

  • scripts/serve_rtsp.py — the server (build scene, render, mediamtx + per-camera ffmpeg, loop, print URLs).
  • scripts/serve-rtsp.sh — dependency-checked wrapper.
  • docs/rtsp.md — architecture, scoping, deps, run.

Clean-room, domain-neutral (items moving through a shared volume — no people, no proprietary terms). No AGPL. The multicam-rt ingest-rtsp consumer + demo wiring land in a sibling PR on the multicam-rt repo.

bamdadd added 2 commits July 20, 2026 20:48
…mtx)

scripts/serve-rtsp.sh renders each camera of a domain-neutral scene with
the pure-numpy software rasterizer (no GPU) and publishes it as its own
live rtsp:// stream through a local mediamtx (one ffmpeg H.264 encoder per
camera), printing the URLs. This turns the simulator into a rig of fake IP
cameras that multicam-rt's ingest-rtsp source consumes like real ones.

Pixels only, no ground truth: RTSP carries encoded video, not the analytic
manifest, so this is the realism / network-path test (and a rig-free way
to exercise the distributed path later), NOT the eval path. MOTA/IDF1/pose
scoring stays on the offline manifest. docs/rtsp.md says this plainly.

Deps (documented): brew install mediamtx + ffmpeg@7. ffmpeg@7 is pinned to
match the Rust consumer's ffmpeg-next (FFmpeg 8 dropped headers it needs);
the script prefers ffmpeg@7 automatically. Scene is domain-neutral (items,
no people, clean-room).
Use contextlib.suppress for the BrokenPipeError on stdin close, drop an
f-string without placeholders, and context-manage the mediamtx temp config.
Also applies ruff format to the ffmpeg argument list.
@bamdadd
bamdadd merged commit ee76dff into main Jul 20, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant