Skip to content

About

Free browser live view for Blackmagic PYXIS 6K over Ethernet — SRT → WHIP → WebRTC (mediaMTX) with MSE fallback. ~0.2s latency, no extra hardware.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

PYXIS 6K over Ethernet — low-latency browser live view

Free, no-extra-hardware live view of your Blackmagic PYXIS 6K in any browser over plain Ethernet — no ATEM Streaming Bridge needed. A plug-and-play system that turns the camera into a sub-half-second live view in your browser

  • WebRTC primary — camera SRT → mediaMTX → browser, ~0.2–0.4s glass-to-glass
  • fMP4/MSE fallback — automatic when WebRTC can't be used (~0.4–0.8s)
  • Pure passthrough on the low-latency path — no re-encode, no fragment buffering
  • No hardware decoders, no ATEM boxes, no cloud — just the camera, a PC and a browser (Chrome/Edge)

What this replaces: Blackmagic's official route for on-set monitoring is an ATEM Streaming Bridge box. This project does the same job entirely in software on a Windows PC you already own — free, no purchase, no extra hardware.

┌──────────┐     SRT caller      ┌──────────┐  ffmpeg -f whip   ┌──────────┐   WHEP    ┌─────────┐
│  PYXIS   │ ──────────────────► │  PC app  │ ────────────────► │ mediaMTX │ ────────► │ Browser │
│   6K     │  192.168.x.x:9000   │ (Node)   │   (H.264 copy)    │  :8889   │           │  video  │
└──────────┘                     └──────────┘                   └──────────┘           └─────────┘
                                   │   └─ fMP4 pipe:1 ── WS relay ──► MSE fallback
                                   └─ camera REST proxy (/cam/*)

Quick start (Windows)

What you get: a web page at http://localhost:9090 that live-views your PYXIS over the LAN — no internet, no cloud, no SDKs. The app manages ffmpeg + mediaMTX for you, auto-respawns either if it crashes, and force-restarts ffmpeg if it silently wedges on a cold start (WHIP vs. just-booted mediaMTX race). Other devices on your network can open the same page (see Multiple viewers below).

  1. Install ffmpeg (>= 8.x, needs the native whip muxer and libsrt): winget install Gyan.FFmpeg — or download from gyan.dev and make sure ffmpeg is on PATH.

  2. Download mediaMTX v1.20.x (single exe) from github.com/bluenviron/mediamtx/releases and place it at mediamtx/mediamtx.exe (it sits next to mediamtx.yml). mediamtx.yml is verified against v1.20.x; newer major releases may rename config keys — if mediaMTX fails to start, check its changelog before upgrading.

  3. Edit mediamtx/mediamtx.yml → webrtcAdditionalHosts is empty by default (auto-detected from your PC's NIC). If browser clients can't connect, set your PC's LAN IP, e.g. [192.168.1.50].

  4. Install the app:

    npm install
    
  5. Run it — double-click Start-PyxisLive.cmd (it asks for the camera IP + login once, remembers them on your PC, opens the page in Chrome by itself — the stream needs Chrome's WebRTC, not your default browser; keep the launcher's window open while you use the app). Or from a terminal:

    $env:CAMERA="PUT_YOUR_CAMERA_IP"   # your camera's IP — this is required
    npm start
    
  6. Open the page in Chrome or Edge: http://localhost:9090

  7. Configure the camera once (next section), then start streaming on the camera — the page auto-opens the SRT listener and the picture appears on its own.

The app auto-starts mediaMTX on boot and auto-respawns the SRT listener if the camera drops — no other services to babysit.

The app never starts or stops the camera. After the platform XML is uploaded and selected, you must press Start/Stream on the camera yourself. Once streaming, the camera's SRT caller reconnects on its own if the PC listener restarts (see docs/TROUBLESHOOTING.md).

Camera setup (one time)

The camera's livestream settings are a "custom platform" XML file. A ready one ships in this repo as streaming.xml ("Pyxis Local SRT", 1080p24, H.264, 16 Mbps, SRT caller to your PC).

  1. Power the camera, connect it to the same network as the PC, note its IP.
  2. Edit the SRT target in streaming.xml — the <url> value srt://PUT_YOUR_PC_IP:9000?mode=caller must point at the PC running this app (keep :9000 unless you changed SRT_PORT).
  3. Set fps in the <config> line to whatever frame rate you normally stream at (fps="24", fps="30", …) — the camera caps the live stream to that rate.
  4. Upload the platform with curl (self-signed HTTPS cert is expected) — replace the placeholders first (PUT_YOUR_CAMERA_USER/PUT_YOUR_CAMERA_PASS = your camera's REST login, PUT_YOUR_CAMERA_IP = your camera's address):
    curl.exe -ku PUT_YOUR_CAMERA_USER:PUT_YOUR_CAMERA_PASS -X PUT -H "Content-Type: application/xml" --data-binary "@streaming.xml" \
      "https://PUT_YOUR_CAMERA_IP/control/api/v1/livestreams/customPlatforms/Pyxis_SRT.xml"
    
  5. On the camera: Setup → Live Streaming → Platform → "Pyxis Local SRT", ensure the profile "Streaming High" / server "Primary" is selected (or just follow the camera's on-screen streaming flow and pick your custom platform).
  6. Open the page in Chrome or Edge — it auto-opens the SRT listener on this PC, and the browser view goes live on its own as soon as the camera is streaming.

Set CAMERA_USER / CAMERA_PASS to your own camera's REST credentials — replace the placeholders (PUT_YOUR_CAMERA_USER, PUT_YOUR_CAMERA_PASS, PUT_YOUR_CAMERA_IP) below with your actual values. The PYXIS REST API has no documented factory-default password (it needs the web media manager enabled in Blackmagic Camera Setup, and authentication is whatever the owner has configured — so use the login YOU set on your camera, not anything written here).

Configuration (environment variables)

Env var Default Purpose
PORT 9090 Web page / REST API / WS relay
CAMERA (required — set it) Camera IP
CAMERA_USER (required — set it) Camera REST user
CAMERA_PASS (required — set it) Camera REST password
FFMPEG ffmpeg ffmpeg binary (needs whip muxer)
MEDIAMTX mediamtx/mediamtx.exe mediaMTX binary
SRT_PORT 9000 SRT listener port (camera's caller URL target)
MY_IP (auto-detected) PC address advertised to the camera + viewers. Auto-detect skips VPN/tunnel adapters and prefers a 192.168/172.16 LAN address; override if you need a specific NIC (e.g. 192.168.1.50)
CAMERA_CONTROL_DIR (unset) Dev-only: local folder with the camera's documentation.html + spec YAMLs, so the Camera tab's discovery runs without the camera on the network

Ports used

Port Protocol Purpose
9090 TCP page, REST API, WS relay
9000 SRT camera → PC ingest
8889 TCP mediaMTX HTTP (WHIP in / WHEP out)
8189 UDP WebRTC media plane

Same-PC viewing needs no firewall changes. The first time you run the app, Windows Firewall pops a security alert for each of node.exe, ffmpeg.exe and mediamtx.exe — accept ("Allow access") each prompt and LAN viewers are covered automatically, no per-port rules needed. You'll get the same prompts for the camera's SRT ingest on 9000.

If the prompts were declined (or firewall rules were removed), LAN viewers then need these inbound rules in Windows Firewall:

Port Why a viewer needs it
9090 page, REST API, WS relay
8889 mediaMTX WHEP handshake
8189 WebRTC media (UDP)

9000 (SRT) is only ever used by the camera connecting to this PC, never by browser viewers.

Multiple viewers (desktop + laptop, WiFi)

The same page runs on any device on your network — a desktop, a laptop on WiFi, a phone — all watching the PYXIS at once. Each browser runs its own WebRTC (WHEP) session, so there's no channel limit; viewers that can't ride WebRTC auto-fall back to the slightly-delayed MSE path.

  • Address: open http://<PC_IP>:9090 on each device, where <PC_IP> is this PC's LAN address (same one you put in streaming.xml / mediamtx.yml, or see http://localhost:9090/api/config).
  • Firewall: if you accepted the first-run Windows prompts, nothing to do. Otherwise whitelist 8889/8189/9090 inbound — see Ports used.
  • WiFi: works, but wireless adds jitter. A WiFi viewer may occasionally trip the WebRTC health check and slide to the MSE fallback (~0.4–0.8s) until it stabilizes. Wired is steadier for the SRT ingest; each WiFi client just monitors.
  • Bandwidth: each WebRTC viewer is one extra stream from mediaMTX to that browser. On a 1 Gb/s switch a handful of 1080p viewers is trivial; over WiFi expect per-client headroom to matter more.

Stopping the app

The page has a Stop server button (top-right). It shuts down this Node app on this PC — ffmpeg, mediaMTX, and the web page — and you're prompted to confirm first. It only stops the PC side: your camera keeps streaming on its own (the camera is always controlled from the camera itself, never from this page). Restart the app anytime with npm start. Anyone with the page open and a confirmed click can stop the server.

Camera control (Camera tab) — WIP

Work in progress. The Camera tab mirrors the camera's menus and applies changes live over the REST API, but it is still under active development — verify anything critical on the camera itself.

Alongside the live view, the page has a second tab — Camera — that mirrors the camera's own on-screen menu system (Exposure, Lens, Color, Record, Media, Monitor, Audio, Setup, Presets, Livestream) and drives the same controls over the camera's REST API. Instead of a hard-coded list of controls (which drifts as the firmware changes), it does dynamic discovery: the server fetches the camera's own OpenAPI/AsyncAPI YAML specs from /control/documentation.html, parses them, and the page builds itself from that registry (GET /api/cam/registry).

  • Camera-style menus. Sections map to the camera's real on-screen menus. Each section is built from whatever the connected camera exposes; per-display monitor settings and per-channel audio settings are generated from what the camera reports.
  • Apply on change. Dropdowns, toggles and fields apply the moment you change them — no Apply buttons — with a toast: a green toast on success, a red toast with the camera's reason on failure (and the control reverts to the camera's last known value).
  • Live values + belt. Every row shows the camera's current value, polling while that section is open. A status belt across the top shows Streaming · 1080p24 · 8 Mbps and glows green/orange/red with the livestream state.
  • "Supported" seeding. Endpoints like /video/supportedISOs fill the dropdowns on the fly (ISO 100–25600, Gain −12 … +36 when the camera says so).
  • Raw API left in Advanced. The Advanced rail lists every endpoint the camera exposes, verbatim (GET on expand, PUT/POST with generated forms, DELETE buttons), so nothing discoverable is hidden from power users.
  • Honest about camera quirks (verified PYXIS firmware behavior): the Livestream section notes that PUT /livestreams/0/stop always 403s while Streaming and that the camera cannot be remote-stopped — there is deliberately no fake "stop stream" button. Rebooting the camera asks for confirmation before it drops your SRT session.
  • All reads/writes go through the same /cam/* proxy, so the Content-Length fix, the env-only credentials and the self-signed-cert handling all apply. The browser never talks to the camera directly, and no IPs/credentials live in this page's code.

Deep-link to it directly: http://localhost:9090/?tab=control.

Latency

  • WebRTC path: ~0.2–0.4s glass-to-glass. The browser rides the live edge at 24.0 fps with ~0 frames dropped and ~7ms jitter. Remaining latency is almost entirely SRT buffering (both peers) + one decode frame.
  • MSE fallback: ~0.4–0.8s. Only used when WebRTC isn't available.
  • Measure ground truth with a stopwatch / running-clock video in front of the lens.

Browser support

Use Chrome or Edge (both Chromium). Firefox can't ride the WebRTC path here and will show a noticeably delayed MSE image instead.

Video only (no audio)

This system is video-only by design. The camera is configured to send audio in its SRT stream, but it is dropped on the PC:

  • WebRTC leg — the WHIP muxer in ffmpeg refuses to start without a stereo audio track, so a silent audio track is fed to it; the browser ignores it and only wires the video.
  • MSE fallback leg — fully silent.

If you ever want the camera's own audio, swap the silent shim for the real track in spawnFfmpeg() (-map 1:a:0 → -map 0:a:0, drop the anullsrc input). See docs/DESIGN.md.

Repo layout

server.js                  Node app: SRT->WHIP+fMP4 pipeline, supervisors, camera proxy, WS relay, OpenAPI discovery
public/                    Browser page: Live tab (WHEP-first player + MSE fallback) + Camera tab (camera-menu control)
public/control.js          Camera tab: mirrors the camera's on-screen menus, built from the OpenAPI/AsyncAPI registry
mediamtx/mediamtx.yml      WebRTC-only mediaMTX config (download mediamtx.exe here)
streaming.xml              Example camera "custom platform" (SRT caller, 1080p24)
docs/DESIGN.md             Deep dive: protocol flow, latency budget, WHIP/SPS-PPS gotchas
docs/TROUBLESHOOTING.md    Wedged streams, black video, restarts, Firefox, and more

Docs

  • docs/DESIGN.md — how it works end-to-end: WHEP handshake, why the WHIP leg must be -c:v copy (and never re-encoded), the silent-stereo-shim requirement, the supervisor design, code map.
  • docs/TROUBLESHOOTING.md — the failure modes we hit and their cures: black video / PLI storms, the "stream is active to a different destination" wedge, restart procedures, browser gotchas.

License (GPL-3.0)

This project is GPL-3.0. In plain terms:

  • Use it, modify it, build on it — free, for personal or open-source projects.
  • Share improvements — if you distribute a modified/derived version, you must release your source under the same copyleft terms.
  • Paid / closed-source use — everyone is free to license it as they see fit, but anyone who wants to use this work as the basis of a paid or proprietary product must either keep it open under GPL or pay the copyright holder for a commercial license (contact the author). You can't silently bundle it into a closed paid product without paying.

The repo's npm dependencies (ws, js-yaml) are MIT, which is compatible with GPL-3.0. ffmpeg and mediaMTX are separately-installed third-party binaries and not part of this codebase.

Looking to use this in a paid or closed-source product? See COMMERCIAL.md for a commercial license.

About

Free browser live view for Blackmagic PYXIS 6K over Ethernet — SRT → WHIP → WebRTC (mediaMTX) with MSE fallback. ~0.2s latency, no extra hardware.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages