FlowKit

Generating automatic subtitles for your videos with n8n and Whisper

Published 10 August 2026 · 6 min read

Captioning a 20-minute video by hand easily takes an hour, and dedicated tools (Rev, Sonix, Descript) bill by the minute — expensive fast once a team produces tutorials, product demos, or training modules at volume. Yet the technical piece that does all the work — Whisper, OpenAI's speech recognition model — is accessible through a simple API key, for a few cents per video. n8n can orchestrate the whole pipeline: fetching the source, timestamped transcription, SRT formatting, and publishing. Here's how to build it end to end.

Why build this pipeline instead of paying for a dedicated tool

Most automatic captioning platforms rely on the same family of speech recognition models exposed directly through the OpenAI API — they add an interface and a subscription, not a fundamentally different technology. Building the pipeline yourself in n8n has three concrete advantages: a cost that stays proportional to actual usage (no monthly tier to justify), video files that never pass through any extra third-party service, and above all direct integration with the rest of your content pipeline — automatic publishing, archiving, multi-language translation, all in the same workflow. It's the same logic detailed in our guide on transcribing and summarizing meetings with Whisper: one AI building block, several uses, no unnecessary subscription.

One important distinction: this differs from extracting the existing subtitles of a third-party YouTube video, covered in our guide on transcribing YouTube videos. Here, you start from a raw audio or video file — your own — and generate subtitles from scratch.

Pipeline overview

Four steps are enough: fetch the source, transcribe with timestamps via Whisper, convert the result into an SRT (or VTT) file in a Code node, then publish or archive that file. An optional fifth step adds automatic translation for multilingual distribution.

Step 1 — Fetch the source video or audio

Three common triggers, from simplest to most automated:

  • Form Trigger with a file field, to test the pipeline without any external integration or shared folder.
  • Google Drive trigger ("new file") watching a folder where a marketing or training team's raw exports land.
  • S3 trigger or a scheduled HTTP Request node, if videos come from an already-automated video production pipeline.

Whisper accepts an audio file directly (mp3, wav, m4a…), but also some common video formats. For a large video, though, it's better to send only the audio track: it weighs a fraction of the full video file and stays under the API's 25 MB limit for much longer. On a self-hosted instance, an Execute Command node calling ffmpeg -i video.mp4 -vn -acodec libmp3lame audio.mp3 extracts that track in a second — our guide on the Execute Command node covers the precautions this node requires (sandboxing, self-hosted only). On n8n Cloud, where running system commands isn't available, either send audio already extracted upstream, or go through a third-party extraction service via HTTP Request.

Step 2 — Transcribe with timestamps via Whisper

The OpenAI node, in "Transcribe" mode, accepts the binary file received in the previous step. The setting that matters most for the rest of the pipeline is response_format: with verbose_json instead of plain text, the response includes a segments array, each with text, a start, and an end in seconds. Without those timestamps, there's no way to produce a synchronized subtitle file — the key difference from a "meeting summary" use case where only the raw text matters.

For files longer than about twenty minutes, plan for a Loop Over Items node paired with Wait if several videos are processed in a batch within the same execution, to stay under the API's rate limits.

Step 3 — Convert the transcript into an SRT file

This is the most specific step of this pipeline: a Code node turns the segments array into text formatted as SRT, which requires precise syntax (sequence number, HH:MM:SS,mmm --> HH:MM:SS,mmm timestamp, text, blank line). An example function for this node:

function formatTimestamp(seconds) {
  const h = Math.floor(seconds / 3600);
  const m = Math.floor((seconds % 3600) / 60);
  const s = Math.floor(seconds % 60);
  const ms = Math.round((seconds - Math.floor(seconds)) * 1000);
  const pad = (n, len = 2) => String(n).padStart(len, "0");
  return `${pad(h)}:${pad(m)}:${pad(s)},${pad(ms, 3)}`;
}

const segments = $input.first().json.segments;
const srt = segments
  .map((seg, i) => {
    const start = formatTimestamp(seg.start);
    const end = formatTimestamp(seg.end);
    return `${i + 1}\n${start} --> ${end}\n${seg.text.trim()}\n`;
  })
  .join("\n");

return [{ json: { srt } }];

For a VTT file (used by native HTML5 players instead of SRT), the logic is identical with one detail changed: milliseconds are separated by a period instead of a comma, and the file starts with a WEBVTT header. A Convert to File node then turns this string into a binary .srt or .vtt file, ready to upload.

Step 4 (optional) — Multilingual subtitles

For an international audience, insert a Basic LLM Chain before the SRT conversion step to translate the text field of each segment while preserving its structure — the same approach described in our guide on automatic content translation. The point specific to subtitles: explicitly instruct the model to preserve the relative length of the translated text, otherwise a translation longer than the original exceeds the display time allotted to that segment and becomes unreadable on screen.

Step 5 — Publish or archive the file

Depending on the destination:

  • YouTube (your own channel): the YouTube Data API v3 accepts direct upload of a subtitle track via captions.insert, described in our guide on transcribing YouTube videos (a method reserved for videos you own).
  • Website or e-learning platform: a simple S3 or Google Drive upload alongside the video file, following the naming convention expected by the video player (often video-name.srt in the same folder). Our guide on automatic archiving with S3 covers structuring such a repository.
  • Burned-in subtitles: on a self-hosted instance, ffmpeg via Execute Command can re-encode the video with the subtitles=file.srt filter, useful for social platforms that don't accept a separate track.

What it actually costs

Whisper transcription through the OpenAI API is billed per minute of audio, at roughly $0.006/minute. A 15-minute video therefore costs less than $0.10 to transcribe, translation aside (the cost of a standard LLM call, generally lower than the transcription cost itself for text of that length). For a team producing ten videos a week, the monthly bill stays under a few dollars — well below the price of a dedicated captioning tool subscription.

Common pitfalls

  • Sending the full video file instead of the extracted audio: past the 25 MB limit, the call simply fails; extracting the audio upstream solves this for the vast majority of videos.
  • Forgetting verbose_json: without this setting, the response only contains continuous text, without the timestamps needed for a synchronized subtitle file.
  • Poorly handled long silences: Whisper naturally segments around pauses, but a video with long silences (title screen, transition) can produce an empty or poorly aligned segment; a quick visual check on the first few processed videos helps calibrate expectations.
  • Translation that lengthens the text: as mentioned above, without a conciseness instruction, a German or Spanish translation can significantly exceed the length of the source segment.

What research says about the value of subtitles

Beyond accessibility for deaf and hard-of-hearing viewers, a 2015 review by Gernsbacher published in Policy Insights from the Behavioral and Brain Sciences (see on Google Scholar) shows that captions improve comprehension and retention of video content for all viewers, not just a hard-of-hearing audience — a strong argument for making them standard on training or product-demo content. On the technical side, the Whisper model itself is documented in Radford et al.'s (2022) paper, Robust Speech Recognition via Large-Scale Weak Supervision (see on Google Scholar), which details the multilingual training data behind its robustness even on middling-quality audio.

Going further

This pipeline — timestamped transcription, SRT formatting, optional translation — relies on the same AI building blocks (OpenAI node, Basic LLM Chain) covered in our guide to connecting OpenAI to n8n. If your organization already combines content production, AI email triage, and a searchable internal knowledge base, the Complete FlowKit Bundle (€269 instead of €347) brings together the Inbox AI Pack (€79), the RAG Assistant Pack (€119), and the Compliance & Audit Pack (€149) — three building blocks that complement this captioning pipeline, for a coherent end-to-end AI automation stack.

FAQ

Frequently asked questions

Can n8n's OpenAI node generate an SRT file directly?

Not natively. The OpenAI node in transcription mode returns either plain text or a structured JSON object (with the verbose_json option) containing segments and their timestamps. Formatting into SRT or VTT — with the exact numbering and millisecond-comma syntax — happens afterward in a Code node, built from those segments.

Does Whisper work for videos that aren't in English or French?

Yes. Whisper (whisper-1 and the newer models offered through the OpenAI API) natively recognizes dozens of languages and automatically detects the spoken language if it isn't specified. Quality is still better on the languages best represented in the training data — English and French among them.

What's the maximum audio file size accepted?

OpenAI's transcription API caps out at 25 MB per file. For a longer video, either extract just the audio track (far lighter than the full video file) via ffmpeg, or split the audio into several segments transcribed separately and then stitched back together while accounting for each segment's time offset.

Can subtitles be burned directly into the video instead of producing a separate file?

n8n can drive that step by calling ffmpeg through an Execute Command node on a self-hosted instance, passing the generated SRT file into a subtitles filter. That's a heavier operation (full video re-encoding), reserved for cases where the target platform doesn't accept a separate subtitle track.

Bundle FlowKit Complet

€269