StreamCrafter — Advanced
WebCodecs Encoder
Section titled “WebCodecs Encoder”WebCodecs encoding is auto-enabled on supported browsers (Chromium-family with RTCRtpScriptTransform). It provides background-safe encoding — the stream continues even when the browser tab loses focus.
How It Works
Section titled “How It Works”The encoder runs in a Web Worker and uses RTCRtpScriptTransform to inject encoded frames into the WebRTC connection. This bypasses the browser’s default encoder, which pauses when the tab is backgrounded.
Disabling WebCodecs
Section titled “Disabling WebCodecs”If you need to force standard WebRTC encoding:
// Vanilla / headlessconst studio = createStreamCrafter({ whipUrl: "...", useWebCodecs: false,});Encoder Overrides
Section titled “Encoder Overrides”Override default encoding parameters for fine-grained control:
studio.setEncoderOverrides({ videoBitrate: 4_000_000, // 4 Mbps videoFrameRate: 30, keyFrameInterval: 60, // Keyframe every 2 seconds at 30fps audioBitrate: 128_000, // 128 kbps});| Override | Type | Description |
|---|---|---|
videoBitrate | number | Target video bitrate in bps |
videoFrameRate | number | Target frame rate |
keyFrameInterval | number | Frames between keyframes |
audioBitrate | number | Target audio bitrate in bps |
Audio Mixing
Section titled “Audio Mixing”When multiple sources are active, StreamCrafter automatically mixes their audio using the Web Audio API.
Per-Source Volume
Section titled “Per-Source Volume”// Set volume (0.0 to 1.0)studio.setSourceVolume("camera-1", 0.8);studio.setSourceVolume("screen-1", 0.3);
// Mute/unmutestudio.setSourceMuted("camera-1", true);Master Volume
Section titled “Master Volume”studio.masterVolume = 0.5; // Affects all sourcesAudio Processing
Section titled “Audio Processing”The mixer applies basic audio processing to prevent clipping when mixing multiple sources. The output level is automatically normalized based on the number of active audio sources.
Reconnection
Section titled “Reconnection”StreamCrafter automatically reconnects when the WHIP connection drops. Enabled by default.
Configuration
Section titled “Configuration”const studio = createStreamCrafter({ whipUrl: "...", reconnection: { enabled: true, maxAttempts: 5, // Maximum reconnection attempts baseDelay: 1000, // Initial delay (ms) maxDelay: 30000, // Maximum delay (ms) backoffMultiplier: 2, // Exponential backoff factor },});Reconnection Events
Section titled “Reconnection Events”studio.on("reconnectionAttempt", ({ attempt, maxAttempts }) => { console.log(`Reconnecting: attempt ${attempt} of ${maxAttempts}`);});
studio.on("reconnectionSuccess", () => { console.log("Reconnected!");});
studio.on("reconnectionFailed", ({ error }) => { console.log("Reconnection failed:", error);});Reactive State
Section titled “Reactive State”studio.reactiveState.on("reconnecting", (isReconnecting) => { reconnectBanner.hidden = !isReconnecting;});Gateway Resolution
Section titled “Gateway Resolution”The SDK can call the public resolveIngestEndpoint GraphQL field to resolve a WHIP endpoint from a
stream key when that resolver is enabled in your environment:
const studio = createStreamCrafter({ gatewayUrl: "https://bridge.frameworks.network/graphql", streamKey: "<YOUR_STREAM_KEY>", profile: "broadcast",});When enabled, the resolver can choose an ingest node based on:
- Geographic proximity
- Node load and capacity
- Stream configuration
Run Gateway resolution from the publisher’s browser or device. If your application backend resolves
the ingest endpoint, Foghorn scores the backend or proxy IP instead of the publisher location. For
OBS, hardware encoders, or server-side publishing, prefer the dashboard DNS ingest URL
(edge-ingest.{tenant}.cdn.{base} when present, then global or cluster-concrete fallback).
Manual Gateway Resolution
Section titled “Manual Gateway Resolution”For custom UIs that need to resolve a WHIP URL before initializing in resolver-backed environments:
import { IngestClient } from "@livepeer-frameworks/streamcrafter-core";
const client = new IngestClient({ gatewayUrl: "https://bridge.frameworks.network/graphql", streamKey: "my-stream-key",});const endpoints = await client.resolve();const whipUrl = endpoints.primary?.whipUrl;if (!whipUrl) throw new Error("No WHIP endpoint resolved");
// Now use the resolved URLconst studio = createStreamCrafter({ whipUrl });Multi-Source Streaming
Section titled “Multi-Source Streaming”Adding Sources
Section titled “Adding Sources”// Camera with constraintsawait studio.startCamera({ video: { width: 1920, height: 1080, frameRate: 30 }, audio: true,});
// Screen share with system audioawait studio.startScreenShare({ audio: true });
// Custom MediaStreamstudio.addCustomSource(customStream, "External Source");Source Management
Section titled “Source Management”// List active sourcesconst sources = studio.sources;// [// { id: "camera-1", type: "camera", label: "FaceTime HD", muted: false, volume: 1 },// { id: "screen-1", type: "screen", label: "Screen", muted: false, volume: 1 }// ]
// Set primary video (determines which source is shown in non-compositor mode)studio.setPrimaryVideo("camera-1");
// Remove a sourcestudio.removeSource("screen-1");Source Events
Section titled “Source Events”studio.on("sourceAdded", (source) => { console.log("New source:", source.label);});
studio.on("sourceRemoved", ({ sourceId }) => { console.log("Removed:", sourceId);});
studio.on("sourceUpdated", (source) => { console.log("Updated:", source.id, source.volume, source.muted);});Runtime Theming
Section titled “Runtime Theming”StreamCrafter ships with 17 theme presets matching the player’s theme system.
// Switch theme at runtimestudio.theme = "tokyo-night";CSS Custom Properties
Section titled “CSS Custom Properties”All tokens use the --fw-sc-* prefix:
| Token | Purpose |
|---|---|
--fw-sc-bg | Background color |
--fw-sc-surface | Panel surfaces |
--fw-sc-border | Border color |
--fw-sc-text | Primary text |
--fw-sc-text-muted | Secondary text |
--fw-sc-accent | Interactive elements |
--fw-sc-success | Success/live indicators |
--fw-sc-danger | Error/destructive actions |
fw-streamcrafter,.fw-sc-root { --fw-sc-accent: 262 80% 60%; --fw-sc-bg: 230 15% 12%;}Internationalization
Section titled “Internationalization”Five built-in locales: en, es, fr, de, nl.
const studio = createStreamCrafter({ whipUrl: "...", locale: "de",});
// Or with custom translationsconst studio = createStreamCrafter({ whipUrl: "...", locale: "de", translations: { goLive: "Live gehen", stopStreaming: "Stoppen", addCamera: "Kamera hinzufugen", },});Configurable Hotkeys
Section titled “Configurable Hotkeys”Override default keyboard shortcuts:
const studio = createStreamCrafter({ whipUrl: "...", keyMap: { toggleStream: ["g"], toggleMute: ["m"], addCamera: ["c"], shareScreen: ["s"], },});Default hotkeys:
| Action | Default Key |
|---|---|
| Toggle streaming | Shift+Enter |
| Toggle mute | m |
| Add camera | c |
| Add screen share | s |
| Toggle settings | , |