---
title: "VideoConductor"
description: "Ring Platform generative video orchestration — xAI Grok Imagine Video, draft/production modes, ImageConductor first frames, ring-filebase persistence, and ring-video-create MCP"
locale: "en"
---
# VideoConductor

**VideoConductor** is Ring Platform's async generative video layer — the video counterpart to [ImageConductor](/docs/development/generative-images.md). It polls xAI Grok Imagine Video, optionally uploads MP4s to **ring-filebase**, and records an audit row in PostgreSQL `generated_videos`.

> **Info**
> Use **Founder** / **Developer** tabs in the docs sidebar to filter this page. Founders see operator workflows and cost control; developers see facade APIs, MCP payloads, and storage.

Operators and agents call **`ring-video-create`** (MCP) or `VideoConductor` from server code. Default **`draft`** mode uses **`grok-imagine-video` @ 480p** (~**$0.05/second**) for cheap text-to-video iteration. Set **`remaster: true`** for **720p** finals, or pass **`sourceVideoUrl`** for scene-preserving **edit/remaster** via xAI's video edits API. First-frame stills compose through **ImageConductor**.

## What VideoConductor does

| Capability | Detail |
|------------|--------|
| **Text-to-video (T2V)** | `grok-imagine-video` — montages, UI demos, vague dialogue |
| **Image-to-video (I2V)** | `grok-imagine-video-1.5` — requires `imageUrl`; prompt drives motion |
| **Draft iteration** | 480p presets — minimize cost while scripting scenes |
| **Production remaster** | 720p re-generate or edit pass on an existing MP4 URL |
| **First-frame automation** | `firstFramePrompt` → ImageConductor when `imageUrl` is absent |
| **Thumbnail overlays** | Optional `thumbnail` spec via `lib/media/thumbnail` |
| **Persistence** | ring-filebase CDN URL + `generated_videos` JSONB ledger |
| **Pipeline audit** | `clipId`, `pipelineRequestId`, `refCode`, `actorId` |

## Quality modes

SSOT: `lib/video/video-presets.json`. Passing `imageUrl` on a `draft` request auto-upgrades to **`draft_i2v`**.

| `qualityMode` | Model | Resolution | ~$/sec | Needs `imageUrl` |
|---------------|--------|------------|--------|------------------|
| **`draft`** (default) | `grok-imagine-video` | 480p | $0.05 | No (T2V) |
| **`draft_i2v`** | `grok-imagine-video-1.5` | 480p | $0.08 | Yes |
| **`production`** | `grok-imagine-video` | 720p | $0.05 | No |
| **`production_i2v`** | `grok-imagine-video-1.5` | 720p | $0.14 | Yes |

**`grok-imagine-video-1.5` is not text-only T2V** — it needs a starting frame (`imageUrl` or `firstFramePrompt`). For word-perfect spoken lines, burn VO in post or treat `DIALOGUE:` blocks as best-effort guidance.

### For founders

## Operator journey

```mermaid
flowchart LR
  Draft["Draft @ 480p"]
  Review["Operator review"]
  Remaster["Remaster @ 720p"]
  CDN["ring-filebase CDN"]
  Draft --> Review --> Remaster --> CDN
```

  
- **[ring-video-create MCP](/docs/mcp/ring-video-create.md)** — Bearer-gated tool for agents and ops — draft clips without touching server code.

  
- **[Viral video CLI](/docs/development/generative-videos.md)** — Manifest-driven multi-clip campaigns with draft → remaster upserts.

  
- **[ImageConductor](/docs/development/generative-images.md)** — First-frame stills and shared xAI credentials for I2V scenes.

  
- **[WalletConductor](/docs/features/wallet-conductor.md)** — Same conductor pattern for money paths (top-up, desk, custodial send).

### Surfaces

| Surface | Entry | Auth |
|---------|--------|------|
| **MCP** | `ring-video-create` → `POST /api/mcp/v1/videos/generate` | `RING_MCP_ACCESS_KEY` bearer |
| **Scripted CLI** | `node scripts/ring-viral-video/run-scripted-video.mjs ` | Local `XAI_API_KEY` + gateway token |
| **Server code** | `VideoConductor.generate` / `.remaster` / `.editFromSource` | App runtime |

### Remaster strategies

| Input | Behavior |
|-------|----------|
| `remaster: true` only | Re-generate at **720p** |
| `remaster: true` + **`sourceVideoUrl`** | **`POST /v1/videos/edits`** — scene-preserving edit |

### Cost control workflow

**Draft every scene @ 480p**

Use `qualityMode: draft` (or `draft_i2v` with a still) until framing and motion are acceptable. Manifest CLI upserts by `id::qualityMode` — partial runs never wipe prior clips.

**Remaster winners @ 720p**

Call with `remaster: true` on approved clips, or pass `sourceVideoUrl` from the draft manifest for an edit pass that preserves composition.

**Persist to ring-filebase**

Leave `persistToFilebase` at default `true` so operators get permanent CDN URLs instead of expiring xAI temporary links.

> **Tip**
> Treat draft spend as the learning budget. Only remaster clips that survive review — that is the main lever on xAI video cost.

### For developers

## End-to-end flow

```mermaid
sequenceDiagram
  participant Surface as MCP / CLI / server
  participant VC as VideoConductor
  participant IC as ImageConductor
  participant xAI as xAI API
  participant FB as ring-filebase
  participant DB as generated_videos

  Surface->>VC: generate(ctx) or remaster(ctx)
  opt firstFramePrompt without imageUrl
    VC->>IC: generate still (16:9)
    IC-->>VC: imageUrl
  end
  VC->>xAI: POST /v1/videos/generations or /edits
  xAI-->>VC: request_id
  loop poll until ready
    VC->>xAI: GET /v1/videos/{request_id}
  end
  xAI-->>VC: temporary MP4 URL
  opt persistToFilebase (default true)
    VC->>FB: upload generated/videos/…
    FB-->>VC: permanent CDN URL
    VC->>DB: createDoc generated_videos
  end
  VC-->>Surface: { success, video, firstFrame, thumbnail }
```

## Public API

{`import { VideoConductor } from '@/lib/video/conductor/video-conductor'

const result = await VideoConductor.generate({
  prompt: 'Cinematic product reveal, slow dolly in',
  qualityMode: 'draft',
  duration: 6,
  purpose: 'news-promo',
  actorId: session.user.id,
})

await VideoConductor.generate({
  prompt: 'ACTION: couple laughs. DIALOGUE: Woman says: "Try Ring."',
  firstFramePrompt: 'Nightclub bar, neon magenta, silver ring on finger',
  clipId: '03_sf_nightclub_opener',
  pipelineRequestId: 'campaign-2026-06',
})

await VideoConductor.remaster({
  prompt: 'Improve clarity; same dialogue, clearer lip movement',
  sourceVideoUrl: 'https://vidgen.x.ai/.../draft.mp4',
  remasterFromRequestId: 'prior-draft-request-id',
})`}

### Implementation map

| Layer | Path |
|-------|------|
| Types | `lib/video/conductor/types.ts` |
| Facade | `lib/video/conductor/video-conductor.ts` |
| Presets | `lib/video/video-presets.json` |
| Config | `lib/video/video.config.ts` |
| xAI provider | `lib/video/providers/xai.provider.ts` |
| Request schema | `lib/media/schemas.ts` → `generateVideoBodySchema` |
| MCP route | `app/api/mcp/v1/videos/generate/route.ts` |
| Scripted media | `lib/media/*` — prompt compiler, thumbnail renderer |
| Truth lens | `AI-LEGIOX/legiox-truth-lens/xai-grok-imagine-video-specialist.nodus.json` |

### MCP request body (validated)

{`{
  "prompt": "ACTION: man leans in. DIALOGUE: Man says: \\"So your HOA uses Ring?\\"",
  "firstFramePrompt": "Cinematic still, couple at SF nightclub bar, neon magenta, silver ring visible",
  "qualityMode": "draft",
  "duration": 12,
  "clipId": "03_sf_nightclub_ring_opener",
  "pipelineRequestId": "hoa-nightclub-viral-2026-06"
}`}

| Field | Required | Notes |
|-------|----------|-------|
| `prompt` | Yes | Motion, `ACTION`, `DIALOGUE` blocks |
| `qualityMode` | No | `draft` (default), `draft_i2v`, `production`, `production_i2v` |
| `imageUrl` | For 1.5 I2V | Auto-upgrades draft → `draft_i2v` |
| `firstFramePrompt` | No | Triggers ImageConductor when `imageUrl` absent |
| `thumbnail` | No | `ThumbnailSpec` — overlays on first frame |
| `sourceVideoUrl` | For edit remaster | Prior clip `url` from manifest or CDN |
| `remaster` | No | `true` → `VideoConductor.remaster()` |
| `remasterFromRequestId` | No | Audit link to draft xAI job |
| `persistToFilebase` | No | Default `true` |
| `clipId` / `pipelineRequestId` | No | Multi-clip campaign tracking |
| `purpose` / `refCode` | No | Storage path + referral attribution |

`actorId` is set server-side from the MCP guard — never trust client-supplied actor ids on the gateway.

## Database & storage

Apply migration **`data/migrations/018_generative_media_conductor_schema.sql`** (idempotent).

{`psql "$DATABASE_URL" -f data/migrations/018_generative_media_conductor_schema.sql`}

| Table | Role |
|-------|------|
| `generated_videos` | One row per persisted clip — JSONB `data` holds `GeneratedVideoRecord` |
| `generated_images` | First-frame stills from ImageConductor (separate ledger) |

Indexed JSONB paths: `actorId`, `provider`, `purpose`, `refCode`, `clipId`, `pipelineRequestId`, `qualityMode`, `requestId`, `generationKind`, `remasterFromRequestId`.

```mermaid
flowchart LR
  VC["VideoConductor"]
  FB["ring-filebase\ngenerated/videos/{purpose}/{qualityMode}/{kind}/"]
  DB[("generated_videos\nid + data JSONB")]
  VC -->|upload MP4| FB
  VC -->|createDoc| DB
  DB -.->|url, fileId, requestId| FB
```

BackendSelector routes `generated_videos` and `generated_images` to PostgreSQL. Missing table: upload still succeeds; persist logs a warning until migration 018 is applied.

## Architecture

```mermaid
flowchart TB
  subgraph surfaces["Surfaces"]
    MCP["ring-video-create MCP"]
    CLI["ring-viral-video CLI"]
    SRV["Server imports"]
  end

  subgraph conductor["VideoConductor"]
    GEN[".generate()"]
    REM[".remaster()"]
    EDT[".editFromSource()"]
  end

  subgraph deps["Dependencies"]
    IC["ImageConductor\nfirst frame"]
    TH["renderAndUploadThumbnail"]
    XAI["xai.provider\nstart + poll"]
    FILE["file()\nupload"]
    DB["db().createDoc\ngenerated_videos"]
  end

  MCP --> GEN
  MCP --> REM
  CLI --> MCP
  SRV --> GEN
  GEN --> IC
  GEN --> TH
  GEN --> XAI
  REM --> EDT
  REM --> XAI
  XAI --> FILE
  FILE --> DB
```

## Environment variables

From `env.local.template` — **reuse `XAI_API_KEY`** from ImageConductor:

{`# Shared xAI credentials (also used by ImageConductor)
XAI_API_KEY=your_key
XAI_API_BASE_URL=https://api.x.ai/v1

# VideoConductor tuning
VIDEO_GEN_STORAGE_PREFIX=generated/videos
VIDEO_GEN_POLL_TIMEOUT_MS=900000
VIDEO_GEN_POLL_INTERVAL_MS=5000
XAI_VIDEO_DEFAULT_DURATION=6
XAI_VIDEO_ASPECT_RATIO=16:9

# MCP gateway (ring-video-create)
# RING_MCP_ACCESS_KEY=dev-only-change-me`}

Never commit `XAI_API_KEY` or `RING_MCP_ACCESS_KEY`. MCP routes are bearer-gated via `withMcpGuard`.

## Response shape

| Field | Description |
|-------|-------------|
| `video.url` | Permanent CDN URL (when persisted) or temporary xAI URL |
| `video.temporaryUrl` | Original xAI download link (expires) |
| `video.requestId` | xAI job id — audit and remaster chains |
| `video.recordId` | `generated_videos` row id |
| `firstFrame` | ImageConductor asset when `firstFramePrompt` was used |
| `thumbnail` | Rendered thumbnail when `thumbnail.enabled` |
| `estimatedCostUsd` | `duration × preset rate` estimate |
| `qualityMode` / `resolution` | Effective preset after auto-upgrade |

Moderation failures return `success: false` when xAI sets `respect_moderation: false`.

## Related

  
- **[Generative Gallery](/docs/features/generative-media.md)** — Product/NFT gallery field; video studio polish is backlog there (`GENERATIVE_CREDIT_VIDEO`).

  
- **[Generative videos (developer)](/docs/development/generative-videos.md)** — CLI examples, model pricing table, legacy generate script.

  
- **[Generative images](/docs/development/generative-images.md)** — Shared xAI block and first-frame generation.

  
- **[WalletConductor](/docs/features/wallet-conductor.md)** — Conductor pattern for wallet money paths.

  
- **[Documentation components](/docs/development/docs-components.md)** — MDX widget reference for authoring.

## Release history

| Date | Milestone |
|------|-----------|
| 2026-06-09 | **ImageConductor** — `generated_images` ledger, `ring-image-create` MCP |
| 2026-06-18 | **VideoConductor v1** — draft/production T2V, `ring-video-create` MCP, manifest v2 |
| 2026-06-18 | **I2V modes** — `draft_i2v` / `production_i2v`, `firstFramePrompt`, `sourceVideoUrl` edit remaster |
| 2026-06-19 | **Migration 018** — `generated_videos` on dev + prod |
| 2026-07-12 | **Dual-audience docs** — Founder ops journey vs Developer API/storage |
