> ## Documentation Index
> Fetch the complete documentation index at: https://docs.reactor.inc/llms.txt
> Use this file to discover all available pages before exploring further.

# LongLive-2.0 overview

> What LongLive-2.0 is, its key features, and a quick start.

export const ModelRate = ({model}) => {
  const [data, setData] = useState(null);
  const [error, setError] = useState(false);
  const [loading, setLoading] = useState(true);
  useEffect(() => {
    const ctrl = new AbortController();
    fetch("https://api.reactor.inc/pricing", {
      signal: ctrl.signal
    }).then(r => {
      if (!r.ok) throw new Error(`HTTP ${r.status}`);
      return r.json();
    }).then(json => {
      setData(json);
      setLoading(false);
    }).catch(err => {
      if (err.name === "AbortError") return;
      setError(true);
      setLoading(false);
    });
    return () => ctrl.abort();
  }, []);
  if (loading) {
    return <span aria-label="loading pricing" className="inline-block h-4 w-28 rounded bg-zinc-950/10 dark:bg-white/10 animate-pulse align-middle" />;
  }
  const creditsPerDollar = data?.settings?.credits_per_dollar;
  const amountPerSec = data?.models?.find(m => m.name === model)?.rate?.amount_per_sec;
  const canRender = !error && creditsPerDollar && typeof amountPerSec === "number";
  if (!canRender) {
    return <span className="text-zinc-950/60 dark:text-white/60">see current rate below</span>;
  }
  const perHour = Math.round(amountPerSec / creditsPerDollar * 3600);
  const perSec = (amountPerSec / creditsPerDollar).toFixed(4);
  return <span>
      <strong>${perHour}/hr</strong> (${perSec}/sec)
    </span>;
};

**LongLive-2.0** is an autoregressive, real-time video model built for **multi-shot** generation: a
single session moves through many scenes without ever tearing down the stream. Set an opening shot,
then steer with soft **shot transitions** and hard **cuts**, sent live or scheduled in advance.

The LongLive-2.0 reference is split across four pages: this overview, the complete
[command and event schema](/model-api-reference/longlive-v2/schema), the
[prompt guide](/model-api-reference/longlive-v2/prompt-guide) for writing prompts and composing
multi-shot sequences, and an end-to-end [tutorial](/model-api-reference/longlive-v2/tutorial)
against the open-source reference frontend.

The base wire protocol is the same as every other Reactor model: open a session with the
[`Reactor`](/sdk-reference/reactor-class) class (model name `reactor/longlive-v2`), send named
commands, and receive events. LongLive-2.0's surface adds commands for shots, cuts, scheduling,
changing the seed, and playback control. Generation is text-driven, there is no reference-image
input in this release.

## At a glance

| Spec            | Value                             |
| --------------- | --------------------------------- |
| **Model name**  | `reactor/longlive-v2`             |
| **Pricing**     | <ModelRate model="longlive-v2" /> |
| **Resolution**  | 1280 × 704                        |
| **Frame rate**  | 24 fps                            |
| **Chunk size**  | 29 frames (\~1.2s)                |
| **Scene limit** | 48 chunks (\~58s) per scene       |
| **Transitions** | shots (soft) · cuts (hard)        |
| **Input**       | Text only (no reference image)    |

The **model name** is the string you pass when you open a session, e.g.
`new Reactor({ modelName: "reactor/longlive-v2" })`; the `create-reactor-app` CLI and the pricing
catalog use the short slug `longlive-v2`. See [Pricing & Billing](/resources/billing) for how
billing works.

## Key features

<CardGroup cols={3}>
  <Card title="Multi-shot generation" icon="film">
    One continuous session spanning many scenes: change shots and cut to new scenes without
    reconnecting.
  </Card>

  <Card title="Soft shots & hard cuts" icon="scissors">
    A soft `set_shot` keeps the world and continuity; a hard `scene_cut` breaks cleanly to a new
    scene.
  </Card>

  <Card title="Storyboard scheduling" icon="timeline">
    Schedule shots and cuts at exact chunk indices to compose a whole sequence before you press
    start.
  </Card>
</CardGroup>

## Chunks, scenes, and length

LongLive-2.0 generates video one **chunk** at a time. A chunk is **29 frames, about 1.2 seconds at
24fps**. Every `chunk_complete` event carries two counters that track your position:

* **`chunk_index`**: chunks since the current scene began. Resets to 0 on every `scene_cut`.
* **`session_chunk`**: cumulative chunks since `start`. Never resets. This is the clock that
  scheduled prompts fire against.

**Each scene can run for up to 48 chunks (\~58 seconds), after which it completes on its own.** That
limit is per scene, not per session, which is what lets you control total length:

* A **`scene_cut`** ends the current scene and starts a fresh one with a **new 48-chunk budget**,
  so cuts are how you extend a video. A session that keeps cutting can run indefinitely; one that
  never cuts stops at \~58 seconds.
* A **`set_shot`** stays in the current scene (keeping its memory) and **spends from the same
  budget**. Use it to evolve a scene, not to lengthen it.

**To make a video longer, cut to a new scene; to evolve a scene in place, send a shot.** A prompt
scheduled past its scene's 48-chunk ceiling never fires, so cut before you reach it.

## Quick start

The fastest path to a working LongLive-2.0 app is the `create-reactor-app` CLI, which scaffolds a
runnable project. You can also clone the
[open-source reference frontend](https://github.com/reactor-team/js-sdk/tree/main/examples/longlive-v2)
directly, or follow the [tutorial](/model-api-reference/longlive-v2/tutorial) for a guided
walkthrough.

<Tabs>
  <Tab title="npm">
    ```shell theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
    npx create-reactor-app my-longlive-app --model=longlive-v2
    ```
  </Tab>

  <Tab title="pnpm">
    ```shell theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
    pnpm create reactor-app my-longlive-app --model=longlive-v2
    ```
  </Tab>
</Tabs>

Working in Python instead? The CLI is JavaScript-only, so install the SDK with
`pip install reactor-sdk` and follow the Python tab below (see the
[quickstart](/quickstart) for the full walkthrough).

A minimal connect-and-generate flow looks like:

<CodeGroup>
  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
  import { Reactor } from "@reactor-team/js-sdk";

  const video = document.querySelector("video")!;
  const reactor = new Reactor({ modelName: "reactor/longlive-v2" });

  // Render frames as soon as they arrive.
  reactor.on("trackReceived", (name, track, stream) => {
    if (name !== "main_video") return;
    video.srcObject = stream;
    void video.play();
  });

  // Once the session is ready, open a shot and start generating.
  reactor.on("statusChanged", async (status) => {
    if (status !== "ready") return;
    await reactor.sendCommand("set_shot", {
      prompt: "A lighthouse on a cliff at dusk, waves crashing below",
    });
    await reactor.sendCommand("start", {});
  });

  const jwt = await getToken(); // token minted on your server
  await reactor.connect(jwt);
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-high-contrast"}}
  import asyncio
  import os
  from reactor_sdk import Reactor, ReactorStatus

  async def main():
      reactor = Reactor(model_name="reactor/longlive-v2", api_key=os.environ["REACTOR_API_KEY"])

      # Frames arrive as (H, W, 3) uint8 RGB NumPy arrays.
      @reactor.on_frame
      def on_frame(frame):
          print(f"Frame: {frame.shape}")

      # Once the session is ready, open a shot and start generating.
      @reactor.on_status(ReactorStatus.READY)
      async def on_ready(status):
          await reactor.send_command("set_shot", {
              "prompt": "A lighthouse on a cliff at dusk, waves crashing below",
          })
          await reactor.send_command("start", {})

      await reactor.connect()
      await asyncio.Event().wait()  # run until interrupted

  asyncio.run(main())
  ```
</CodeGroup>

LongLive-2.0 also has a typed SDK, `@reactor-models/longlive-v2`, with named methods (`setShot`,
`sceneCut`, `start`, …) and React hooks. See [Typed Model SDKs](/sdk-reference/typed-model-sdk).

## How it works

On connect the model is live but idle. Set an opening shot with `set_shot`, call `start`, and frames
begin streaming on the `main_video` track. From there you drive the session in real time: send a
`set_shot` or `scene_cut` to transition at the next chunk boundary, `schedule_shot` /
`schedule_scene_cut` to plant prompts ahead, `pause` / `resume` between chunks, and `reset`
to clear everything and begin a new sequence.

See the [schema](/model-api-reference/longlive-v2/schema) for every command and event, and the
[prompt guide](/model-api-reference/longlive-v2/prompt-guide) for how to compose multi-shot
sequences.
