@amaster.ai/pi-video-gen

extensionmaintained

Pi extension for AI video generation plus local video composition: lossless clip concat and mixed image/video timelines with overlays, TTS, soft or burned subtitles, source audio, BGM, and bundled LGPL/GPL FFmpeg runtimes.

by · v0.1.8 · published 2d ago

$ pi install npm:@amaster.ai/pi-video-gen
downloads/mo
742
stars
40
last push
1d ago
open issues
3

Signals

license: Apache-2.0testspi manifest: missinginstall size: —deps: 0peer deps: 0

Download trend

781 downloads · last 12 weeks (weekly)

README

pi-video-gen

Pi extension for agentic video generation. Ships the single-clip primitive (video_generate), the multi-shot render pipeline (video_render), local lossless clip composing and mixed-media promo timelines with overlays, TTS, soft or burned subtitles, source-video audio, and BGM (video_compose), the read-only video_capabilities query, a /video-gen command, and the video-gen skill that orchestrates the full shot-book workflow together with pi-image-gen (all image work).

Providers

Wire formatModelsStatus
ark (Volcengine Ark)Seedance 2.0 standard / fast / mini✅ built-in
dashscope (Alibaba)HappyHorse 1.1 / 1.0 (t2v/i2v/r2v auto-routed)✅ built-in
kling (Kuaishou)Kling 3.0 Turbo / 3.0 Omni (API 2.0)✅ built-in
minimaxMiniMax-H3 (v2 API)✅ built-in
openroutergoogle/veo-3.1 (+ custom models)✅ built-in
newapiself-hosted NewAPI relay (Kling / Jimeng / Vidu / Gemini channels)✅ via customProvidersbaseUrl required
customyour own endpoints✅ via customProviders

Registry entries are written against provider documentation (each adapter's header notes the source) and are pending live smoke tests against real accounts — verify with /video-gen doctor + one small paid clip before heavy use. Seedance 2.5 stays on the roadmap until its official API ID and parameter contract are published.

Setup

Global settings (~/.pi/agent/settings.json):

{
  "pi-video-gen": {
    "defaultModel": "seedance-2.0",              // alias of doubao-seedance-2-0-260128
    "providers": {
      "ark": { "apiKey": "${ARK_API_KEY}" }      // Volcengine Ark key
    },
    "rateLimit": { "maxRequestsPerMinute": 2, "maxRequestsPerDay": 20 },
    "concurrency": { "clips": 2 }
  }
}

Custom providers (same idea as pi-image-gen's — point any Ark-compatible endpoint at your own models; string models get conservative capabilities, object models declare them). When a custom model's id names a built-in model (e.g. "MiniMax-H3" behind your relay), the built-in capability table and defaults are inherited automatically — undeclared capabilities, defaultResolution/defaultAspectRatio/defaultDurationSec fall back to the registry values instead of the conservative 720p/16:9 profile, and any field you do declare overrides the inherited one:

{
  "pi-video-gen": {
    "defaultModel": "fast9",
    "customProviders": {
      "myproxy": {
        "api": "ark",
        "baseUrl": "https://proxy.example/api/v3",
        "apiKey": "${MY_PROXY_KEY}",
        "models": [
          "seedance-lite-x",
          { "id": "remote-model-9", "alias": "fast9",
            "capabilities": { "maxReferenceImages": 2, "durations": [2, 30],
              "resolutions": ["480p", "720p", "1080p"], "aspectRatios": ["16:9", "9:16"],
              "nativeAudio": true, "supportsFirstLastFrame": true } }
        ]
      }
    }
  }
}

NewAPI notes (video format docs): NewAPI is a self-hosted relay, so the newapi wire format has NO default endpoint — baseUrl is mandatory and resolution fails with the exact settings path to fix when it is absent. Both the server root ("https://newapi.example.com") and the OpenAI-style "…/v1" form are accepted. Channel-specific parameters ride in metadata following the upstream doc examples: aspect_ratio + resolution (Jimeng/Vidu style), image_tail for the last frame (Kling style) and image_urls for extra reference images (Jimeng style); the first frame goes in the top-level image field. There is no documented audio toggle or idempotency key, so ambiguous submits are parked for manual resolution rather than auto-retried:

{
  "pi-video-gen": {
    "defaultModel": "kling-v1",
    "customProviders": {
      "newapi": {
        "api": "newapi",
        "baseUrl": "https://newapi.example.com",   // REQUIRED
        "apiKey": "${NEWAPI_API_KEY}",
        "models": ["kling-v1", "jimeng_vgfm_t2v_l20", "viduq1"]
      }
    }
  }
}

MiniMax notes (v2 API, create / query): MiniMax-H3 speaks a multimodal task API — prompt + frames ride in one content array with first_frame / last_frame / reference_image roles (first/last frames and reference images are mutually exclusive; a last frame requires a first frame). Resolution is 768P or 2K, duration 4–15s, ratio 16:9|4:3|1:1|3:4|9:16|21:9 — required and non-adaptive for text-to-video, ignored (forced adaptive) once a first frame is present. There is no audio toggle, no idempotency key and no documented cancel endpoint, so ambiguous submits are parked for manual resolution rather than auto-retried. Auth is a plain Bearer key (providers.minimax.apiKey, env MINIMAX_API_KEY), and keys are region-locked: the default endpoint is international api.minimax.io — mainland-China keys need providers.minimax.baseUrl set to https://api.minimaxi.com (and vice versa a 401 means wrong region). Result URLs are time-limited; clips are downloaded immediately, and tasks stay queryable for 7 days.

Kling notes (verified against kling.ai/document-api via browser, 2026-07): current Kling API 2.0 uses a plain API key (providers.kling.apiKey, env KLING_API_KEY) — the JWT ak/sk scheme is legacy. The model lives in the URL path (kling-3.0-turbo / kling-3.0); default base is api-singapore.klingai.com (regional endpoints via baseUrl). Kling 3.0 Omni supports last-frame, native audio and 4k; Turbo is first-frame-only and silent. Submits carry external_task_id (our request fingerprint), so ambiguous failures are looked up first; an inconclusive lookup is parked for manual resolution rather than blindly resubmitted.

HappyHorse notes: no native audio and no last-frame interpolation (nativeAudio: false, supportsFirstLastFrame: false in the capability table, so the tools hide/reject those options). One call takes either a first frame (i2v) OR reference images (r2v, prompt them as [Image 1], [Image 2], …), not both. The default endpoint is the classic dashscope.aliyuncs.com (no workspace id needed); if you use a new Bailian workspace, set providers.dashscope.baseUrl to https://{workspaceId}.cn-beijing.maas.aliyuncs.com. Video/task URLs expire after 24h — clips are downloaded immediately.

Trust boundary: providers.*, customProviders.* and ffmpegPath are honored ONLY from global / agent-dir settings — project-level .pi/settings.json can set outputDir, defaultModel, rateLimit, concurrency only (and only when the project is trusted). A malicious repo cannot redirect your API key or swap binaries.

ffmpeg: required for multi-shot concat and installed automatically with the plugin through a platform-specific optional npm package. The main plugin stays small, while pi install npm:@amaster.ai/pi-video-gen downloads only the platform payload matching the current OS and CPU. That payload contains a default LGPL build plus separately named GPL ffmpeg-gpl/ffprobe-gpl binaries with libx264 for requested H.264 timeline output. Supported bundled targets are macOS 11+ arm64/x64, glibc Linux arm64/x64 (built on Ubuntu 22.04), and Windows x64; musl Linux uses a system FFmpeg through PATH. Resolution order: ffmpegPath setting → FFMPEG_PATH env → installed platform package → ffmpeg-static (development only) → PATH. An automatic bundled candidate that is present but not runnable is skipped so it cannot mask a working PATH installation. Check with /video-gen doctor. Release CI builds every platform package from the pinned official FFmpeg source with external-library autodetection disabled; the exact FFmpeg, zlib, and x264 source archives, build script, licenses, and provenance ship beside the binaries.

Tools

ToolWhat it does
video_composeLocal video assembly, no paid video models. C0 (compose-input.json) concatenates compatible clips. Timeline media, overlays, transitions, subtitles, source audio, and BGM render locally. Narration is an explicit network feature: setting voice to edge-tts:<voice-name> sends narration text to Microsoft Edge TTS.
video_generateOne short clip from a prompt (+ optional first/last frame images). Paid, minutes per clip. Interrupted after receiving a task id? Resume with the returned jobId; an ambiguous submit is parked and never resubmitted automatically.
video_renderMulti-shot film from <jobDir>/render-input.json: snapshots + hashes all frames, submits one paid task per shot (resume-aware, finished shots never re-bill), downloads clips, ffmpeg-concats into final_video.mp4.
video_capabilitiesRead-only: active model's capability table + registered models. Call before composing prompts or shot books.

Commands

CommandWhat it does
/video-gen compose <spec>Same as the video_compose tool
/video-gen generate <prompt>Same as the video_generate tool
/video-gen render <spec>Same as the video_render tool
/video-gen recover <jobId>List ambiguous render shots; explicitly reset a confirmed-absent task or adopt <taskId> found in the provider console
/video-gen modelsList registered models + key readiness
/video-gen reloadReload settings
/video-gen doctorEnvironment check (key, ffmpeg+ffprobe, libx264, CJK fonts, image_generate, output dir, trust)

The shot-book workflow (multi-shot films)

Driven by the video-gen skill in conversation:

  1. Shot book — the agent authors a shot book (characters + shots with first/last-frame descriptions, motion, audio, continuity) and you review it in chat. Default small: 1 scene, 3–5 shots.
  2. Frames — the agent generates character portraits and per-shot frames via image_generate (pi-image-gen), tracking real returned paths in assets.json.
  3. Render — after explicit confirmation, ONE video_render call pays for and stitches everything.

Jobs on disk

<cwd>/.video-gen/<jobId>/
├── render-input.json   # immutable spec (revisions = new job dir)
├── assets.json         # semantic assets ↔ image_generate's real returned paths
├── manifest.json       # state + per-shot remote handles + frame SHA-256 (atomic, single writer)
├── shots/<shotId>/first_frame.png|last_frame.png|video.mp4
└── final_video.mp4

Crash or cancel mid-render? Rerun the same spec path — the input fingerprint (spec + frame hashes + model/provider) is verified, then persisted handles resume via inspect without re-billing. NOTE: cancelling stops local polling only; the remote task may keep running and billable (Ark cancellation support is unverified). If submit completion is ambiguous, rerun is blocked until /video-gen recover <jobId> explicitly resets or adopts the affected shot. Single-clip ambiguous submits are also persisted and blocked; check the provider console before starting another generation. Single-job resume independently recomputes the request fingerprint from its frozen input.json; an inspect 404 keeps the remote handle and parks the job as ambiguous instead of declaring it safe to resubmit.