Media Edge

WHIP ingest, WHEP playback, and HLS/LL-HLS output for production Beam streams.

Beam's browser WebRTC path is still useful for interactive source preview and small rooms. Public streams, slow networks, Discord watch parties, and high viewer counts need a media edge. The media edge accepts a Beam source over WHIP, serves low-latency WHEP/WebRTC playback, and exposes HLS or LL-HLS for more resilient viewers.

WHIP ingest WHEP playback LL-HLS Stable HLS Optional simulcast Provider-ready SFU

Recommended topology

Interactive Beam path

The existing `/v1/streams/realtime` WebSocket path keeps browser publisher and viewer WebRTC working for live studio preview, direct viewers, and fast product demos.

Media edge path

Browser, game, mobile, or desktop companion sources publish a MediaStream to the media edge using WHIP. Viewers choose WHEP/WebRTC for low latency or HLS/LL-HLS for stability.

Provider choice

Use MediaMTX first for WHIP, WHEP, and LL-HLS output. Use LiveKit, mediasoup, Janus, or another SFU when you need full multi-layer simulcast routing and room-level media control.

Beam API surface

Beam now exposes media-edge discovery and per-stream media URLs.

GET /api/v1/media/edge
GET /api/v1/streams/{stream_id}/media
GET /api/v1/streams/{stream_id}/media?join_token=jt_xxx

Public viewers receive playback URLs. Stream owners or valid join-token publishers also receive the WHIP ingest URL.

{
  "stream_id": "sess_661734e0f1c675faf937",
  "media_path": "beam-sess_661734e0f1c675faf937",
  "enabled": true,
  "provider": "mediamtx",
  "whip_url": "https://beam.be-online.ro/whip/beam-sess_661734e0f1c675faf937/whip",
  "whep_url": "https://beam.be-online.ro/whep/beam-sess_661734e0f1c675faf937/whep",
  "hls_url": "https://beam.be-online.ro/hls/beam-sess_661734e0f1c675faf937/index.m3u8",
  "playback_protocols": ["webrtc-whep", "ll-hls", "hls", "browser-webrtc"]
}

SDK examples

Publish a browser game, canvas, tab, camera, or app-owned MediaStream into the media edge.

const media = canvas.captureStream(60);

const publisher = await BeamStream.publishToMediaEdge({
  apiBase: "https://beam.be-online.ro/api",
  streamId: "sess_661734e0f1c675faf937",
  joinToken: "jt_xxx",
  stream: media,
  maxBitrate: 6500000,
  minBitrate: 700000,
  maxFramerate: 60,
  simulcast: true
});

// Stop publishing when the app stops streaming.
publisher.stop();

Use WHEP or HLS playback depending on the viewer network.

const mediaInfo = await BeamStream.getStreamMedia({
  apiBase: "https://beam.be-online.ro/api",
  streamId: "sess_661734e0f1c675faf937"
});

// HLS playback with hls.js on browsers that need it.
const video = document.querySelector("video");
if (video.canPlayType("application/vnd.apple.mpegurl")) {
  video.src = mediaInfo.hls_url;
} else {
  const hls = new Hls({ lowLatencyMode: true });
  hls.loadSource(mediaInfo.hls_url);
  hls.attachMedia(video);
}

Server environment

Set these variables on the Beam server when the media edge is deployed behind the same public origin.

BEAM_MEDIA_EDGE_ENABLED=true
BEAM_MEDIA_EDGE_PROVIDER=mediamtx
BEAM_MEDIA_EDGE_PUBLIC_BASE_URL=https://beam.be-online.ro
BEAM_MEDIA_EDGE_WHIP_BASE_URL=https://beam.be-online.ro/whip
BEAM_MEDIA_EDGE_WHEP_BASE_URL=https://beam.be-online.ro/whep
BEAM_MEDIA_EDGE_HLS_BASE_URL=https://beam.be-online.ro/hls
BEAM_MEDIA_EDGE_PATH_PREFIX=beam
BEAM_MEDIA_EDGE_LL_HLS_ENABLED=true
BEAM_MEDIA_EDGE_SFU_ENABLED=false
BEAM_MEDIA_EDGE_SIMULCAST_ENABLED=false

Set `BEAM_MEDIA_EDGE_SFU_ENABLED=true` and `BEAM_MEDIA_EDGE_SIMULCAST_ENABLED=true` only when the selected provider actually routes simulcast layers, such as an SFU deployment.

Reverse proxy shape

For a MediaMTX edge on localhost, proxy the edge through HTTPS so browsers do not hit mixed-content or permission problems.

location /whip/ {
  proxy_pass http://127.0.0.1:8889/;
  proxy_http_version 1.1;
  proxy_set_header Host $host;
  proxy_set_header X-Forwarded-Proto https;
}

location /whep/ {
  proxy_pass http://127.0.0.1:8889/;
  proxy_http_version 1.1;
  proxy_set_header Host $host;
  proxy_set_header X-Forwarded-Proto https;
}

location /hls/ {
  proxy_pass http://127.0.0.1:8888/;
  proxy_http_version 1.1;
  proxy_set_header Host $host;
  add_header Cache-Control "no-store";
}

Latency modes

WHEP/WebRTC

Use for interactive watch parties, app demos, and operators who need near-real-time feedback. Target sub-second to a few seconds depending on network quality.

LL-HLS

Use for public viewing when reliability matters more than instant interaction. A delay of several seconds is normal and helps slower PCs avoid constant buffering.

Stable HLS

Use for weak networks, mobile viewers, and large public fan-out. Increase buffer and accept higher delay to protect playback continuity.