StreamCrafter ingest overview
Browser-based broadcasting — camera, screen share, or both with audio mixing. No encoder software needed.
Packages
Section titled “Packages”| Package | Use Case |
|---|---|
@livepeer-frameworks/streamcrafter-react | React 17+ apps |
@livepeer-frameworks/streamcrafter-svelte | Svelte 5 apps |
@livepeer-frameworks/streamcrafter-wc | Web Components — Vue, Angular, CDN, plain HTML |
@livepeer-frameworks/streamcrafter-core | Vanilla JS, headless, or building custom integrations |
Not sure which package to use? See the Integration Guide.
Quick Start
Section titled “Quick Start”Direct WHIP Mode — pass the WHIP endpoint shown in the dashboard:
<StreamCrafter whipUrl="https://edge-ingest.frameworks.network/webrtc/your-stream-key" initialProfile="broadcast" />Gateway Resolution Mode — the SDK resolves the WHIP endpoint from a stream key via
resolveIngestEndpoint, which picks the ingest node closest to and least loaded for the publisher:
import { StreamCrafter } from "@livepeer-frameworks/streamcrafter-react";import "@livepeer-frameworks/streamcrafter-react/streamcrafter.css";
<StreamCrafter gatewayUrl="https://bridge.frameworks.network/graphql" streamKey="<YOUR_STREAM_KEY>" initialProfile="broadcast"/>;The drop-in component includes video preview, camera/screen share controls, quality selection, Go Live button, source management, and auto-reconnection.
Where to Find Your WHIP URL
Section titled “Where to Find Your WHIP URL”Your WHIP ingest URL is shown in the FrameWorks dashboard under Ingest URLs:
WHIP: https://edge-ingest.frameworks.network/webrtc/your-stream-keyFrameWorks uses MistServer’s /webrtc/{streamKey} path for WHIP ingest. The dashboard URL points at
the edge-ingest DNS name, which resolves to the geographically nearest healthy ingest node.
Ingest Front Door
Section titled “Ingest Front Door”The DNS name steers on geography alone. For load-aware routing without a GraphQL call, publish against Foghorn’s ingest front door instead:
POST https://foghorn.{base}/ingest/{streamKey}It validates the stream key, scores candidate ingest nodes on load and distance, and answers with a
307 Temporary Redirect to the chosen node’s WHIP URL.
RFC 9725 requires WHIP clients to support
redirects on the initial POST, and 307 preserves the method and SDP offer, so any spec-compliant
WHIP client can publish to this URL in place of a fixed node URL.
The same path answers GET with JSON when you need the candidates rather than a redirect — useful
for encoder setup scripts:
curl https://foghorn.{base}/ingest/{streamKey}Require your encoder’s protocol with ?protocol=whip, ?protocol=rtmp, or ?protocol=srt:
curl 'https://foghorn.{base}/ingest/{streamKey}?protocol=srt'This filters candidates before ranking and limiting the response. If no eligible node advertises
that protocol, the response is unavailable; it does not substitute a different protocol. Omit the
parameter to discover any advertised ingest protocols. WHIP POST always requires WHIP, and an
explicit conflicting protocol or duplicate protocol parameter returns 400.
The URLs below illustrate one node’s listeners, not fixed platform-wide ports. A node that does not advertise a protocol omits its URL. Resolution is advisory, not a reservation or confirmation that publishing has started.
Use the returned URL for the selected protocol unchanged. baseUrl identifies the node’s public
HTTP(S) endpoint; its scheme and port are not the RTMP or SRT listener’s scheme and port. Do not
reconstruct publishing URLs from it or assume every returned node supports every protocol.
Resolve with an explicit protocol when your encoder requires one.
{ "primary": { "nodeId": "edge-ams-1", "whipUrl": "https://edge-ams-1.{cluster}.{base}/webrtc/{streamKey}", "rtmpUrl": "rtmp://edge-ams-1.{cluster}.{base}:1935/live/{streamKey}", "srtUrl": "srt://edge-ams-1.{cluster}.{base}:8889?streamid={streamKey}", "region": "eu-west", "loadScore": 1950, "kind": "INGEST_ENDPOINT_KIND_NODE_SPECIFIC", "clusterId": "media-eu-1" }, "fallbacks": [...]}RTMP and SRT have no redirect mechanism, so those protocols use either the edge-ingest DNS name or
a URL taken from this response. Resolution never claims ingest placement — the publish itself does —
so it is safe to call speculatively or repeatedly.
The Foghorn listener hostname does not constrain the result to one virtual media cluster. Commodore supplies the stream’s authorized healthy cluster envelope, and an existing live claim pins reconnects to the cluster already receiving the publisher.
An unknown key returns 404, a suspended account 403, a negative balance 402, and an unhealthy
cluster 503. The endpoint is rate limited per IP.
Customization Levels
Section titled “Customization Levels”StreamCrafter supports three levels of customization across all framework packages:
| Level | What You Get | When to Use |
|---|---|---|
| Drop-in | Full built-in UI | Quick integration, default look |
| Composable | Use framework sub-components, rearrange and mix with your own UI | Custom layouts, partial customization |
| Headless | Raw controller/hooks/stores, build your own UI entirely | Full creative control |
See the framework-specific pages for details on each level:
Quality Profiles
Section titled “Quality Profiles”The drop-in UI exposes three quality presets. The lower-level core type also accepts auto for
custom integrations that want browser-selected defaults:
| Profile | Resolution | Use Case |
|---|---|---|
professional | 1920x1080 | High quality, good upload |
broadcast | 1920x1080 | Balanced quality/bandwidth |
conference | 1280x720 | Limited bandwidth, meetings |
<StreamCrafter initialProfile="conference" />Multi-Source Streaming
Section titled “Multi-Source Streaming”StreamCrafter supports simultaneous camera + screen share with per-source volume control and audio mixing.
const { startCamera, startScreenShare, sources } = useStreamCrafterV2({ ... });
await startCamera();await startScreenShare({ audio: true });// Both sources now stream together with mixed audioSee Advanced Features for audio mixing details.
Compositor
Section titled “Compositor”The compositor is enabled by default — multi-source layout control with scenes, layers, and transitions:
- 15 layout presets (solo, PiP, split, grid, featured, and more)
- Drag-and-drop layer ordering
- Scene switching with animated transitions
- GPU-accelerated rendering (WebGPU, WebGL, Canvas2D fallback)
See Compositor for full details.
States
Section titled “States”| State | Description |
|---|---|
idle | Ready, no capture active |
requesting_permissions | Waiting for camera/mic permission |
capturing | Media captured, not streaming |
connecting | Establishing WHIP connection |
streaming | Live and streaming |
reconnecting | Connection lost, attempting reconnect |
error | Error occurred |
destroyed | Cleanup complete |
Browser Support
Section titled “Browser Support”| Browser | Tested |
|---|---|
| Chrome 90+ | Full support |
| Firefox 90+ | Full support |
| Safari 14.1+ | Full support |
| Edge 90+ | Full support |
Troubleshooting
Section titled “Troubleshooting”Camera/Microphone Not Working
Section titled “Camera/Microphone Not Working”- Check permissions — Ensure the browser has camera/mic access
- HTTPS required — MediaDevices API requires secure context
- Device in use — Close other apps using the camera
Stream Won’t Connect
Section titled “Stream Won’t Connect”- Check WHIP URL — Verify the endpoint is correct
- Firewall/NAT — WebRTC may need TURN servers for restrictive networks (pass
iceServersin config) - Stream key — Ensure the stream key is valid
High Latency
Section titled “High Latency”- Upload bandwidth — Check your upload speed matches the profile bitrate
- Profile mismatch — Try
conferenceprofile for limited bandwidth
Screen Share Audio Missing
Section titled “Screen Share Audio Missing”- System audio — Screen share audio only works with
{ audio: true } - Browser support — System audio capture requires Chrome/Edge (not Firefox/Safari)
- User selection — User must check “Share audio” in the browser dialog