Skip to content
/ prism Public

A low-latency live video server built on SRT ingest and WebTransport delivery, implementing Media over QUIC(MoQ) for browser playback via WebCodecs.

License

Notifications You must be signed in to change notification settings

zsiec/prism

Repository files navigation

Prism

A low-latency live video server built on SRT ingest and WebTransport delivery, implementing Media over QUIC Transport (MoQ) for browser playback via WebCodecs.

Prism accepts MPEG-TS streams over SRT, demuxes H.264/H.265 video and AAC audio, extracts CEA-608/708 captions and SCTE-35 cues, and delivers them to browser viewers over WebTransport with sub-second latency.

Features

  • SRT ingest — Push and pull modes via a pure Go SRT implementation
  • MoQ Transport — IETF draft-15 with LOC media packaging
  • H.264 and H.265 — Full NAL unit parsing, SPS extraction, codec string generation
  • Multi-track AAC audio — Dynamic subscription and switching
  • CEA-608/708 captions — Extracted from H.264 SEI messages
  • SCTE-35 — Splice insert and time signal parsing
  • SMPTE 12M timecode — Extracted from pic_timing SEI
  • GOP cache — Late-joining viewers start from the most recent keyframe
  • Multiview — 9-stream composited grid with per-tile audio solo
  • WebCodecs decoding — Hardware-accelerated video/audio decode in the browser

Quick Start

Prerequisites: Go 1.24+, Node.js 22+

make demo

This builds the server, builds the web viewer, and pushes a bundled test stream. Open https://localhost:4444/?stream=demo in your browser and accept the self-signed certificate.

Full broadcast demo

For the complete 9-stream experience with captions, SCTE-35 cues, timecode, and multi-track audio:

Additional prerequisites: ffmpeg (includes ffprobe)

make demo-full

This downloads Blender open-movie sources (~2 GB on first run), encodes 9 broadcast-realistic streams, and pushes them all simultaneously. Open https://localhost:4444/ to see the multiview grid.

Push your own stream

ffmpeg -re -i input.ts -c copy -f mpegts srt://localhost:6000?streamid=mystream

Then open https://localhost:4444/?stream=mystream.

Examples

Prism's packages are designed to be used as a library. The examples/ directory contains standalone programs showing how to embed Prism in your own application, and web/examples/ shows how to use the player in a browser.

Minimal server (Go)

A stripped-down version of cmd/prism — SRT ingest, demux, and WebTransport delivery in ~60 lines:

go run ./examples/minimal-server
ffmpeg -re -i input.ts -c copy -f mpegts srt://localhost:6000?streamid=demo
open https://localhost:4443

Custom ingest (Go)

Feed any MPEG-TS io.Reader directly into the pipeline — no SRT required:

go run ./examples/custom-ingest input.ts
open https://localhost:4443/?stream=file

Standalone web player (TypeScript)

Embed PrismPlayer in your own page using the built library bundle:

cd web && npm run demo:lib   # builds dist-lib/prism.js + starts Vite dev server
# (start the Prism server in another terminal: make run)
open http://localhost:5173/examples/standalone.html?stream=demo

The HTML is ~80 lines and shows the full API: create a player, connect to a stream key, handle lifecycle callbacks. See web/examples/standalone.html.

Building the web player library

To use PrismPlayer in your own project:

cd web && npm run build:lib   # outputs web/dist-lib/prism.js
import { PrismPlayer } from "./dist-lib/prism.js";

const player = new PrismPlayer(document.getElementById("container"), {
  onStreamConnected(key) { console.log("connected:", key); },
  onStreamDisconnected(key) { console.log("disconnected:", key); },
});
player.connect("demo");

The library also exports MoQTransport, MoQMultiviewTransport, MetricsStore, and related types for advanced use cases.

Architecture

SRT socket ──> io.Pipe ──> MPEG-TS Demuxer ──> Pipeline ──> Relay ──> Viewers
                               │                              │
                          H.264/H.265                   GOP cache
                          AAC (multi-track)             Fan-out
                          CEA-608/708                   Pre-computed wire data
                          SCTE-35
                          SMPTE 12M timecode

Single Go binary, vanilla TypeScript frontend:

Package Purpose
cmd/prism/ Entry point, wires everything together
ingest/ Stream ingest registry
ingest/srt/ SRT server (push) and caller (pull)
demux/ MPEG-TS demuxer, H.264/H.265/AAC parsers
media/ Frame types (VideoFrame, AudioFrame)
distribution/ WebTransport server, MoQ sessions, relay fan-out
moq/ MoQ Transport wire protocol codec
pipeline/ Demux-to-distribution orchestration
stream/ Stream lifecycle management
mpegts/ Low-level MPEG-TS packet/PES/PSI parsing
scte35/ SCTE-35 splice info encoding/decoding
certs/ Self-signed ECDSA certificate generation
webtransport/ WebTransport server on quic-go/HTTP3
web/ Vanilla TypeScript viewer (Vite, WebTransport, WebCodecs)

Configuration

Environment variables with defaults:

Variable Default Description
SRT_ADDR :6000 SRT ingest listen address
WT_ADDR :4443 WebTransport listen address
API_ADDR :4444 HTTPS REST API listen address
WEB_DIR web/dist Static file directory for the viewer
DEBUG (unset) Set to any value to enable debug logging

The server listens on:

  • :6000 — SRT ingest
  • :4443 — WebTransport (MoQ)
  • :4444 — HTTPS REST API + web viewer

REST API

Method Endpoint Description
GET /api/streams List active streams
GET /api/streams/{key}/debug Stream debug diagnostics
GET /api/cert-hash WebTransport certificate hash
POST /api/srt-pull Start an SRT pull from a remote address
GET /api/srt-pull List active SRT pulls
DELETE /api/srt-pull?streamKey=... Stop an SRT pull

Development

# Run all checks (must pass before committing)
make check

# Run tests with race detector
make test

# Format code
make fmt

# Build and run the server
make run

# Run web dev server with hot reload (port 5173, proxies API to :4444)
make dev

# Quick demo with bundled test stream
make demo

# Full 9-stream broadcast demo (requires ffmpeg)
make demo-full

make check requires staticcheck:

go install honnef.co/go/tools/cmd/staticcheck@latest

Security Considerations

Prism is designed for development and local-network use. If you expose it to untrusted networks, be aware of the following:

  • CORSAccess-Control-Allow-Origin: * is set on all responses. Production deployments should restrict this at a reverse proxy layer.
  • WebTransport originsCheckOrigin accepts all origins. Production deployments should enforce origin checks at the proxy layer.
  • SRT pull endpointPOST /api/srt-pull accepts arbitrary addresses, which could be used for SSRF. Restrict this endpoint to authenticated operators or internal networks.
  • Self-signed certificates — The server generates a self-signed certificate at startup. Production deployments should use proper TLS certificates.

See SECURITY.md for the vulnerability reporting policy.

Dependencies

Four direct Go dependencies:

Dependency License Purpose
quic-go/quic-go MIT QUIC + HTTP/3 for WebTransport
zsiec/ccx MIT CEA-608/708 closed caption extraction
zsiec/srtgo MIT Pure Go SRT implementation
golang.org/x/sync BSD-3-Clause errgroup for structured concurrency

License

MIT

About

A low-latency live video server built on SRT ingest and WebTransport delivery, implementing Media over QUIC(MoQ) for browser playback via WebCodecs.

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors