Files
XC_VM/tools/test-stream-generator
Divarion_D ee3707f79a feat(tools): synthetic test pattern in test-stream-generator (no input file)
Drop the sample.mp4 dependency: generate the source live with ffmpeg
`testsrc2` plus overlays — a big running stopwatch (elapsed), the real
wall-clock (handy to eyeball end-to-end latency), a frame counter and two
sweeping boxes; 1 kHz test tone for audio. Falls back to `testsrc` (v1,
built-in timestamp) when no TrueType font is found.

New flags: --size, --fps, --font (autodetected). Removed -i/--input and
--encode (the raw synthetic source is always encoded).

Long-run hardening so it can sit generating for days:
- --max-clients caps concurrent /stream.ts pulls (each is an ffmpeg);
  extra connections get 503 instead of piling up processes/FDs.
- Per-client socket write timeout + TCP keepalive drops a stalled or
  half-open peer instead of pinning its ffmpeg; hard-kill if terminate()
  does not reap it.
- Per-request access logging is off by default (an HLS player polls every
  few seconds and would flood the log over days); --verbose restores it.
2026-09-09 21:33:06 +03:00
..

Test stream generator

Generates a synthetic, ever-changing test pattern (no input file) and serves it as looping, HTTP-served streams you can paste into the panel as a live stream source — for end-to-end testing of the panel's streaming pipeline, including LLOD (the Low-Latency On-Demand processor in src/Cli/Commands/LlodCommand.php).

The picture is drawn live by ffmpeg from testsrc2 (a moving colour test pattern) with overlays: a large running stopwatch (elapsed), the real wall-clock time (compare it to your own clock to eyeball end-to-end latency), a frame counter, and two boxes sweeping across the frame. Audio is a low 1 kHz tone. Everything is paced in real time, so the panel sees a never-ending "live" channel.

Requirements

  • Python 3.7+ (standard library only — no pip install)
  • ffmpeg available in PATH (or pass --ffmpeg /path/to/ffmpeg)
  • A TrueType font for the on-screen clock/labels — autodetected (DejaVu / Liberation / fc-match). If none is found it falls back to testsrc (v1), whose built-in timestamp still gives a running timer plus the moving boxes.

Usage

cd tools/test-stream-generator
./stream_server.py

On start it prints the URLs to paste into the panel, e.g.:

  TS (LLOD): http://192.168.1.50:8088/stream.ts
  HLS      : http://192.168.1.50:8088/stream.m3u8
  M3U list : http://192.168.1.50:8088/playlist.m3u
  Index    : http://192.168.1.50:8088/

Stop with Ctrl+C.

Options

Flag Default Description
--host 0.0.0.0 Bind address.
--port 8088 Bind port.
--advertise-host autodetect Host/IP printed in the URLs (set this if the panel is on another host).
--size 1280x720 Frame size WxH.
--fps 25 Frame rate.
--font autodetect Path to a .ttf for the on-screen clock/labels.
--max-clients 32 Max concurrent /stream.ts pulls (each is an ffmpeg). Extra connections get 503.
--verbose off Log every HTTP request (off by default to keep long runs quiet).
--ffmpeg ffmpeg ffmpeg binary to use.
./stream_server.py --size 1920x1080 --fps 30
./stream_server.py --font /usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf

Endpoints

URL Content-Type Use
/stream.ts video/mp2t Continuous MPEG-TS — the endpoint for testing LLOD.
/stream.m3u8 application/vnd.apple.mpegurl Live HLS (sliding-window playlist + .ts segments).
/playlist.m3u audio/x-mpegurl M3U channel list with both URLs, for bulk import.
/ text/html Index page listing every URL.

Adding a stream in the panel

  1. Admin → Streams → Add/Edit stream.
  2. Paste a URL into the stream source field (stream_source[] in src/Public/Views/admin/stream.php). You can add several sources.
  3. Save and start the stream.

Testing LLOD specifically

  1. Use the /stream.ts URL as the stream source (LLOD requires an upstream that responds with Content-Type: video/mp2t, which this endpoint does).
  2. Enable the LLOD flag on the stream (streams.llod = 1).
  3. Start the stream and confirm the panel writes rolling 4-second segments to /home/xc_vm/content/streams/{id}_{segment}.ts and the client can play it.

Bulk import

Add http://HOST:8088/playlist.m3u as a playlist source to register both the TS and HLS test channels at once.

Notes

  • Each /stream.ts client gets its own ffmpeg; the HLS output is shared by a single background ffmpeg that auto-restarts if it dies.
  • HLS segments live in a temp directory (bounded by delete_segments) that is removed on exit.
  • Long-run safety (fine to leave running for days): concurrent /stream.ts pulls are capped (--max-clients), each client socket has a write timeout + TCP keepalive so a stalled/half-open peer is dropped instead of pinning an ffmpeg, and per-request access logging is off unless --verbose. The only cosmetic quirk over multi-day runs is the MPEG-TS 33-bit timestamp wrap (~26.5 h), which ffmpeg handles.
  • This is a development/testing tool. Do not expose it to the public internet.