本文へ移動
cccskills
無料GitHub で公開日本語紹介

varg-consistent-characters

人物やキャラクター、衣装、場所の見た目を複数の場面で揃えた広告動画を作り、静止画で確認してから音声・字幕付きの映像に仕上げます。

原文原文の説明を見る

Makes multi-scene ad videos on varg in which the same people, outfits and location stay consistent in every shot, built from real actor photos or generated characters: one profile card per actor, an empty location card, scene composites approved as stills first, then image-to-video with native dialogue audio, trimmed and captioned in one cloud render. Also covers frame and audio QA of the output and turning a reference video into a scene script. Use when a script names actors (A1, A2), a location (L1) and numbered scenes, when someone sends actor or model photos, or asks for a consistent character, the same person in every scene, a recurring mascot or brand character, a UGC or skit ad with two actors, or to remake a reference ad with new people. Not for one speaker on a stage (use varg-character-keynote), seated two-person podcast dialogue (use varg-podcast-video), music videos (use varg-music-video), or one-off images and clips (use varg-ai).

hashgraph-online/awesome-codex-pluginsスター 1,440(GitHub 1,440 + cccskills 0)

実行スコア 未検証

インストール方法を見る

こんなときに便利

  • 出演者が場面をまたいで登場する広告
  • 同じマスコットの動画を作りたいとき
  • 参考広告からシーン台本を作りたいとき
  • 生成動画の字幕と音声を確認したいとき

日本語での紹介

できること

人物写真や生成キャラクターをもとに、複数場面で人物、衣装、場所の見た目が揃った広告動画を作ります。出演者ごとのプロフィール画像と人物のいない場所画像を用意し、それらを参照して場面ごとの静止画を生成します。静止画を確認してから、台詞を含む映像を生成し、クラウド上で長さを整え、字幕を付けてまとめます。完成後は場面のフレームや音声も確認できます。台本がない場合は、参考動画の場面構成や台詞を読み取り、生成用のシーン台本に整理します。

こんなときに便利

出演者や場所が指定された複数場面の広告、同じマスコットを繰り返し登場させる動画、2人が出演するUGC風広告や寸劇に向いています。参考広告の構成を新しい人物で作り直したい場合にも使えます。ステージ上の1人語り、座った2人のポッドキャスト、ミュージックビデオ、単発の画像や短い映像には適しません。

使い方の例

  • 「この出演者写真と台本で、人物とジムの見た目が揃った広告動画を作って」
  • 「この参考広告を場面ごとに整理して、新しい出演者で作る台本にして」
  • 「生成した動画の人物、字幕、音声を確認して」

注意点

VARG_API_KEYまたはvarg MCP接続が必要です。静止画をまとめて確認するスクリプトにはbun、ローカルで映像を検査する場合はffmpegとffprobeを使います。

この紹介文は、公開されている SKILL.md をもとに AI(OpenAI Codex)が作成しました。正確な仕様は下の原文を確認してください。

含まれるファイル(1)

  • SKILL.md18.5 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

varg consistent characters

Turn a scene script + actor photos into a multi-scene vertical ad where characters, outfits and location stay consistent across every cut. Tested on a 5-scene, 22-second 9:16 fitness ad with two real actors in one gym.

Generation runs on varg: the varg-ai skill (sign-in, models, local and cloud render) or the varg MCP server (https://mcp.varg.ai/mcp). This skill assumes a working VARG_API_KEY or MCP connection.

Core idea: cards, then composites

Never describe characters from scratch in every scene prompt. Build a small set of frozen reference images once, then compose every scene from them.

photo A1 ──edit──> a1Card ─┐
photo A2 ──edit──> a2Card ─┼──edit──> scene1..N ──image-to-video──> vid1..N
prompt   ──gen───> gymLoc ─┘

Upload the actor photos first (POST /v2/files, or the MCP upload tools) and use the returned URLs.

No actor photos? Design the cast with varg-character-design (archetypes, a model sheet per character on flat grey) and use each character's full-body crop as the profile card below.

1. Consistency

1.1 Character profile cards

One image-edit call per actor, from their photo:

const a1Card = Image({
  prompt: {
    text: "Full-body character reference card of the exact same woman from the photo: same face, same grey hair, same body shape. <age/build>. She wears <FIXED OUTFIT, described precisely>. Standing straight facing camera, neutral relaxed pose, arms at her sides. Plain light grey studio background, even soft lighting, head-to-toe framing, photorealistic",
    images: [A1_PHOTO_URL],
  },
  model: varg.imageModel("nano_banana_2_1"),   // edits when images are passed
  aspectRatio: "9:16",
});

Rules that make cards work:

  • "exact same ... from the photo: same face, same hair, same body shape" anchors identity to the reference instead of the text description.
  • Fix the outfit in the card. The card's clothes become the outfit for the whole video. Pick it so the script works (e.g. arms or legs visible if scenes point at them). Never re-describe clothes differently later.
  • Full body, neutral pose, plain studio background: a clean card composites into any scene; a scene-styled card does not.

The pipeline was first built with Nano Banana Pro edit; nano_banana_2_1 is its successor and varg's default. For the hardest identity cases try gpt_image_2_5.

1.2 Location card

One text-to-image generation, no people:

const gymLoc = Image({
  prompt: "Empty modern gym interior with huge floor-to-ceiling windows... No people. ... photorealistic, 9:16 portrait framing",
  model: varg.imageModel("nano_banana_2_1"),
  aspectRatio: "9:16",
});

An empty location card lets every scene reuse the same walls, light and floor without characters from a previous scene leaking in.

1.3 Scene composites

Every scene is one edit call with all three refs:

const SAME =
  "First reference image is Woman A (<short recap of card>). Second reference image is Woman B (<short recap>). Third reference image is the gym location with huge windows. Keep both women's faces, hair, bodies and outfits exactly as in their reference cards, and the gym exactly as in the location reference.";

const scene2 = Image({
  prompt: { text: `${SAME} <scene-specific framing, poses, gestures>`, images: [a1Card, a2Card, gymLoc] },
  model: varg.imageModel("nano_banana_2_1"),
  aspectRatio: "9:16",
});
  • The SAME preamble is shared verbatim across all scenes. It names each reference by position ("First reference image is...") and pins identity.
  • Image edit models take several refs fine. For Video, one image = the first frame; several images switch to reference mode, which only some models support (see varg-ai).
  • Scene text only describes what changes: camera framing, poses, gestures, expressions.

1.4 Cache discipline (critical)

Identical prompt + params = free cache hit, both locally and server-side on api.varg.ai. This is what makes the whole pipeline cheap:

  • Keep prompts byte-identical between the images-only script, the local template and the cloud template. Copy-paste, never retype.
  • The full 5-scene video re-rendered in the cloud for a few credits (the stitching fee) because every image, video and music prompt matched the earlier runs.
  • Editing one scene's prompt regenerates only that scene; everything else stays cached.

1.5 Content-moderation gotcha

Body-part wording such as "rear" or "booty" in an image prompt can silently stall generation for ~10 min (provider moderation). Rephrase to neutral anatomy: "hips and thighs". The same words inside spoken dialogue in video prompts passed fine.

Fitness and swimwear scenes trip filters on words, not pictures: "girl" instead of "woman, 28", "tight", "bikini" and short prompts without a garment description get blocked on GPT Image 2.5, FLUX 3 and Grok, while a catalog-style prompt (adult age as a number, each garment named, an activity, "activewear brand catalog photo") passed on all six image models we tried. A block can be random: retry once, then rephrase, then route. Test log, safe-phrasing table and routing: varg-character-design → references/moderation.md.

2. Photos-for-approval pass (images first)

Generate and show all stills before paying for any video. A still costs a few credits; a video clip costs ten times more or more. Approve the cheap layer first.

Standalone script pattern (<project>-images.ts, run with bun):

import { Image } from "vargai/react";
import { createVarg } from "vargai/ai";

const varg = createVarg({ apiKey: process.env.VARG_API_KEY! });
// ... define a1Card, a2Card, gymLoc, scene1..sceneN exactly as in 1.x ...

async function save(name: string, el: ReturnType<typeof Image>) {
  const resolved = await el;               // await triggers generation (cached)
  await Bun.write(`output/<project>/${name}.png`, await resolved.file.data());
}

// cards + location first, then scenes (scenes reference the cards)
await Promise.all([save("a1-card", a1Card), save("a2-card", a2Card), save("location", gymLoc)]);
await Promise.all([save("scene1", scene1), /* ... */]);

Key facts:

  • Image({...}) is a lazy thenable: await resolves it, .file.data() gives the bytes. Awaited results are cached, so the later video render reuses them for free.
  • Run it in the background (nohup bun run <project>-images.ts > images.log 2>&1 &) and report the PID.
  • Show the user: the cards + location + every scene. Iterate on individual scene prompts (only the changed one regenerates) until approved.

No bun? Generate the same stills one by one with POST /v2/image (or MCP generate_image), passing the references in files. Keep the prompts identical to the ones you will use in the render.

3. Final render: cloud (POST /v2/render)

After the stills are approved, wrap them in videos + composition and submit the whole TSX to the cloud. No bun or ffmpeg needed on the machine that submits.

3.1 Video layer: image-to-video with native audio

Dialogue is written into the video prompt and the model voices it:

const vid2 = Video({
  prompt: {
    text: `Same gym with huge windows. <scene action, static camera>.
The trainer says matter-of-factly: "<the scene's line>"
Soft gym ambient sounds.`,
    images: [scene2],                      // exactly ONE image = the first frame
  },
  model: varg.videoModel("kling_v4"),
  audio: "native",                         // generates and keeps the dialogue audio
  duration: 4,                             // integer seconds (kling_v4: 3-30)
});
  • Quote dialogue lines verbatim in the prompt; add a voice direction ("clear encouraging voice", "matter-of-factly").
  • Budget ~1 s of dialogue per ~2.5 words, then trim (3.3).
  • kling_v3 is what this pipeline was first tested on and still works the same way (integer 3-15 s); kling_v4 is the current Kling. seedance_2_5 gives the best faces and lip movement at a higher price.
  • Native audio needs audio: "native". A flat providerOptions: { varg: { generate_audio: true } } is silently dropped and you get a silent clip.

3.2 Cloud TSX rules

POST https://api.varg.ai/v2/render with {"code": "<tsx>"} (MCP: render_video with code):

  • No imports, no createVarg: Render/Clip/Image/Video/Music/Captions and varg are injected as globals. Local LSP errors on this file are expected and fine.
  • Must export default (<Render ...>...); no named exports.
  • Same varg.*Model() ids as local.

Price it first (MCP estimate_cost with tool render and the code, or POST /v2/estimate on each clip's request) and get the user's go-ahead. Then submit and poll:

curl -s -X POST https://api.varg.ai/v2/render \
  -H "Authorization: Bearer $VARG_API_KEY" -H "Content-Type: application/json" \
  -d "{\"code\": $(jq -Rs . < template-cloud.tsx)}"
# -> {"id":"job_xxx",...}; poll every 15s:
curl -s https://api.varg.ai/v2/jobs/JOB_ID -H "Authorization: Bearer $VARG_API_KEY"
# completed -> output.outputs[0].url  (s3.varg.ai mp4)

If all prompts match a previous run, the cloud render costs a few credits (server cache) and finishes in ~2 min.

3.3 Dynamic pacing: trim dead air

Generated clips have ~0.2-0.5 s of warm-up and often trailing silence. Detect speech boundaries on the generated clips, then cut tight:

ffmpeg -i scene.mp4 -af "silencedetect=noise=-35dB:d=0.35" -f null -
<Clip cutFrom={0.2} cutTo={5.6} duration={5.4}>{vid1}</Clip>  // cut right after the line ends

This took the test video from 27 s to 22.4 s with no content loss. Keep Music duration an integer: a fractional total like 22.4 failed with a 422 on ElevenLabs music. Round down.

3.4 Centered captions in the cloud (inline SRT)

<Captions> transcribes Speech elements by itself. For dialogue that lives in a video's native audio, the tested route is two passes (newer vargai builds also accept src={vid.audio}; if the render rejects that with "Captions src must be ...", use this route):

  1. Render once without captions (cloud or local).
  2. Upload the audio and transcribe it on varg: POST /v2/files (upload) -> POST /v2/transcription with {"model":"whisper_large_v3","audio_url":...}. The result has word-level timestamps.
  3. Build a word-level SRT; fix Whisper mishears (product names, unusual words). Captions' prompt prop can also pass context hints to Whisper.
  4. Embed the SRT inline in the cloud TSX. The srt prop takes a file path, and template code runs on the render server, so write the file to /tmp at module eval:
const SRT_CONTENT = `1
00:00:00,260 --> 00:00:00,320
You
...`;
const SRT_PATH = `/tmp/project-${Date.now()}.srt`;
await Bun.write(SRT_PATH, SRT_CONTENT);
// in <Render>:
<Captions srt={SRT_PATH} style="tiktok" position="center"
          color="#ffffff" activeColor="#a3e635" wordsPerLine={3} fontSize={64} />

Re-submitting is nearly free (everything cached); only the composition re-runs. Important: if you change any clip trim, regenerate the SRT, because the timings shift.

4. QA: how to analyze what you generated

Agents can't watch video, but they can read frames and measure audio.

4.1 Visual QA: extract frames and READ them

After every render (and every images pass), pull frames and inspect them as images. Never ship a video you haven't frame-checked.

# one frame per scene, at a timestamp INSIDE that scene (mind the trims)
ffmpeg -v error -ss 3  -i out.mp4 -frames:v 1 -vf scale=270:-1 check-s1.png -y
ffmpeg -v error -ss 9  -i out.mp4 -frames:v 1 -vf scale=270:-1 check-s3.png -y
ffmpeg -v error -ss 14 -i out.mp4 -frames:v 1 -vf scale=270:-1 check-s4.png -y
  • Downscale (scale=270:-1 .. 360:-1): enough to judge, cheap on context.
  • Read several frames in one parallel tool call.
  • No local ffmpeg? The varg MCP analyze_video tool answers questions about a rendered video.

Visual checklist per frame:

  • Identity: same face/hair/body as the profile cards, in every scene.
  • Outfit drift: clothes must match the cards exactly (color, cut, shoes). Drift usually means a scene prompt re-described clothing: fix the wording, not the card.
  • Location drift: windows/floor/props consistent with the location card.
  • Framing: matches the script (full-body vs close-up); subjects not cropped at the wrong place; both actors present when required.
  • Captions: correct position (center), readable size, active-word color visible, no overlap with faces.
  • Age/build drift: edit models can age or slim a person between scenes. Compare against the card and regenerate the outlier scene only.

Also verify structure numerically:

ffprobe -v error -show_entries format=duration,size -of default=noprint_wrappers=1 out.mp4

Duration must equal the sum of clip durations; a mismatch means a clip or music duration bug, not an encoding issue.

4.2 Audio QA: silencedetect as ears

silencedetect shows where speech actually lives in each generated clip:

ffmpeg -i scene.mp4 -af "silencedetect=noise=-35dB:d=0.35" -f null - 2>&1 | grep silence_

Read it per clip:

  • silence at the start -> dead air / late speech start -> raise cutFrom;
  • silence at the end -> line finished early -> lower cutTo;
  • no silence in an N-second clip -> speech fills it; if the line is long, the model may have rushed or truncated it: listen-check via transcription;
  • silence in the middle of a one-line clip -> possible stutter or split delivery.

Then confirm the words: transcribe the final mix (3.4 step 2) and diff the transcript against the script. This catches mispronunciations by the video model and mishears by Whisper. Fix mishears in the SRT; regenerate the clip only if the model actually said the wrong thing.

4.3 When to regenerate vs when to trim

SymptomFix
Dead air, late start, early finishTrim with cutFrom/cutTo: free
Wrong/garbled spoken lineRegenerate that Video
Identity/outfit drift in one sceneRegenerate that scene Image, then its Video
Caption timing off after re-trimRegenerate the SRT only (one transcription)

5. No script? Analyze the reference video first

When the user sends a reference video instead of a script, reverse-engineer the same A/L/Scene structure this skill consumes. Do this before touching any generation. (media-download fetches a reference by link.)

5.1 Extract structure

ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1 ref.mp4

# scene cut candidates (hard cuts)
ffmpeg -i ref.mp4 -vf "select='gt(scene,0.35)',showinfo" -f null - 2>&1 | grep showinfo | grep pts_time

# speech map
ffmpeg -i ref.mp4 -af "silencedetect=noise=-35dB:d=0.35" -f null - 2>&1 | grep silence_

Scene-cut timestamps + speech gaps together give the beat structure: how many scenes, how long each, where dialogue sits.

5.2 Sample frames per scene

Extract 1-2 frames inside each detected scene and read them (parallel call):

ffmpeg -v error -ss <t> -i ref.mp4 -frames:v 1 -vf scale=360:-1 ref-s1.png -y

From the frames, document for each scene:

  • Actors: who is on screen, rough age/build/hair -> becomes A1, A2...
  • Wardrobe: what each actor wears (this defines the profile-card outfits).
  • Location: environment, light, key props -> becomes L1 (L2...).
  • Framing: full-body / medium-wide / close-up; front or back view; camera static or moving; who is closer to camera.
  • Action + gesture: what each actor does (squats, points at X, thumbs-up).

5.3 Get the dialogue

Transcribe the reference audio (same varg call as 3.4). Map each line to its scene via the timestamps. If there's no speech, note the music mood and on-screen text instead.

5.4 Write the script, then confirm

Assemble the standard format and show it to the user for approval before generating anything:

Actors:
- A1: <description from frames>  - C1: <wardrobe>
- A2: <description>
Location:
- L1: <description>
Scene 1 (Ns): <framing>. <action>. A2 says: "<line>". L1
Scene 2 ...

From here the pipeline is identical: cards (1.1) -> location (1.2) -> composites (1.3) -> approval pass (2) -> videos + cloud render (3). Use the reference's measured scene durations as the initial duration values, and its framing notes verbatim in scene prompts.

Cost reference (5 scenes, ~22 s at 9:16)

Rough credits from the varg catalog (October 2026). Always quote the user the exact figure from POST /v2/estimate / estimate_cost, in credits.

StepCredits (~)
8 images (2 cards + location + 5 scenes), nano_banana_2_1~65
5 Kling clips with native audio, 4-6 s at 720p~400-500
Music bed (mureka_9_5) + one transcription~30
Cloud re-render with everything cacheda few (stitching fee)
Iterating one scene image / one scene video~8 / ~80-100

Related skills

varg-ai (sign-in, models, render formats), varg-character-keynote (one speaker on a stage), varg-podcast-video (two seated characters in dialogue), varg-previz (plan many shots and camera moves first), media-download (fetch a reference video), video-skills (find a skill for another format).

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

コメント

ログインなしで書き込めます。使ってみた感想、質問、動かなかった環境などを気軽にどうぞ。

まだコメントはありません。最初のコメントを書いてみませんか。

送信するとすぐに公開されます。メールアドレスや電話番号などの個人情報は書かないでください。URL は 2 つまでです。

0 / 1000 文字

このフォームは reCAPTCHA で保護されており、Google のプライバシーポリシーと利用規約が適用されます。

同じリポジトリのスキル

accelerate-local-work

無料概要あり

複数の独立したローカル作業を安全性と依存関係を確認して実行計画にまとめ、対応環境では並列化やAppleシリコン向け処理の選択を支援します。

  • ビルドやテストの独立した処理を並列化したいとき
  • 複数段階の作業計画を安全に実行したいとき
  • Appleシリコン向け処理の候補を確認したいとき
hashgraph-online/awesome-codex-plugins1,4362026年10月27日 更新

ad-creative-testing

無料概要あり

TikTokやMeta広告の勝ちパターンを分解し、異なる切り口のテスト案や予算、評価時期を整理して、数値から継続・修正・停止を判断するスキルです。

  • 勝ち広告を分解して次のテスト案を作りたいとき
  • 広告の本数やテスト予算を決めたいとき
  • 似た広告案の成果が変わらない原因を探したいとき
hashgraph-online/awesome-codex-plugins1,4402026年10月30日 更新

add

無料概要あり

将来の読み手が理由を知りたくなる未決定や暫定対応を、技術的負債として登録し、後から項目ごとに整理できるスキルです。

  • 暫定対応を負債として記録したいとき
  • TODOや未完了作業を管理したいとき
  • 負債の影響箇所や解消条件を残したいとき
hashgraph-online/awesome-codex-plugins1,4402026年10月30日 更新

adk-framework-adapters

無料概要あり

LangChain、EINO、AutoGen、AgentScope、CrewAI向けのコード雛形やAPI対応、プロジェクト構成を参照し、バージョン確認を踏まえてAIエージェント開発を支援します。

  • 指定したフレームワークで雛形を作りたいとき
  • 複数のエージェントフレームワークを比較したいとき
  • ツール定義やメモリ設定の例を参照したいとき
hashgraph-online/awesome-codex-plugins1,4362026年10月26日 更新

agent-debug-fixer

無料概要あり

エラーやテスト失敗、画面の異常などを再現して原因を特定し、テストで確認しながら影響を絞った修正を進めるデバッグ用スキルです。

  • テスト失敗の根本原因を調べたいとき
  • 画面や機能の不具合を小さく修正したいとき
  • 再発防止のテストを先に用意したいとき
hashgraph-online/awesome-codex-plugins1,4402026年10月30日 更新

agent-dev-workshop

無料概要あり

対話を通じてAI Agentの要件整理から設計、ツール定義、コード生成、動作確認まで6段階で進め、実行可能なプロジェクトを作ります。

  • Agentの要件と設計を整理したいとき
  • 実行可能なAgentの試作品を作りたいとき
  • ツールやPromptの構成を決めたいとき
hashgraph-online/awesome-codex-plugins1,4362026年10月26日 更新

hashgraph-online のスキルをすべて見る

このスキルの問題を報告する