Documentation Index
Fetch the complete documentation index at: https://docs.daydream.live/llms.txt
Use this file to discover all available pages before exploring further.
React Hooks
The @daydreamlive/react package provides React hooks for easy integration with React applications.
Installation
npm install @daydreamlive/react
useBroadcast
Manages broadcasting state and controls.
import { useBroadcast } from "@daydreamlive/react";
function Broadcaster({ whipUrl }: { whipUrl: string }) {
const { status, start, stop, setMaxFramerate } = useBroadcast({
whipUrl,
reconnect: { enabled: true },
});
const handleStart = async () => {
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
await start(stream);
};
return (
<div>
<p>Status: {status.state}</p>
{status.state === "live" && (
<p>WHEP URL: {status.whepUrl}</p>
)}
{status.state === "error" && (
<p>Error: {status.error.message}</p>
)}
<button onClick={handleStart} disabled={status.state === "live"}>
Start Broadcasting
</button>
<button onClick={stop} disabled={status.state !== "live"}>
Stop
</button>
</div>
);
}
Options
useBroadcast({
whipUrl: string, // Required: WHIP endpoint
reconnect?: {
enabled: boolean, // Auto-reconnect (default: false)
maxAttempts?: number,
baseDelay?: number,
maxDelay?: number,
},
video?: {
maxBitrate?: number,
maxFramerate?: number,
},
})
Returns
| Property | Type | Description |
|---|
status | UseBroadcastStatus | Current state (see below) |
start | (stream: MediaStream) => Promise<void> | Start broadcasting |
stop | () => void | Stop broadcasting |
setMaxFramerate | (fps?: number) => void | Adjust framerate |
Status States
The status is a discriminated union - use status.state to determine the current state:
type UseBroadcastStatus =
| { state: "idle" }
| { state: "connecting" }
| { state: "live"; whepUrl: string }
| { state: "reconnecting"; whepUrl: string; reconnectInfo: ReconnectInfo }
| { state: "ended" }
| { state: "error"; error: DaydreamError };
usePlayer
Manages playback state and controls.
import { usePlayer } from "@daydreamlive/react";
function Player({ whepUrl }: { whepUrl: string }) {
const { status, play, stop, videoRef } = usePlayer(whepUrl, {
autoPlay: true,
reconnect: { enabled: true },
});
return (
<div>
<p>Status: {status.state}</p>
{status.state === "error" && (
<p>Error: {status.error.message}</p>
)}
<video ref={videoRef} autoPlay playsInline muted />
<button onClick={play} disabled={status.state === "playing"}>
Play
</button>
<button onClick={stop}>
Stop
</button>
</div>
);
}
Options
usePlayer(whepUrl: string, {
autoPlay?: boolean, // Auto-start playback (default: false)
reconnect?: {
enabled: boolean,
maxAttempts?: number,
baseDelay?: number,
maxDelay?: number,
},
})
Returns
| Property | Type | Description |
|---|
status | UsePlayerStatus | Current state |
play | () => Promise<void> | Start playback |
stop | () => void | Stop playback |
videoRef | RefObject<HTMLVideoElement> | Attach to <video> |
Status States
type UsePlayerStatus =
| { state: "idle" }
| { state: "connecting" }
| { state: "playing" }
| { state: "buffering"; reconnectInfo: ReconnectInfo }
| { state: "ended" }
| { state: "error"; error: DaydreamError };
Complete Example
Here’s a full example with broadcasting and playback:
"use client";
import { useState } from "react";
import { useBroadcast, usePlayer } from "@daydreamlive/react";
export default function DaydreamDemo({ whipUrl }: { whipUrl: string }) {
const [localStream, setLocalStream] = useState<MediaStream | null>(null);
// Broadcast hook
const broadcast = useBroadcast({
whipUrl,
reconnect: { enabled: true },
});
// Player hook - only connect when we have a WHEP URL
const player = usePlayer(
broadcast.status.state === "live" ? broadcast.status.whepUrl : "",
{ autoPlay: true, reconnect: { enabled: true } }
);
const handleStart = async () => {
const stream = await navigator.mediaDevices.getUserMedia({
video: { width: 512, height: 512 },
audio: false,
});
setLocalStream(stream);
await broadcast.start(stream);
};
const handleStop = () => {
broadcast.stop();
localStream?.getTracks().forEach(track => track.stop());
setLocalStream(null);
};
return (
<div className="flex gap-4">
{/* Local preview */}
<div>
<h3>Input</h3>
<video
autoPlay
playsInline
muted
ref={(el) => {
if (el && localStream) el.srcObject = localStream;
}}
className="w-64 h-64 bg-black"
/>
<p>Broadcast: {broadcast.status.state}</p>
</div>
{/* AI output */}
<div>
<h3>AI Output</h3>
<video
ref={player.videoRef}
autoPlay
playsInline
muted
className="w-64 h-64 bg-black"
/>
<p>Player: {player.status.state}</p>
</div>
{/* Controls */}
<div className="flex gap-2">
<button
onClick={handleStart}
disabled={broadcast.status.state === "live"}
className="px-4 py-2 bg-green-500 text-white rounded"
>
Start
</button>
<button
onClick={handleStop}
disabled={broadcast.status.state !== "live"}
className="px-4 py-2 bg-red-500 text-white rounded"
>
Stop
</button>
</div>
{/* Errors */}
{broadcast.status.state === "error" && (
<p className="text-red-500">
Broadcast error: {broadcast.status.error.message}
</p>
)}
{player.status.state === "error" && (
<p className="text-red-500">
Player error: {player.status.error.message}
</p>
)}
</div>
);
}
Next.js Server Actions Pattern
For Next.js apps, create the stream on the server and pass the WHIP URL to the client:
// app/actions.ts
"use server";
import { Daydream } from "@daydreamlive/sdk";
const daydream = new Daydream({
bearer: process.env.DAYDREAM_API_KEY!,
});
export async function createStream() {
const stream = await daydream.streams.create({
pipeline: "streamdiffusion",
params: {
modelId: "Lykon/dreamshaper-8",
prompt: "anime character",
},
});
return {
id: stream.id,
whipUrl: stream.whipUrl,
playbackUrl: `https://lvpr.tv/?v=${stream.outputPlaybackId}`,
};
}
export async function updatePrompt(streamId: string, prompt: string) {
await daydream.streams.update(streamId, {
pipeline: "streamdiffusion",
params: {
modelId: "Lykon/dreamshaper-8",
prompt,
},
});
}
// app/page.tsx
"use client";
import { useState } from "react";
import { createStream, updatePrompt } from "./actions";
import DaydreamDemo from "./DaydreamDemo";
export default function Page() {
const [streamData, setStreamData] = useState<{
id: string;
whipUrl: string;
} | null>(null);
const handleCreate = async () => {
const data = await createStream();
setStreamData(data);
};
if (!streamData) {
return <button onClick={handleCreate}>Create Stream</button>;
}
return <DaydreamDemo whipUrl={streamData.whipUrl} />;
}
Live Examples
Next Steps