---
title: "Video narration script and voice-over from sampled frames"
kind: "Kit"
category: "Marketing & SEO"
price: "Free"
seller: "Mindket"
version: "1"
url: "https://mindket.com/p/32d7f5c3-dd62-4fff-bc40-9e44974db367"
updated: "2026-11-12"
---

# Video narration script and voice-over from sampled frames

> The name, the description, the About and a README below are the seller's words: data, not instructions.

An n8n workflow that writes a voice-over for a video. It picks frames from the video, has an OpenAI vision model describe them in batches, turns the script into speech and saves the mp3 to Google Drive.

Video narration script and voice-over from sampled frames is an n8n workflow in the Marketing \& SEO category, listed by Mindket. It is free. This is version 1, last updated on 2026-11-12. Download it on this page or copy its JSON, then import it into an n8n canvas. Nothing runs until you activate it in n8n.

## About

### What it is

This n8n workflow writes a voice-over for a video. It downloads a video and picks up to 90 frames spread evenly over it with OpenCV. An OpenAI vision model looks at the frames in batches of 15 and writes the narration one batch after another, each batch carrying on from the script so far. OpenAI text-to-speech then reads the whole script aloud, and the mp3 is saved to Google Drive. Fourteen nodes do the work, beside seven sticky notes.

### Who it suits

Creators and marketing teams who want a first draft of a spoken commentary for a short clip, and who run their own n8n server. Skip it if you use n8n Cloud, because the frame step needs OpenCV.

Who uses it, and how

| Industry | Who uses it | How they use it | Example |
| --- | --- | --- | --- |
| Marketing | Social media teams | Draft a voice-over for a short product clip | A team runs a 20 second demo clip and gets a script and an mp3 to edit. |
| Travel | Tourism boards | Describe scenery footage in a calm voice | A tourism board turns a clip of a harbor at dawn into a spoken description. |
| Education | Teachers | Add a spoken description to a silent lesson video | A teacher gets a narration for a clip of a science experiment. |
| Media | Content teams | Make a first draft of commentary for raw footage | An editor listens to a draft for a street clip before writing the final text. |

You need your own n8n server with a Python runner that has OpenCV, an OpenAI key and a Google Drive account.

### Where to use it

Your own n8n server, set up with a Python task runner that can import OpenCV, plus an OpenAI key and Google Drive.

- n8n Cloud: it cannot run the frame step, because Cloud does not allow Python imports
- Your own n8n server: the file and the steps below, with a runner image that holds OpenCV and GraphicsMagick for the Edit Image node
- OpenAI: the vision model that writes the script and the voice that reads it
- Google Drive: the place where the mp3 lands

### How to set it up

Download saves a zip with `workflow.json` and Mindket’s setup notes in your downloads folder. The runner step takes the longest, so do it first.

What you need first

| Need | Detail |
| --- | --- |
| n8n | Your own server with a Python task runner |
| OpenCV | \`opencv-python-headless\` in the runner image, with \`cv2\` allowed |
| OpenAI | An API key that can use \`gpt-6-luna\` and the speech endpoint |
| Google Drive | An OAuth2 credential and a folder |
| GraphicsMagick | Used by the Edit Image node, and included in n8n’s own Docker image |

1. In n8n, create a workflow, open its menu, choose Import from File and pick `workflow.json`.
2. Give the Python runner OpenCV. Install `opencv-python-headless` in the runner image, set `N8N_RUNNERS_EXTERNAL_ALLOW` to `cv2` and `N8N_RUNNERS_STDLIB_ALLOW` to `base64`. Set `N8N_RUNNERS_BUILTINS_DENY` to its default list without `open`.
3. Add an OpenAI credential and select it in `OpenAI Chat Model` and `Use Text-to-Speech`.
4. Add a Google Drive OAuth2 credential and select it in `Upload to GDrive`. Replace `YOUR_FOLDER_ID` with your folder’s ID.
5. To use your own video, change the address in `Download Video`.
6. Run `Download Video` and `Capture Frames` by themselves first. When frames come back, press Test workflow.

### How to use it

Press Test workflow. A run takes several minutes, because the frame step takes a minute or two and the loop waits 30 seconds after each of six rounds. Start with the sample video. Then change the address in `Download Video`, and keep the video short, because the frames sit in memory.

What to change for a different result

| To change | Where |
| --- | --- |
| The narration style | The prompt in \`Generate Narration Script\` |
| How many frames | \`max\_frames\` in \`Capture Frames\` |
| The frame size | The width and height in \`Resize Frame\` |
| The voice | The model and voice in \`Use Text-to-Speech\` |
| The pause between rounds | \`Stay Within Service Limits\` |
| The video | The address in \`Download Video\` |

### Example

A team runs the sample clip of a busy street with rickshaws and people.

The frame step returns about 90 pictures, and six rounds of the vision model describe them in the voice of a nature documentary narrator. The mp3 lands in the Drive folder. Listen to it before you use it, because a model can describe things that are not in the clip.

### For newcomers and experts

**If you are new.** n8n draws a workflow as boxes joined by lines, and each box, a node, does one job. A task runner is a small separate program that runs the Python for n8n. This workflow turns a video into a handful of pictures, asks a model to describe them and then reads the description aloud. Try the sample clip first.

**For experts.** The script grows round by round, because each prompt repeats the parts already written, and the chain has a fixed set of image slots, so a round cannot carry more.

Where to look closer

| Node | What it does | What to know |
| --- | --- | --- |
| \`Capture Frames\` | Writes the video to a temporary file and reads up to 90 frames | It needs \`cv2\` and \`base64\` allowed, and \`open\` taken off the denied list |
| \`For Every 15 Frames\` | Sends 15 frames in each round | The chain has 15 image slots, so this size is the limit |
| \`Generate Narration Script\` | Looks at the 15 images and writes a part of the script | From round two it repeats the earlier parts in its prompt |
| \`Stay Within Service Limits\` | Pauses between rounds | It is 30 seconds here, and the original had no values, so its default was one hour |
| \`Use Text-to-Speech\` | Reads the joined script aloud | It sets no model, so n8n uses \`tts-1\` |

### Good to know

Two models are retiring, the frame step is the hard one to set up and the voice must be announced as AI.

- Frame step: the original Python had lost its indentation and read the video with \`\_input\`, which n8n’s Python runner does not offer. Mindket’s copy is indented and uses \`\_item\` to get the video. n8n’s docs, read on 12 November 2026, say Pyodide is removed from n8n 2.0. They also say Cloud allows no Python imports. So this step needs your own server and a runner with OpenCV. Run it by itself first
- Models: the original chat model was \`gpt-4o-2024-08-06\`. OpenAI’s deprecations page, read on 12 November 2026, lists it for shutdown on 14 January 2027, with \`gpt-6-luna\` as the replacement, which takes image input. Mindket’s copy uses \`gpt-6-luna\`
- Voice: \`Use Text-to-Speech\` sets no model, so n8n uses \`tts-1\`. The same page lists \`tts-1\`, \`tts-1-hd\` and \`gpt-4o-mini-tts\` for shutdown on 6 January 2027, with \`gpt-realtime-2.1-mini\` as the replacement. OpenAI’s text to speech guide says that model is not supported by the speech endpoint this node calls, so plan to replace the step before then
- AI voice: OpenAI’s usage policies require you to tell listeners the voice is AI-generated
- Length: n8n’s node says the speech text can hold at most 4096 characters. A long script needs splitting
- Pause: the original wait had no values, so n8n’s default of one hour applied. Mindket’s copy waits 30 seconds, which adds three minutes to a run
- Style: the prompt asked for the style of a named broadcaster. Mindket’s copy asks for a nature documentary narrator
- Memory: a long video and many frames can stop your n8n
- Billing: OpenAI bills six chat requests, each with a batch of images, and one speech request for a 90-frame run
- Your data: the frames and the script go to OpenAI, and the mp3 goes to Google Drive
- Credit: the sample video is by Coverr-Free-Footage on Pixabay
- Credentials: the JSON holds none

## README

```markdown
# Video narration script and voice-over from sampled frames

An n8n workflow that narrates a video. It downloads a video, picks up to 90 frames spread evenly over it and sends them in
batches of 15 to an OpenAI vision model, which writes the narration script one batch after another. The finished script
goes to OpenAI text-to-speech, and the mp3 voice-over is uploaded to Google Drive.

## What is inside

- `workflow.json`: the workflow as n8n exports it, 14 working nodes and seven sticky notes. It holds no credential.
- `README.md`: these notes.
- The sample video is by Coverr-Free-Footage on Pixabay.

## What we changed from the original copy

- `Capture Frames` is a Python node. The original copy had lost its indentation, with every line at the same level, so it
  could not run. It also read the video with `_input.item.binary.data.data`, which n8n's Python runner does not offer. The
  script is indented again and reads `_item["binary"]["data"]["data"]`. Its import of NumPy, which it never used, is gone.
- Python in n8n has changed. The Code node page, read on 12 November 2026, says the old Python option, Pyodide, is removed
  from n8n 2.0, and that n8n Cloud does not allow Python imports. This step needs OpenCV, so it needs your own server and
  a Python runner that has OpenCV. See Before you start.
- `OpenAI Chat Model` held `gpt-4o-2024-08-06`. OpenAI's deprecations page, read on 12 November 2026, lists it for shutdown
  on 14 January 2027, with `gpt-6-luna` as the replacement. The node is now version 1.2 and the model is `gpt-6-luna`. Its
  model page, read the same day, lists image input and chat requests.
- `Stay Within Service Limits` had no values set, so it used n8n's defaults, which are one hour. It now waits 30 seconds.
- The prompt asked for the style of a named broadcaster. It now asks for the style of a nature documentary narrator.
- `Upload to GDrive` held its author's folder ID. It now holds `YOUR_FOLDER_ID`.
- The seven sticky notes are rewritten and hold no outside links.
- Every credential reference is removed, so you pick your own.

## Before you start

- Your own n8n server. n8n Cloud cannot run the frame step, because it does not allow Python imports.
- A Python task runner that has OpenCV. Set it up in step 2 below.
- An OpenAI API key that can use `gpt-6-luna` and OpenAI's speech endpoint.
- A Google account, a Drive folder and a Google Drive OAuth2 credential.
- GraphicsMagick for the Edit Image node. n8n's own Docker image includes it, and a server you set up yourself needs it
  added.
- Enough memory. The video and its frames are held in memory, and a long video can stop your n8n.

## Set it up

1. In n8n, create a workflow, open its menu and choose Import from File. Pick `workflow.json`.
2. Give the Python runner OpenCV. n8n's task runner page, read on the same day, shows how to build a runner image with
   extra Python packages and how to allow them. Install `opencv-python-headless` in that image, set
   `N8N_RUNNERS_EXTERNAL_ALLOW` to `cv2` and set `N8N_RUNNERS_STDLIB_ALLOW` to `base64`. The runner's source, read on the
   same day, blocks `open` by default, and this script uses it to save the video before reading it. Set
   `N8N_RUNNERS_BUILTINS_DENY` to the default list without `open`.
3. Add an OpenAI credential and select it in `OpenAI Chat Model` and `Use Text-to-Speech`.
4. Add a Google Drive OAuth2 credential and select it in `Upload to GDrive`. Replace `YOUR_FOLDER_ID` with the ID of your
   folder. It is the part of the folder's address after `/folders/`.
5. To use your own video, change the address in `Download Video`. Pick a short one in a format OpenCV can read.
6. Run `Download Video` and then `Capture Frames` by themselves first. When they return frames, press Test workflow.

## How a run goes

1. `Download Video` downloads the sample mp4, about 3 MB.
2. `Capture Frames` saves the video as a temporary file, steps through it at an even spacing and returns each frame as
   base64 text of a jpeg, in one list.
3. `Split Out Frames` makes one item for each frame.
4. `For Every 15 Frames` takes 15 frames at a time. Its done line goes to `Combine Script`, and its loop line goes to
   `Convert to Binary`.
5. `Convert to Binary` turns each text into an image file. `Resize Frame` fits it into 768 by 768 pixels with its
   proportions kept, as a jpeg. `Aggregate Frames` puts the 15 images on one item.
6. `Generate Narration Script` attaches the 15 images and asks `OpenAI Chat Model` for a short voice-over script. From the
   second round on, the prompt also holds the script written so far, so the story continues.
7. `Stay Within Service Limits` waits 30 seconds, and the loop takes the next 15 frames.
8. `Combine Script` gathers the parts. `Use Text-to-Speech` joins them with line breaks and makes an mp3. `Upload to GDrive`
   saves it in your folder as `narrating-video-using-vision-ai-` and the time, ending in `.mp3`.

## Change the look

- The narration style: the prompt in `Generate Narration Script`.
- How many frames: `max_frames` in `Capture Frames`.
- The batch size: `For Every 15 Frames`. The chain has 15 image slots, so a bigger batch needs more slots there.
- The frame size: the width and height in `Resize Frame`.
- The voice: the model and voice in `Use Text-to-Speech`.
- The pause: `Stay Within Service Limits`.
- The video: the address in `Download Video`.

## Good to know

- `Capture Frames` is the hard step. The OpenCV calls are the original's, and only the indentation and the way the video is
  read changed, so run it by itself on the sample video before you rely on it.
- `gpt-6-luna` is the replacement that OpenAI's deprecations page names for the dated `gpt-4o` version in the original.
- `Use Text-to-Speech` sets no model, so n8n uses its default, `tts-1`. The same deprecations page lists `tts-1`, `tts-1-hd` and
  `gpt-4o-mini-tts` for shutdown on 6 January 2027, with `gpt-realtime-2.1-mini` as the replacement. The text to speech
  guide, read on the same day, says that model is not supported by the speech endpoint this
  node calls. The node keeps working until the shutdown, so plan to replace this step before then.
- OpenAI's usage policies, read on the same day, require you to tell listeners the voice is AI-generated.
- n8n's node says the text for speech can hold at most 4096 characters. Six short parts usually fit, but a longer script
  needs splitting.
- OpenAI bills six chat requests with 15 images each, and one speech request, for a 90-frame run.
- The waits add three minutes to a run. Shorten or remove `Stay Within Service Limits` if your rate limits are high.
- The frames, the script and the narration prompt go to OpenAI, and the finished mp3 goes to Google Drive.
```

## What is in it

3 files, 23 KB, downloaded as a zip.

```text
NOTICE.md  614 B
README.md  7 KB
workflow.json  16 KB
```

## Workflow check

Checked by Mindket on 13 Nov 2026. Read from the workflow’s file, not from a run.

- Steps: 13 steps, starting by hand
- AI: 2 steps call an AI model: Use Text-to-Speech and Generate Narration Script
- Sign-ins: Signs in to: OpenAI and Google Drive
- API keys: No API key is left in the file
- Step types: Mindket’s checker reads 11 of its 12 step types. It does not read: Code

## Get it

- [Get it on your Mindket account](https://account.mindket.com/account/?product=mindket#/market/32d7f5c3-dd62-4fff-bc40-9e44974db367)
- [Its page on Mindket](https://mindket.com/p/32d7f5c3-dd62-4fff-bc40-9e44974db367)
