Skip to content

Video Analyzer

Watch a clip once and get the lock list — every cut, shot, beat, caption, and face-free range — as text you can wire into Ad Recast, Video Gen, or an LLM.

Video Analyzer watches a video and writes down what it saw, precisely enough to be enforced rather than wished for. It detects every cut with ffmpeg, samples frames from each shot for a vision model, and composes the result deterministically into a lock list: the source facts, what stays LOCKED, what is CHANGING, and the warning that matters most for recasting — which shots show hands with no face in frame. The same analysis renders as a recast prompt for Ad Recast, a recreate brief for Video Gen, a shot list for an LLM, or plain JSON for agents. Switching between those on the card is free; only Analyze video spends money, and it costs a few cents.

Inputs video — the clip to study · talent_image — optional photo of the person you will recast to
Outputs text — one port, carrying whichever render purpose selects
Params model · purpose · wardrobe · changes · notes
Param Notes
model Any model from the LLM catalog (every entry is vision-capable). Default is Claude Sonnet.
purpose Which render goes out on the port. recast (default) is the gate-1 report, a --- RECAST PROMPT --- line, then the lock-list prompt: this is what Ad Recast’s prompt input expects. brief is a shot-for-shot recreate brief for Video Gen. shot_list is the source line plus a markdown table (start, end, size, camera, face, lighting, beats per shot). json is the whole analysis as text, for agents. Changing the purpose on an analysed node swaps the text on the port without a new run.
wardrobe change (default) recasts the presenter and their wardrobe to the talent photo. keep moves wardrobe onto the LOCKED list, so the new person wears what the source presenter wore. Changing this re-runs the analysis.
changes Extra things to change, one per line. Each line becomes a CHANGING entry and a numbered CHANGE op in the recast prompt, and the prompt’s “everything else stays” clause yields to those ops so it never contradicts itself. Changing this re-runs the analysis.
notes Hints for the vision pass: the product’s name, “talent has no glasses”, which part of the clip to focus on. Notes shape the analysis; they are never copied into the prompt.

The wardrobe and changes fields are how you “move items between the lists” without editing the prompt by hand. Edit them after an analysis and the card says so (“Analyze again to apply”), because the panel and the prompt on the wire always reflect the values the analysis was actually composed with.

Nothing renders until an analysis exists, and the panel only turns amber when there is a real warning. Top to bottom:

  • Source line — shot count, duration, dimensions, frame rate, the audio verdict, and codecs, for example Source: 8 shots, 26.10s, 720x1280, 30fps, original audio (speech + ambience, no music — inferred from frames; on-camera speech in shots 1,2,7), h264/aac.
  • ✗ PREFLIGHT (red, only when the clip would be refused by Ad Recast): the failing limits, and for an over-30-second clip the cut-aligned segments that fit plus an ffmpeg recipe for the first one.
  • The face-free warning (amber, only when there is one): ⚠ Shots 3-6 (9.5-16.5s, 27% of runtime) show hands with no face in frame. followed by why it matters (Seedance cannot re-identify these; they keep the source creator’s hands, build, nails and jewellery too) and the three ways out: cast talent with a similar skin tone to the source creator, accept the mismatch, or choose a source ad without face-free body shots. When every shot has a face in frame you get a green “No face-free body shots” line instead.
  • Unknown shots — ? Shots 4, 5 could not be judged for a face in frame — check them before recasting. A shot the model could not judge is never silently counted as “has a face”.
  • Talent photo lines — Talent photo: … for each problem the vision pass found with the wired photo (angle, obstructed face, theatrical expression, retouched skin, lighting direction, text or logos on clothing, skin tone versus the source when face-free shots exist). Without a talent photo you get a reminder that the PERSON line is generic.
  • The 24 fps note — when the source is not 24 fps: “Frame rate is not preserved — output will be 24fps (source 30fps); cuts still land.”
  • LOCKED — cuts, the shot roster (index, span, size, camera, face flag), camera buckets (handheld, static, tracking), beats, product scale and hand-contact points, lighting continuity and its physical logic, original audio and its sync, on-screen text, and wardrobe when you chose keep.
  • CHANGING — the presenter line, one line per changes entry, and, if the prompt had to be trimmed to fit Seedance’s 4000-character limit, a note saying exactly which change lines were dropped so the list you approve matches the prompt that is sent.
  • Shots (collapsed) — the full shot table.
  • Text on screen + audio (collapsed) — every caption, graphic, or logo with its styling, placement and timing, and the audio summary.

Below the panel sits the deliverable for the chosen purpose with a Copy button. For recast, only the prompt is repeated there, since the panel already shows the report.

Ad Recast’s Compose from ad button runs this same analyzer and drops the prompt straight into Ad Recast’s box. Use it when you only want one recast and do not need the analysis anywhere else. Place a Video Analyzer node when you want to reuse the analysis (recast, brief, and shot list from one spend), keep the lock list visible as its own card, tune wardrobe, changes, or notes, or let an agent read the report before anything is rendered. Wiring the analyzer into Ad Recast’s prompt input disables Compose there; the analyzer owns the text then.

  • Face-free shots keep the source person. Shots that show the body with no face in frame keep the original creator’s hands, build, nails, and jewellery. That is a model limitation, not a prompt problem, and the warning exists so you decide before paying for a render.
  • Beats are approximate. Frames are sampled on a grid of one per second, capped at 32 for the whole clip (each shot keeps its first frame while the budget allows; past 32 shots the panel names the ones that were not sampled). A beat’s time is the model’s reading of those frames, snapped to 0.5 s and clamped inside its shot. Cuts, by contrast, come from ffmpeg and are exact.
  • Audio is inferred from frames. Whether a track exists and whether it is silent are measured. Speech, ambience, and music are inferred from lips, captions, and visible instruments, and the source line says so.
  • Output is 24 fps whatever the source frame rate. Cut timing still lands; the note appears before you spend and again in the recast report.
  • The cost estimate is the list rate. Ad Recast prices per source second from the provider’s list price. Whether the provider bills input and output seconds separately is still being verified against a wallet, so treat the number as an estimate.
  • Recast an ad — purpose: recast, wire the port into Ad Recast’s prompt input. Read the panel, then press Recast Ad on that node. Full walkthrough in Recast a winning ad.
  • Recreate an ad with new footage — purpose: brief, wire into Video Gen’s prompt. The brief names the pacing, every shot with its span, size, camera, beats and lighting, the on-screen text, the audio, and an avoid list. Add your own product and talent references on the Video Gen node.
  • Shot list for a writer or editor — purpose: shot_list, wire into an LLM to rewrite or into an Output node to keep. It is a markdown table, so it pastes cleanly into a doc.
  • JSON for agents — purpose: json. The same structure an MCP client gets in the job’s result.metadata.analysis, but on the port, so it can feed a text input.

The analyzer is the step an agent must not skip. Run it, relay the gate-1 block to the person, and only then approve the recast:

create_canvas_node node_type: "ad-analyzer" params: { purpose: "recast" }
create_canvas_node node_type: "ad-recast"
connect_canvas_nodes source: <video input> target: <analyzer> target_handle: "video"
connect_canvas_nodes source: <analyzer> target: <recast> target_handle: "prompt"
connect_canvas_nodes source: <talent image> target: <recast> target_handle: "talent_image"
run_canvas_node node_id: <analyzer> wait: true
→ output text; show the user everything before "--- RECAST PROMPT ---"
→ get_job result.metadata.schema == "video-analysis/1", .analysis, .renders
# after the user approves:
update_canvas_node node_id: <recast> params: { approved: true }
run_canvas_node node_id: <recast> wait: false idempotency_key: <a NEW key>

Running Ad Recast with a wired prompt and no approved returns “Ad Recast is waiting for approval”. The rejected run is remembered under its idempotency key, so the approved run needs a fresh one. See Claude & MCP for the connection setup.