Skip to content

feat: optional real-time monitoring dashboard - #6

Merged
pzanella merged 1 commit into
mainfrom
feat/dashboard
Oct 5, 2026
Merged

pzanella merged 1 commit into
mainfrom
feat/dashboard

Conversation

@pzanella

@pzanella pzanella commented Oct 5, 2026

Copy link
Copy Markdown
Owner

Adds an optional web dashboard, served from the same container as the stream. Without the new flags nothing changes: the pipeline stays exactly ffmpeg | moq import.

./stream.sh bbb --dashboard                  # http://localhost:8080
./stream.sh bbb --dashboard-port 9000        # another port (implies --dashboard)

What it shows:

  • Transport: connection state, RTT, packet loss, jitter, bitrate, with charts over the last 2 minutes.
  • Media: resolution, frame rate, end-to-end latency, codecs. On --abr-ladder, a selector picks the rendition.
  • Container logs, live, with filter and pause.

How it works:

  • The page is its own MoQ subscriber over WebTransport and measures that session: getStats() where the browser has it, the relay's PROBE RTT, RFC 3550 jitter on the video frames, the catalog for resolution and codecs.
  • End-to-end latency: the proxies before moq import record when each media time was due at the source (lib/ingest-clock.mjs; the base and SGAI pipelines get a small pass-through tap). The browser compares that with arrival time and corrects for the clock offset between host and podman VM.
  • dashboard/ (React, Vite, Tailwind CSS, Chart.js) is built in its own Containerfile stage. Only the static files and a dependency-free Node server (dashboard/server/) reach the image.
  • With --auth/--auth-key, the page uses the viewer token automatically.

Also:

  • The fMP4 parser moved from ssai/impression-tracker.mjs to lib/fmp4.mjs (FMP4Inspector), shared with the tap. No behavior change.
  • New CI job smoke-test-podman-dashboard. The .mjs syntax check now skips every node_modules/.
  • README: new section 9 "Dashboard: real-time monitoring", plus flags and troubleshooting. CHANGELOG and CONTRIBUTING updated.

Tested locally in Chrome:

  • Base, --abr-ladder (incl. switching renditions), CSAI, SSAI, SSAI + --auth on a custom port, and a 400px-wide layout.
  • --abr-ladder on a 5-vCPU podman VM shows the encode falling behind live (frame rate under nominal, latency growing). That is the stream's real state, not a dashboard issue.

Known limits: SGAI's host-side publisher logs stay in the terminal; packet loss needs WebTransport getStats() (headless Chrome reports none).

stream.sh --dashboard (or --dashboard-port N, default 8080) serves a web UI
from the container: connection state, RTT, packet loss, jitter, bitrate,
resolution, frame rate, end-to-end latency, codecs, and a live view of the
container's logs.

The page is its own MoQ subscriber over WebTransport and measures that
session. For end-to-end latency, the proxies before `moq import` record an
ingest clock (lib/ingest-clock.mjs, plus the new dashboard/server/ingest-tap.mjs
for the base and SGAI pipelines).

dashboard/ (React, Vite, Tailwind CSS, Chart.js) is built in its own
Containerfile stage; only the static output and a dependency-free Node server
reach the image. Without the flag the pipeline is unchanged.

Also moves the fMP4 parser from ssai/impression-tracker.mjs to lib/fmp4.mjs
(FMP4Inspector) so the tap can share it, and adds the CI job
smoke-test-podman-dashboard.
@pzanella
pzanella merged commit 5f94dec into main Oct 5, 2026
10 checks 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