@reactor-models/longlive-v2
v3.0.5
Published
Strongly-typed SDK for the LongliveV2 model on Reactor
Downloads
498
Maintainers
Readme
@reactor-models/longlive-v2
Typed JavaScript + React SDK for the LongliveV2 model on Reactor. Version v3.0.5.
Get started
Scaffold a starter app for LongliveV2 with create-reactor-app:
npx create-reactor-app my-app --model=longlive-v2pnpm dlx create-reactor-app my-app --model=longlive-v2Install
npm install @reactor-models/longlive-v2pnpm add @reactor-models/longlive-v2The package exports a plain-JavaScript client and a set of React bindings. Import whichever you need from @reactor-models/longlive-v2:
import { LongliveV2Model } from "@reactor-models/longlive-v2";import { LongliveV2Provider, useLongliveV2 } from "@reactor-models/longlive-v2";React 18 or later is required when using the provider and hooks. The token-loading examples below use React 19's use(); on React 18, fetch the JWT in a useEffect and pass it to the provider once it resolves.
Authenticate
Reactor uses short-lived JWTs for session auth. You hold your API key on your server, mint a token on demand, and the client never sees the raw key. Tokens are valid for 6 hours — if one leaks, it expires on its own.
Mint a JWT with POST https://api.reactor.inc/tokens and the Reactor-API-Key header; the response JSON is { "jwt": "..." }.
JavaScript (Next.js route handler)
// app/api/reactor/token/route.ts
import { NextResponse } from "next/server";
export async function POST() {
const res = await fetch("https://api.reactor.inc/tokens", {
method: "POST",
headers: { "Reactor-API-Key": process.env.REACTOR_API_KEY! },
});
const { jwt } = await res.json();
return NextResponse.json({ jwt });
}React (provider)
Call the /api/reactor/token route above from a client component and pass the result to the provider:
"use client";
import { use } from "react";
import { LongliveV2Provider } from "@reactor-models/longlive-v2";
import { ReactorView } from "@reactor-team/js-sdk";
async function getToken() {
const r = await fetch("/api/reactor/token", { method: "POST" });
const { jwt } = await r.json();
return jwt;
}
const tokenPromise = getToken();
export default function App() {
const token = use(tokenPromise);
return (
<LongliveV2Provider jwtToken={token} connectOptions={{ autoConnect: true }}>
<ReactorView className="w-full aspect-video" />
</LongliveV2Provider>
);
}Connect
JavaScript
import { LongliveV2Model } from "@reactor-models/longlive-v2";
const longliveV2 = new LongliveV2Model();
await longliveV2.connect(jwt);React
The provider takes the JWT as a prop; fetch it from the same /api/reactor/token route the Authenticate example mints:
"use client";
import { use } from "react";
import { LongliveV2Provider, useLongliveV2 } from "@reactor-models/longlive-v2";
async function getToken() {
const r = await fetch("/api/reactor/token", { method: "POST" });
const { jwt } = await r.json();
return jwt;
}
const tokenPromise = getToken();
function Controller() {
const { status } = useLongliveV2();
return <span>Status: {status}</span>;
}
export default function App() {
const token = use(tokenPromise);
return (
<LongliveV2Provider jwtToken={token}>
<Controller />
</LongliveV2Provider>
);
}Events
Client-to-model commands. The typed surface is LongliveV2Model (one method per event) in plain JS, and useLongliveV2() in React — every field name below matches the parameter name the method accepts.
pause
Pause generation after the current chunk finishes. Valid only while generating (after start, not already paused). Emits generation_paused and state on success, or command_error if the session is not generating or is already paused.
Emits: generation_paused, state, command_error
No parameters.
JavaScript
import { LongliveV2Model } from "@reactor-models/longlive-v2";
const longliveV2 = new LongliveV2Model();
await longliveV2.connect(jwt);
await longliveV2.pause();React
"use client";
import { useLongliveV2 } from "@reactor-models/longlive-v2";
function Example() {
const { pause } = useLongliveV2();
return <button onClick={() => pause()}>pause</button>;
}reset
Abort the current run, clear the active prompt and any scheduled cuts or shots, and return to the waiting state. Always succeeds — there is no command_error path. Emits generation_reset and state. After reset the session is back to its just-connected state: the client must call set_shot again before start will succeed.
Emits: command_error, generation_reset, state
No parameters.
JavaScript
import { LongliveV2Model } from "@reactor-models/longlive-v2";
const longliveV2 = new LongliveV2Model();
await longliveV2.connect(jwt);
await longliveV2.reset();React
"use client";
import { useLongliveV2 } from "@reactor-models/longlive-v2";
function Example() {
const { reset } = useLongliveV2();
return <button onClick={() => reset()}>reset</button>;
}start
Begin generating video on main_video from the opening shot. Requires an opening shot set via set_shot, and zeros the chunk counters for the new run. Emits state on success, or command_error if no shot has been set, or if a previous run has finished (call reset first).
Emits: state, command_error
No parameters.
JavaScript
import { LongliveV2Model } from "@reactor-models/longlive-v2";
const longliveV2 = new LongliveV2Model();
await longliveV2.connect(jwt);
await longliveV2.start();React
"use client";
import { useLongliveV2 } from "@reactor-models/longlive-v2";
function Example() {
const { start } = useLongliveV2();
return <button onClick={() => start()}>start</button>;
}resume
Resume generation from a previous pause. Valid only when the session is paused. Emits generation_resumed and state on success, or command_error if the session is not paused.
Emits: generation_resumed, state, command_error
No parameters.
JavaScript
import { LongliveV2Model } from "@reactor-models/longlive-v2";
const longliveV2 = new LongliveV2Model();
await longliveV2.connect(jwt);
await longliveV2.resume();React
"use client";
import { useLongliveV2 } from "@reactor-models/longlive-v2";
function Example() {
const { resume } = useLongliveV2();
return <button onClick={() => resume()}>resume</button>;
}setSeed
Set seed
| Parameter | Type | Required | Description |
|---|---|---|---|
| seed | number | | Random seed for noise sampling. Read once when start fires; later changes only take effect after reset followed by a new start. (min 0, default 42) |
JavaScript
import { LongliveV2Model } from "@reactor-models/longlive-v2";
const longliveV2 = new LongliveV2Model();
await longliveV2.connect(jwt);
await longliveV2.setSeed({ seed: 42 });React
"use client";
import { useLongliveV2 } from "@reactor-models/longlive-v2";
function Example() {
const { setSeed } = useLongliveV2();
return <button onClick={() => setSeed({ seed: 42 })}>setSeed</button>;
}setShot
Set the shot prompt. Before start, this seeds the opening shot the video begins from. After start, it triggers a soft shot change: at the next chunk boundary the video transitions to the new prompt while keeping the model's memory of what came before, so motion, identity, and the world carry across the cut. Use it to change framing, action, or subject within the same continuous scene. For a clean break to an unrelated scene — memory wiped, a brief transition pause — use scene_cut instead. Emits shot_set and state on success, or command_error if the prompt is empty or a previous run has finished (call reset first).
Emits: scene_cut, shot_set, state, command_error
| Parameter | Type | Required | Description |
|---|---|---|---|
| prompt | string | | What the shot should show, in natural language. Before start this is the opening prompt generation begins from; after start it drives a soft shot change at the next chunk boundary. (default "") |
JavaScript
import { LongliveV2Model } from "@reactor-models/longlive-v2";
const longliveV2 = new LongliveV2Model();
await longliveV2.connect(jwt);
await longliveV2.setShot({ prompt: "A sunset over the ocean" });React
"use client";
import { useLongliveV2 } from "@reactor-models/longlive-v2";
function Example() {
const { setShot } = useLongliveV2();
return <button onClick={() => setShot({ prompt: "A sunset over the ocean" })}>setShot</button>;
}sceneCut
Cut to an unrelated scene mid-stream. A hard cut: the model's memory is wiped and generation restarts from the new prompt, giving a clean break with no carry-over of motion, identity, or world. The cut lands at the next chunk boundary and costs a one-time ~150-300ms transition; the per-scene chunk counter (current_chunk) restarts at 0 while the session-wide session_chunk keeps counting. Use it for a genuine change of scene — new subject, new place, new world. For a lighter change that stays in the same continuous scene (new framing, action, or subject with memory preserved) use set_shot instead. Emits scene_cut and state when the next chunk fires, or command_error if the prompt is empty or a previous run has finished (call reset first).
Emits: scene_cut, state, command_error
| Parameter | Type | Required | Description |
|---|---|---|---|
| prompt | string | | What the new scene should show, in natural language. Queued for the next chunk boundary, where it replaces the current scene wholesale (memory wiped, a fresh start). Calling scene_cut again before the next chunk fires overwrites the queued prompt. (default "") |
JavaScript
import { LongliveV2Model } from "@reactor-models/longlive-v2";
const longliveV2 = new LongliveV2Model();
await longliveV2.connect(jwt);
await longliveV2.sceneCut({ prompt: "A sunset over the ocean" });React
"use client";
import { useLongliveV2 } from "@reactor-models/longlive-v2";
function Example() {
const { sceneCut } = useLongliveV2();
return <button onClick={() => sceneCut({ prompt: "A sunset over the ocean" })}>sceneCut</button>;
}scheduleShot
Schedule a soft set_shot change to fire at a specific chunk index, instead of changing immediately. Same memory-preserving transition as a mid-stream set_shot, but planted ahead of time so it lands frame-accurately without a network round-trip race or activation delay. Use schedule_shot for changes within the same continuous scene and schedule_scene_cut for clean breaks to a new scene. at_session_chunk counts total chunks since the most recent start and keeps counting across cuts. Note: a shot scheduled at at_session_chunk=0 does not render as a transition — there is no earlier chunk to change from — so its prompt simply drives the first chunk, the same as if it were the opening shot (overriding any shot set via set_shot). Emits shot_scheduled and state on success, or command_error if the prompt is empty, at_session_chunk is negative, or a previous run has finished (call reset first).
Emits: shot_scheduled, state, command_error
| Parameter | Type | Required | Description |
|---|---|---|---|
| prompt | string | | What the shot should change to when the target chunk is reached, in natural language. Held server-side until then so the change fires with no delay. Scheduling at an at_session_chunk already in the schedule replaces that entry; entries whose target chunk has already passed never fire. (default "") |
| at_session_chunk | number | | Chunk index at which the shot change fires, counted as total chunks since the most recent start. Must be ≥ 0, with no upper bound — schedule beyond the run length to fire after earlier cuts. A target that has already passed never fires. (default -1) |
JavaScript
import { LongliveV2Model } from "@reactor-models/longlive-v2";
const longliveV2 = new LongliveV2Model();
await longliveV2.connect(jwt);
await longliveV2.scheduleShot({ prompt: "A sunset over the ocean", at_session_chunk: 0 });React
"use client";
import { useLongliveV2 } from "@reactor-models/longlive-v2";
function Example() {
const { scheduleShot } = useLongliveV2();
return <button onClick={() => scheduleShot({ prompt: "A sunset over the ocean", at_session_chunk: 0 })}>scheduleShot</button>;
}scheduleSceneCut
Schedule a hard scene_cut to fire at a specific chunk index, instead of cutting immediately. This removes the network round-trip race for frame-accurate cuts: the cut lands exactly when session_chunk reaches the target, no matter when the command arrives, and with no activation delay. at_session_chunk counts total chunks since the most recent start and keeps counting across cuts, so scheduling at 10 and 20 fires both as the session reaches those counts. Use this to script a multi-scene sequence up front. Emits scene_cut_scheduled and state on success, or command_error if the prompt is empty, at_session_chunk is negative, or a previous run has finished (call reset first).
Emits: scene_cut, scene_cut_scheduled, state, command_error
| Parameter | Type | Required | Description |
|---|---|---|---|
| prompt | string | | What the scene should show when the target chunk is reached, in natural language. Held server-side until then so the cut fires with no delay. Scheduling at an at_session_chunk already in the schedule replaces that entry; entries whose target chunk has already passed never fire. (default "") |
| at_session_chunk | number | | Chunk index at which the cut fires, counted as total chunks since the most recent start. Must be ≥ 0, with no upper bound — schedule beyond the run length to fire after earlier cuts. A target that has already passed never fires. (default -1) |
JavaScript
import { LongliveV2Model } from "@reactor-models/longlive-v2";
const longliveV2 = new LongliveV2Model();
await longliveV2.connect(jwt);
await longliveV2.scheduleSceneCut({ prompt: "A sunset over the ocean", at_session_chunk: 0 });React
"use client";
import { useLongliveV2 } from "@reactor-models/longlive-v2";
function Example() {
const { scheduleSceneCut } = useLongliveV2();
return <button onClick={() => scheduleSceneCut({ prompt: "A sunset over the ocean", at_session_chunk: 0 })}>scheduleSceneCut</button>;
}Messages
Model-to-client messages. Register a typed listener with on… on LongliveV2Model, or a useLongliveV2… hook in React, to receive only the messages you care about.
state
Emitted on connect, after every state-mutating event, and after each completed chunk. Snapshot of the session's observable state — clients drive UI from this single source of truth without reconstructing state from the event stream.
Listener: onState · React hook: useLongliveV2State
| Field | Type | Description |
|---|---|---|
| seed | number | Current value of the seed input field. |
| paused | boolean | True while generation is paused via pause. |
| running | boolean | True while the model is actively producing frames (started and not paused). |
| started | boolean | True once start has been accepted. Reset to false by reset. |
| has_prompt | boolean | True once a shot prompt has been set for the session. |
| current_chunk | number | Index of the last completed chunk within the current scene. Restarts at 0 after every hard scene_cut. |
| current_frame | number | Running total of frames emitted since the last reset or connect. |
| session_chunk | number | Session-wide chunk count — total chunks since the most recent start. Keeps counting across cuts; zeros on start and reset. This is the clock that scheduled cuts and shots fire against. |
| current_prompt | unknown | The prompt currently driving generation, or null when none is set. |
| scheduled_shots | unknown[] | Sorted chunk indices at which scheduled soft shot changes will fire, as session-wide chunk counts. |
| scheduled_scene_cuts | unknown[] | Sorted chunk indices at which scheduled hard cuts will fire, as session-wide chunk counts. |
JavaScript
import { LongliveV2Model } from "@reactor-models/longlive-v2";
const longliveV2 = new LongliveV2Model();
longliveV2.onState((msg) => {
console.log(
"state",
msg.seed,
msg.paused,
msg.running,
msg.started,
msg.has_prompt,
msg.current_chunk,
msg.current_frame,
msg.session_chunk,
msg.current_prompt,
msg.scheduled_shots,
msg.scheduled_scene_cuts,
);
});
await longliveV2.connect(jwt);React
import { useLongliveV2State } from "@reactor-models/longlive-v2";
// Inside a React component wrapped by <LongliveV2Provider>:
useLongliveV2State((msg) => {
console.log(
"state",
msg.seed,
msg.paused,
msg.running,
msg.started,
msg.has_prompt,
msg.current_chunk,
msg.current_frame,
msg.session_chunk,
msg.current_prompt,
msg.scheduled_shots,
msg.scheduled_scene_cuts,
);
});shot_set
Emitted when set_shot is accepted. Before start it confirms the opening shot has been seeded; after start it confirms a soft shot change has been queued for the next chunk boundary.
Listener: onShotSet · React hook: useLongliveV2ShotSet
| Field | Type | Description |
|---|---|---|
| prompt | string | The shot prompt that was accepted. |
JavaScript
import { LongliveV2Model } from "@reactor-models/longlive-v2";
const longliveV2 = new LongliveV2Model();
longliveV2.onShotSet((msg) => {
console.log("shot_set", msg.prompt);
});
await longliveV2.connect(jwt);React
import { useLongliveV2ShotSet } from "@reactor-models/longlive-v2";
// Inside a React component wrapped by <LongliveV2Provider>:
useLongliveV2ShotSet((msg) => {
console.log("shot_set", msg.prompt);
});scene_cut
Emitted when a hard scene_cut fires (immediate or scheduled). Marks the clean break to a new scene: at_session_chunk is the session-wide chunk count at which the new scene took effect. The per-scene chunk counter (current_chunk) restarts at 0 while the session-wide session_chunk keeps counting.
Listener: onSceneCut · React hook: useLongliveV2SceneCut
| Field | Type | Description |
|---|---|---|
| prompt | string | The prompt the scene was cut to. |
| at_session_chunk | number | Session-wide chunk count at which the cut fired (total chunks since the most recent start). |
JavaScript
import { LongliveV2Model } from "@reactor-models/longlive-v2";
const longliveV2 = new LongliveV2Model();
longliveV2.onSceneCut((msg) => {
console.log("scene_cut", msg.prompt, msg.at_session_chunk);
});
await longliveV2.connect(jwt);React
import { useLongliveV2SceneCut } from "@reactor-models/longlive-v2";
// Inside a React component wrapped by <LongliveV2Provider>:
useLongliveV2SceneCut((msg) => {
console.log("scene_cut", msg.prompt, msg.at_session_chunk);
});command_error
Emitted when a command is rejected because preconditions are not met.
Listener: onCommandError · React hook: useLongliveV2CommandError
| Field | Type | Description |
|---|---|---|
| reason | string | Human-readable explanation of why the command was rejected. |
| command | string | Name of the command that was rejected. |
JavaScript
import { LongliveV2Model } from "@reactor-models/longlive-v2";
const longliveV2 = new LongliveV2Model();
longliveV2.onCommandError((msg) => {
console.log("command_error", msg.reason, msg.command);
});
await longliveV2.connect(jwt);React
import { useLongliveV2CommandError } from "@reactor-models/longlive-v2";
// Inside a React component wrapped by <LongliveV2Provider>:
useLongliveV2CommandError((msg) => {
console.log("command_error", msg.reason, msg.command);
});chunk_complete
Emitted once per completed chunk of main_video.
Listener: onChunkComplete · React hook: useLongliveV2ChunkComplete
| Field | Type | Description |
|---|---|---|
| chunk_index | number | Index of this chunk within the current scene. Restarts at 0 after every hard scene_cut; use session_chunk for the cumulative count since start. |
| active_prompt | string | The prompt used to generate this chunk. |
| session_chunk | number | Session-wide chunk count — total chunks since the most recent start. Keeps counting across cuts. |
| frames_emitted | number | Running total of frames emitted since the last reset or connect. |
JavaScript
import { LongliveV2Model } from "@reactor-models/longlive-v2";
const longliveV2 = new LongliveV2Model();
longliveV2.onChunkComplete((msg) => {
console.log(
"chunk_complete",
msg.chunk_index,
msg.active_prompt,
msg.session_chunk,
msg.frames_emitted,
);
});
await longliveV2.connect(jwt);React
import { useLongliveV2ChunkComplete } from "@reactor-models/longlive-v2";
// Inside a React component wrapped by <LongliveV2Provider>:
useLongliveV2ChunkComplete((msg) => {
console.log(
"chunk_complete",
msg.chunk_index,
msg.active_prompt,
msg.session_chunk,
msg.frames_emitted,
);
});shot_scheduled
Emitted when schedule_shot is accepted. Confirms a future soft shot change has been queued — the transition itself fires later when the session reaches at_session_chunk and is reported by that chunk's normal chunk_complete and state messages.
Listener: onShotScheduled · React hook: useLongliveV2ShotScheduled
| Field | Type | Description |
|---|---|---|
| prompt | string | The prompt scheduled for the soft shot change. |
| at_session_chunk | number | Session-wide chunk count at which the scheduled shot change fires (i.e. after this many total chunks since start). |
JavaScript
import { LongliveV2Model } from "@reactor-models/longlive-v2";
const longliveV2 = new LongliveV2Model();
longliveV2.onShotScheduled((msg) => {
console.log("shot_scheduled", msg.prompt, msg.at_session_chunk);
});
await longliveV2.connect(jwt);React
import { useLongliveV2ShotScheduled } from "@reactor-models/longlive-v2";
// Inside a React component wrapped by <LongliveV2Provider>:
useLongliveV2ShotScheduled((msg) => {
console.log("shot_scheduled", msg.prompt, msg.at_session_chunk);
});generation_reset
Emitted after reset clears session state.
Listener: onGenerationReset · React hook: useLongliveV2GenerationReset
| Field | Type | Description |
|---|---|---|
| reason | string | Short human-readable reason the reset was issued. |
JavaScript
import { LongliveV2Model } from "@reactor-models/longlive-v2";
const longliveV2 = new LongliveV2Model();
longliveV2.onGenerationReset((msg) => {
console.log("generation_reset", msg.reason);
});
await longliveV2.connect(jwt);React
import { useLongliveV2GenerationReset } from "@reactor-models/longlive-v2";
// Inside a React component wrapped by <LongliveV2Provider>:
useLongliveV2GenerationReset((msg) => {
console.log("generation_reset", msg.reason);
});generation_paused
Emitted in response to pause, once the current chunk finishes.
Listener: onGenerationPaused · React hook: useLongliveV2GenerationPaused
| Field | Type | Description |
|---|---|---|
| chunk_index | number | Index of the last completed chunk before pausing. |
JavaScript
import { LongliveV2Model } from "@reactor-models/longlive-v2";
const longliveV2 = new LongliveV2Model();
longliveV2.onGenerationPaused((msg) => {
console.log("generation_paused", msg.chunk_index);
});
await longliveV2.connect(jwt);React
import { useLongliveV2GenerationPaused } from "@reactor-models/longlive-v2";
// Inside a React component wrapped by <LongliveV2Provider>:
useLongliveV2GenerationPaused((msg) => {
console.log("generation_paused", msg.chunk_index);
});generation_resumed
Emitted in response to resume when leaving the paused state.
Listener: onGenerationResumed · React hook: useLongliveV2GenerationResumed
| Field | Type | Description |
|---|---|---|
| chunk_index | number | Index of the next chunk to be generated. |
JavaScript
import { LongliveV2Model } from "@reactor-models/longlive-v2";
const longliveV2 = new LongliveV2Model();
longliveV2.onGenerationResumed((msg) => {
console.log("generation_resumed", msg.chunk_index);
});
await longliveV2.connect(jwt);React
import { useLongliveV2GenerationResumed } from "@reactor-models/longlive-v2";
// Inside a React component wrapped by <LongliveV2Provider>:
useLongliveV2GenerationResumed((msg) => {
console.log("generation_resumed", msg.chunk_index);
});generation_started
Emitted once when start succeeds and frames begin streaming.
Listener: onGenerationStarted · React hook: useLongliveV2GenerationStarted
| Field | Type | Description |
|---|---|---|
| prompt | string | The prompt active at the start of generation. |
| chunk_num | number | Total number of chunks the run will produce. |
| frame_num | number | Total number of pixel frames the run will emit. |
JavaScript
import { LongliveV2Model } from "@reactor-models/longlive-v2";
const longliveV2 = new LongliveV2Model();
longliveV2.onGenerationStarted((msg) => {
console.log(
"generation_started",
msg.prompt,
msg.chunk_num,
msg.frame_num,
);
});
await longliveV2.connect(jwt);React
import { useLongliveV2GenerationStarted } from "@reactor-models/longlive-v2";
// Inside a React component wrapped by <LongliveV2Provider>:
useLongliveV2GenerationStarted((msg) => {
console.log(
"generation_started",
msg.prompt,
msg.chunk_num,
msg.frame_num,
);
});generation_complete
Emitted when every chunk of a run has streamed. The session returns to idle (started = false) and is locked: start, set_shot, scene_cut, schedule_scene_cut, and schedule_shot all reject with command_error until the client calls reset. This enforces a clean slate between runs — the prompt and any scheduled cuts or shots from the completed run cannot leak into the next.
Listener: onGenerationComplete · React hook: useLongliveV2GenerationComplete
| Field | Type | Description |
|---|---|---|
| total_chunks | number | Total number of chunks produced by the run. |
JavaScript
import { LongliveV2Model } from "@reactor-models/longlive-v2";
const longliveV2 = new LongliveV2Model();
longliveV2.onGenerationComplete((msg) => {
console.log("generation_complete", msg.total_chunks);
});
await longliveV2.connect(jwt);React
import { useLongliveV2GenerationComplete } from "@reactor-models/longlive-v2";
// Inside a React component wrapped by <LongliveV2Provider>:
useLongliveV2GenerationComplete((msg) => {
console.log("generation_complete", msg.total_chunks);
});scene_cut_scheduled
Emitted when schedule_scene_cut is accepted. Confirms a future hard cut has been queued — the cut itself fires later when the session reaches at_session_chunk and is reported by scene_cut.
Listener: onSceneCutScheduled · React hook: useLongliveV2SceneCutScheduled
| Field | Type | Description |
|---|---|---|
| prompt | string | The prompt scheduled for the scene cut. |
| at_session_chunk | number | Session-wide chunk count at which the scheduled cut fires (total chunks since the most recent start). |
JavaScript
import { LongliveV2Model } from "@reactor-models/longlive-v2";
const longliveV2 = new LongliveV2Model();
longliveV2.onSceneCutScheduled((msg) => {
console.log("scene_cut_scheduled", msg.prompt, msg.at_session_chunk);
});
await longliveV2.connect(jwt);React
import { useLongliveV2SceneCutScheduled } from "@reactor-models/longlive-v2";
// Inside a React component wrapped by <LongliveV2Provider>:
useLongliveV2SceneCutScheduled((msg) => {
console.log("scene_cut_scheduled", msg.prompt, msg.at_session_chunk);
});Tracks
Named media channels between your app and the LongliveV2 model. Use the typed helpers below — LongliveV2Model.publish<Track> / on<Track> in plain JS, and useLongliveV2Track or the per-track <LongliveV2<Track>View> components in React — so track names are checked at compile time.
main_video
A video channel you subscribe to — the model publishes this for your app to render.
JavaScript
import { LongliveV2Model } from "@reactor-models/longlive-v2";
const longliveV2 = new LongliveV2Model();
longliveV2.onMainVideo((track, stream) => {
// attach to a <video> element, pipe to a canvas, etc.
videoEl.srcObject = stream;
});
await longliveV2.connect(jwt);React
"use client";
import { LongliveV2MainVideoView } from "@reactor-models/longlive-v2";
// Inside a component wrapped by <LongliveV2Provider>:
export function Example() {
return <LongliveV2MainVideoView className="w-full aspect-video" />;
}