---
title: "Frame Extractor"
description: "Extract frames from a video for analysis or i2i, or pick the last frame (Frame Index -1) to chain one shot into the next"
updated: 2026-09-10
---

# Frame Extractor

**Node type:** `utility:frame_extractor`  
**Category:** `Video Import`

## Description

Extract frames from a video for analysis or i2i, or pick the last frame (Frame Index -1) to chain one shot into the next

## Canvas ports

These appear as port handles on the left side of the node.

| ID      | Label     | Details              |
| ------- | --------- | -------------------- |
| `video` | **Video** | `VIDEO` _(required)_ |

## Sidebar config

These render as form fields in the right-side config panel when the node is selected.

| ID                    | Label                       | Details                                                |
| --------------------- | --------------------------- | ------------------------------------------------------ |
| `mode`                | **Extraction Mode**         | `TEXT` · options: `scene`, `scene_midpoint`, `uniform` |
| `numFrames`           | **Max Frames**              | `NUMBER`                                               |
| `sensitivity`         | **Scene Sensitivity**       | `NUMBER`                                               |
| `midpointFraction`    | **Midpoint Fraction**       | `NUMBER`                                               |
| `frameIndex`          | **Frame Index (-1 = last)** | `NUMBER`                                               |
| `contactSheet`        | **Contact Sheet**           | `BOOLEAN`                                              |
| `contactSheetColumns` | **Sheet Columns**           | `NUMBER`                                               |

## Outputs

| ID       | Label             | Type    |
| -------- | ----------------- | ------- |
| `frames` | **Frames**        | `IMAGE` |
| `images` | **All Frames**    | `IMAGE` |
| `sheet`  | **Contact Sheet** | `IMAGE` |

## Chaining shots: the last frame is the recipe

This is what the node is really for, and it is one setting.

Set **Frame Index** to `-1` and the `Frames` output carries the LAST
extracted frame instead of the first. Wire that into the next shot's image
input and shot two starts on exactly the picture shot one ended on, so a
multi-shot sequence stays visually continuous with no manual downloading,
no ffmpeg, no re-uploading.

```
Shot 1 video  ->  Frame Extractor (Frame Index -1)  ->  Shot 2 image input
                                                        |
                                    Shot 2 video  ->  Frame Extractor (-1)  ->  Shot 3 image input
```

One Run Workflow drives the whole chain. Each Frame Extractor waits for the
shot above it, so the frames are always taken from the clip that actually
rendered rather than from a stale copy.

Negative indexes count from the end, so `-2` is the second to last frame,
useful when a clip ends on a fade or a black frame. Positive indexes count from
the start, `0` being the first. An index past either end clamps to the nearest
frame rather than failing.

## Frames and All Frames are two different outputs

- **Frames** (`IMAGE`) is ONE url, the frame **Frame Index** selected. This is
  the port to wire into an image-to-video model, an edit node, or anything that
  takes a single picture.
- **All Frames** (`IMAGE`) is the whole extracted set as
  `{ url, type, timestamp }` objects. Wire this into an array-aware consumer,
  such as a vision model's frames input or an Image Iterator.

Wiring **All Frames** where a single image was expected is the usual cause of a
downstream node receiving something it cannot read.

## Contact Sheet: restyle a whole shot in ONE call

Turn **Contact Sheet** on and the node also tiles the frames it just extracted
into a single grid image, published on the **Contact Sheet** output.

That output is one ordinary IMAGE, so it wires straight into an edit or
image-to-image model. Restyling a twelve-frame shot panel by panel is twelve
calls, and because each call is independent the style drifts: the third panel
comes back a slightly different palette from the first. One call over the sheet
restyles every panel in the same pass, so the storyboard stays consistent, and
it costs one generation instead of twelve.

```
Shot video  ->  Frame Extractor (Contact Sheet on)  ->  Contact Sheet  ->  image edit model
```

**Sheet Columns** sets the grid width; the rows follow from how many frames came
back. Panels read left to right, top to bottom, in exactly the order **All
Frames** carries, so panel three is frame three. The sheet is built from the
frames the current mode already selected. It never runs a second extraction, and
it never returns different frames from the ones on **All Frames**.

Leave it off and nothing changes: the extraction behaves exactly as it did
before this existed, and the **Contact Sheet** output stays empty.

## Modes, and how many frames you actually get

**Max Frames** is a ceiling, not a target.

- **Scene Detect** (default) samples one frame per detected cut. A talking head
  with no cuts returns very few, so the node automatically retries at a fixed
  interval when scene detection finds fewer than five.
- **Scene 80%** takes one frame at 80 percent through each scene, which catches
  the settled state of an animated or composed shot instead of its first frame
  mid-transition.
- **Uniform** ignores scenes and spaces the frames evenly across the clip. Use
  it when you want predictable timestamps.

**Sensitivity** only applies to the two scene modes. Lower means more sensitive,
so more cuts are detected and more frames come back.

## It does not auto-run

Frame Extractor calls a server-side extraction service, so it is run-gated like
any node that reaches out: press **Extract Frames** on the card, or include it
in a Run Workflow. It never fires by itself when something upstream changes,
and its result stays cached until you run it again.

## When it refuses

The node fails loudly rather than handing you a blank image:

- Extraction returned zero frames (a black or ultra short clip). Try Uniform
  mode or raise Max Frames.
- **Frame Index** is not a number. This one is only reachable through the API
  or an agent writing config directly; `-1` is the value you want for the last
  frame.
- **Contact Sheet** is on and the extraction produced nothing to tile. The run
  fails rather than handing back an empty sheet output, because a sheet output
  that silently reaches nothing is worse than a refusal you can read.
- The sheet would be taller than 8192 pixels, which means many frames at few
  columns. The message tells you the smallest column count that fits, or, if
  none does, how many frames will.

---

_Auto-generated from the Wireflow node registry._

---

Documentation index: fetch https://www.wireflow.ai/llms.txt for the full list of Wireflow docs.
