Skip to content

Streams

A stream is the live object you broadcast into and viewers watch. It owns three things you will use in most integrations:

FieldWhat it isSafe to expose?
idGraphQL object ID for API mutations and queriesBackend only
streamKeySecret ingest credential for push streamsNo
playbackIdPublic viewer identifier for /play and PlayerYes

Use streamKey only where media is being uploaded. Use playbackId everywhere viewers need to watch.

FrameWorks supports two ingest models:

ModelHow media arrivesCreation path
PushYour encoder opens RTMP/E-RTMP, SRT, or WHIP to FrameWorksDashboard or GraphQL createStream
PullFrameWorks opens RTSP, SRT, RIST, HLS, DTSC, or TS to youDashboard or GraphQL createStream

Most builders start with push streams. Pull-input streams are useful for cameras, venue feeds, and upstream origins that cannot push into FrameWorks. See Pull-input streams for supported source schemes, private-source rules, and lifecycle visibility. Note that RTMP and FLV-over-HTTP pull are not supported todayopen a ticket if you need them.

Experimental media-engine discovery exists locally today. On the roadmap: packaging that into FrameWorks Edge, Tray, CLI, API, and dashboard workflows for venues and studios that want camera pickup without hand-wiring RTSP URLs.

  1. Open Content -> Streams.
  2. Click Create Stream.
  3. Give it a name and optional description.
  4. Copy the Stream Key for your encoder.
  5. Copy the Playback ID for players and embeds.

For the fastest end-to-end setup, follow Quick Start.

Most mutations return a union. Always check __typename.

mutation {
createStream(input: { name: "Main Stage", record: true }) {
__typename
... on Stream {
id
name
streamKey
playbackId
record
}
... on ValidationError {
field
message
}
... on AuthError {
message
}
}
}

record: true enables DVR recording from the start. For event channels, this gives late viewers seekback while the stream is live. For 24/7 channels, the live stream keeps running while replay is served from chapter artifacts that segment the session timeline — no forced stream restart at a duration boundary. You can also toggle recording later with updateStream. See Live and DVR Streams for what that creates.

Setting record: true at create time (or calling startDVR(streamId) later) creates a separate stream entity for the recording, with its own internal name and playbackId, distinct from the live stream:

  • Live stream — segments live in a shared-memory ring buffer of about 50 seconds. Right for real-time playback and CLIP_NOW of recent moments.
  • DVR stream — segments are written to disk and archived under one recording artifact. Right for seek-back, longer clips, and post-event playback. The live DVR window is bounded for player performance; historical replay uses finalized chapter artifacts over the same segment archive.

The live ring is configurable — private deployments often want a longer window — but every extra second costs cluster RAM, so the default stays tight. Open an in-app ticket if your deployment needs a non-default size.

Practical consequences:

  • Players use the DVR playbackId (with contentType="dvr") to seek back beyond the live ring within the live DVR window.
  • Clip creation runs against the entity that holds the moment you want — see Clips. Use the live stream for the live ring and the DVR recording for archived ranges.
  • Access control, multistream targets, thumbnails, and analytics attach per stream entity.

For 24/7-style streams, the recording can continue as one DVR artifact for the full stream session. Replay viewers navigate that archive through chapters or explicit time ranges, while the live player still receives a bounded seekback window. See Recordings, Clips & VOD.

After creating a push stream, send media to one of the ingest endpoints shown on the stream detail page:

ProtocolTypical useGuide
RTMP/E-RTMPOBS, hardware encoders, FFmpegEncoder Setup
SRTUnreliable or long-haul networksEncoder Setup
WHIPBrowser or WebRTC-native broadcastStreamCrafter

The stream becomes live once the media edge accepts the input and MistServer reports an active session.

Use playbackId with the FrameWorks Player or raw /play URLs:

import { Player } from "@livepeer-frameworks/player-react";
<Player contentType="live" contentId="<PLAYBACK_ID>" options={{ autoplay: true, muted: true }} />;
Terminal window
https://foghorn.frameworks.network/play/<PLAYBACK_ID>/hls/index.m3u8
https://foghorn.frameworks.network/play/<PLAYBACK_ID>/webrtc

See Playback & Embedding for protocols, players, and custom source resolution.

  • Offline - The stream exists, but no encoder or pull input is currently active.
  • Live - The media edge is receiving or pulling source media.
  • Recording - If recording is enabled, DVR assets are produced while the stream is live.
  • Idle pull input - Pull streams do not fetch upstream media until a viewer requests playback.

Playback access policies, multistream targets, recordings, thumbnails, and analytics attach to the stream regardless of whether the media arrives by push or pull. The difference is only how the source media gets into the platform.