RTSP server development and verification

The Go manager in internal/rtspserver supervises the C++ helper in native/rtsp-server. Protocol version 1 uses bounded JSON messages over private stdin/stdout pipes. Credentials must never be placed in arguments or diagnostics. The helper needs GStreamer RTSP Server, pbutils, JSON-GLib, UDP/RTP/RTSP elements, MPEG-TS/MP4/Matroska demuxers, H.264/H.265/AAC parsers and payloaders, and KLV payloading. It does not decode or transcode RTSP output.

Build with scripts/build-rtsp-server.ps1 on Windows or scripts/build-rtsp-server.sh on Linux. CMake, Ninja, and pkg-config are required. The Windows script uses the repository's MinGW GStreamer installation and copies the compiler's matching pthread runtime. skyview-rtsp-server --protocol-version must print 1.

Linux setup and development container

On Debian/Ubuntu, run make setup-rtsp-linux before make build-rtsp-server. The Linux scripts/codex_bootstrap.sh workflow runs this setup automatically. Setup installs native build tools, JSON-GLib, packet-capture headers, FFmpeg, and the system development libraries needed by the local GStreamer build. It selects SkyView's GStreamer 1.28.7 installation, then adds any missing AAC/Matroska, UDP/RTP/RTSP, MPEG-TS and H.264/H.265 plugins and builds the matching RTSP Server library. Source archives are checked against pinned SHA-256 hashes. Existing unrelated plugins are kept. Setup needs sudo for system packages or a system SDK; a project-local SDK stays under .cache. Private SDK access uses the existing ImpleoTV Git setup.

For an already provisioned host, use bash scripts/setup-rtsp-linux.sh --no-system-packages. Other distributions must first supply C++17, CMake 3.24+, Ninja, pkg-config, Meson 1.4+, Python/venv, curl, xz and GLib/JSON-GLib/zlib development packages, plus the dependencies of their selected GStreamer installation. Do not copy older distribution plugins into the pinned SDK.

The development container explicitly builds RTSP Server and all required plugin groups from the same GStreamer source tag. It installs JSON-GLib, builds the helper into /usr/local/bin, and checks its protocol version. Rebuild the dev container after updating these dependencies. make build-rtsp-server updates the workspace helper in bin/ during development; make run-server and make frontdev select that helper. The dev-container environment points direct Go launches at the image's /usr/local/bin/skyview-rtsp-server helper.

Both development and production Docker builds run the shared plugin check. Run it manually in the selected Linux environment with:

./scripts/with-gstreamer-linux.sh bash scripts/verify-rtsp-dependencies.sh --build
./scripts/with-gstreamer-linux.sh bash scripts/verify-rtsp-dependencies.sh --runtime

The build check also requires the RTSP Server, RTSP, pbutils, app and JSON-GLib development libraries. The runtime check loads every required element, including both H.264/H.265 payloaders and depayloaders, AAC and KLV. KLV requires no decoder. The production image copies the matching RTSP Server library from its builder, installs JSON-GLib, and checks the helper's linked libraries and protocol. RTSP defaults need TCP 8554 and UDP 10000–10999 reachable from clients. The dev container uses host networking; Docker deployments must publish those ports when using bridge networking.

Deterministic media fixtures

Native tests are opt-in. Use six-second, 25 FPS fixtures with one-second GOPs; the loop and decoded-frame assertions depend on these properties. With FFmpeg on PATH, generate the base fixture:

ffmpeg -f lavfi -i testsrc2=size=320x180:rate=25 -f lavfi -i sine=frequency=440:sample_rate=44100 -t 6 -c:v libx264 -g 25 -keyint_min 25 -sc_threshold 0 -c:a aac fixture.mp4
ffmpeg -i fixture.mp4 -c copy fixture.ts
ffmpeg -i fixture.mp4 -c copy fixture.mkv
ffmpeg -i fixture.mp4 -c:v libx265 -x265-params keyint=25:min-keyint=25:scenecut=0 -c:a copy fixture-h265.mp4

To generate deterministic ST 0601 metadata, configure the native build with -DSKYVIEW_RTSP_TEST_FIXTURE=ON, then build rtsp-test-fixture and run:

rtsp-test-fixture fixture.mp4 fixture-klv.ts

This adds six complete KLV units, with one-second precision timestamp increments and valid checksums. It is a test tool, not part of the installed application.

Automated checks

Set absolute paths for these environment variables:

Variable Value
SKYVIEW_RTSP_NATIVE_TEST 1
SKYVIEW_RTSP_SERVER Built native helper
SKYVIEW_RTSP_TEST_FILE Six-second fixture
SKYVIEW_RTSP_KLV_FILE Generated KLV TS fixture

Run the package with race detection:

& ./scripts/go-test-windows.ps1 -GoTestArgs @('-race', '-v', './internal/rtspserver', '-timeout', '240s')
go test -race -v ./internal/rtspserver -timeout 240s

Repeat TestNativeFileClients and TestNativeAuthenticationRecoveryAndLoop with TS, MKV, and H.265 fixtures. Checks include actual decoded frames after NPT seeking, two independent sessions, pause/resume, replay after EOF, TCP/UDP delivery, authentication, session limits, occupied ports, unsupported codecs, helper crash recovery, listener changes, publication edits, and stalled clients. Live tests exercise both direct UDP transport and an authenticated RTSP upstream with two clients, including one leaving while the other continues. Live reconnect tests also decode new clients after completed playback and DESCRIBE-only disconnects for both delivery formats, without restarting the helper. The adapter loop test detects unpaced replay bursts.

Set SKYVIEW_RTSP_VLC to a VLC executable and run TestNativeVLC to verify actual video/audio decoder counters for both formats over TCP and UDP. It starts isolated headless VLC instances with a temporary loopback control listener and does not test a visible player window or audible output.

KLV integrity tests inspect original MPEG-TS/RTP bytes and decode separate-track metadata with FFmpeg. Older FFmpeg versions strip an assumed five-byte metadata header from raw KLV PES, including from the original fixture. Do not interpret that receiver behavior as lost server bytes. The adapter timing test additionally checks timestamp rewriting and checksums without generating metadata.

TestRTSPNativeLocalEOFAndExplicitStop in internal/app consumes the existing local encoded playback branch while two RTSP clients seek independently. It checks that local EOF leaves file publications serving and explicit Stop removes them. It does not establish a browser WebRTC session.

Also run the ordinary stream/settings/API tests, npm test --prefix web, and npm run build --prefix web. API tests on Windows need SKY_VIEW_HOST_MEDIA set to a Windows path. Native skips must be reported separately from passing tests.

Release interoperability checks

  • Play TS, MP4, and MKV in a real browser while VLC clients occupy different positions. Pause and seek one client; verify the others continue unchanged.
  • Repeat looping and non-looping playback, TCP and UDP, H.264/H.265 with AAC, and KLV reception/timing in STView. Verify behavior after EOF and reconnect.
  • Exercise UDP, SRT, UDS where supported, PCAP, pattern, and licensed Flywheel source routes alongside existing recast outputs.
  • Remove and disable targets, change credentials, revoke Recast, restart the listener, kill the helper, and shut down the app. Check process/session cleanup.
  • Validate clean Windows installer, Linux server, and Docker installations with no development plugin paths. Test sustained connections and resource bounds.

These manual and packaging checks are separate release gates; the automated native tests do not substitute for VLC, STView, browser, or deployment testing.