StreamCrafter — React
Installation
Section titled “Installation”npm install @livepeer-frameworks/streamcrafter-reactImport the CSS once in your app:
import "@livepeer-frameworks/streamcrafter-react/streamcrafter.css";Drop-in Component
Section titled “Drop-in Component”The <StreamCrafter /> component is fully self-contained with video preview, controls, and connection management.
Direct WHIP Mode:
<StreamCrafter whipUrl="https://edge-ingest.frameworks.network/webrtc/stream-key" initialProfile="broadcast" />Gateway Resolution Mode:
import { StreamCrafter } from "@livepeer-frameworks/streamcrafter-react";import "@livepeer-frameworks/streamcrafter-react/streamcrafter.css";
function BroadcastPage() { return ( <StreamCrafter gatewayUrl="https://bridge.frameworks.network/graphql" streamKey="<YOUR_STREAM_KEY>" initialProfile="broadcast" onStateChange={(state) => console.log(state)} /> );}Gateway resolution calls the public resolveIngestEndpoint GraphQL field from the publisher’s
browser. Use direct whipUrl unless that resolver is enabled in your environment, and prefer the
dashboard DNS ingest URL for backend or encoder-side publishing.
Composable Components
Section titled “Composable Components”Pass children to <StreamCrafter> to replace the default UI with your own layout using the provided sub-components:
import { StreamCrafter, StudioPreview, StudioMixer, StudioActionBar, StudioSettings, StudioStatusBadge,} from "@livepeer-frameworks/streamcrafter-react";import "@livepeer-frameworks/streamcrafter-react/streamcrafter.css";
function CustomStudio() { return ( <StreamCrafter whipUrl="https://edge-ingest.frameworks.network/webrtc/my-key"> <div className="my-layout"> <StudioStatusBadge /> <StudioPreview /> <div className="sidebar"> <StudioMixer /> <StudioSettings /> </div> <StudioActionBar /> </div> </StreamCrafter> );}When children are provided, the built-in UI is entirely replaced. Sub-components auto-connect to the parent <StreamCrafter> via React context.
Sub-Component Reference
Section titled “Sub-Component Reference”| Component | Purpose |
|---|---|
StudioPreview | Video preview with optional compositor overlay and live badge |
StudioMixer | Source list with volume sliders, mute, and remove buttons |
StudioActionBar | Camera, Screen Share, Settings, and Go Live buttons |
StudioSettings | Quality profile selector popup |
StudioStatusBadge | State badge (Idle, Capturing, Live, Connecting, etc.) |
All sub-components accept optional prop overrides for any value they normally read from context.
Custom UI with Hooks
Section titled “Custom UI with Hooks”For complete UI control, use useStreamCrafterV2 directly:
import { useStreamCrafterV2 } from "@livepeer-frameworks/streamcrafter-react";
function FullyCustomBroadcaster() { const { state, isStreaming, isCapturing, sources, mediaStream, startCamera, startScreenShare, startStreaming, stopStreaming, removeSource, setSourceVolume, setSourceMuted, qualityProfile, setQualityProfile, } = useStreamCrafterV2({ whipUrl: "https://edge-ingest.frameworks.network/webrtc/key", profile: "broadcast", reconnection: { enabled: true }, });
return ( <div> <video ref={(el) => { if (el) el.srcObject = mediaStream; }} autoPlay muted /> <p>State: {state}</p> <p>Sources: {sources.length}</p> <button onClick={() => startCamera()}>Add Camera</button> <button onClick={() => startScreenShare({ audio: true })}>Share Screen</button> <button onClick={() => (isStreaming ? stopStreaming() : startStreaming())}> {isStreaming ? "Stop" : "Go Live"} </button> </div> );}Hook Return Reference
Section titled “Hook Return Reference”| Property | Type | Description |
|---|---|---|
state | IngestState | Current lifecycle state |
isStreaming | boolean | Whether currently live |
isCapturing | boolean | Whether media is captured |
isReconnecting | boolean | Whether reconnecting |
sources | MediaSource[] | Active media sources |
mediaStream | MediaStream | null | Combined output stream |
qualityProfile | QualityProfile | Current quality settings |
startCamera(opts?) | () => Promise<MediaSource> | Add camera source |
startScreenShare(opts?) | () => Promise<MediaSource | null> | Add screen share source |
startStreaming() | () => Promise<void> | Go live |
stopStreaming() | () => Promise<void> | Stop streaming |
removeSource(id) | (id: string) => void | Remove a source |
setSourceVolume(id, vol) | (id, number) => void | Set source volume (0-1) |
setSourceMuted(id, muted) | (id, boolean) => void | Mute/unmute source |
setQualityProfile(profile) | (profile: QualityProfile) => Promise<void> | Change quality profile |
getController() | () => IngestControllerV2 | null | Direct controller access |
State Callbacks
Section titled “State Callbacks”<StreamCrafter whipUrl="..." onStateChange={(state, context) => { if (state === "streaming") showLiveBadge(); if (state === "error") showError(context?.error); }}/>