Convert Video Formats in n8n with RenderIO

February 19, 2026 · RenderIO

Video format conversion is the most common workflow

You have MOV files from iPhone recordings. Your web app needs MP4. Your CDN wants WebM. Your podcast tool needs MP3 audio extracted from video interviews.

Format conversion is the bread and butter of video processing. And n8n can handle it with a single HTTP Request node pointed at the right API.

The problem with video formats

Different devices and platforms produce different formats:

  • iPhone/Mac: MOV (ProRes or HEVC)

  • Android: MP4 (H.264 or H.265)

  • Screen recorders: MKV or WEBM

  • Cameras: MOV, MXF, or AVCHD

  • Downloads: AVI, FLV, WMV, or anything

Your application probably wants MP4 (H.264 + AAC). It's the most compatible format. Every browser, device, and platform supports it.

Converting between formats requires FFmpeg. n8n can't run FFmpeg. But n8n can call an API that runs FFmpeg. (If you're wondering why n8n Cloud blocks shell access and how the HTTP Request workaround works, the n8n FFmpeg cloud fix covers it.)

Option 1: Use the RenderIO n8n node

The fastest setup is RenderIO's partner-verified community node. Install it from Settings → Community Nodes → search "renderio". It provides a visual interface for FFmpeg commands, file management, and reusable presets without configuring HTTP Request nodes manually.

The node handles authentication, request formatting, and response parsing. Just select the "Run Command" operation, paste your FFmpeg command, and configure input/output files.

The workflows below use the HTTP Request approach for full flexibility, but every example works with the native node too — just use the same FFmpeg commands and file mappings.

Option 2: Base workflow structure (HTTP Request)

Every conversion workflow in n8n follows this pattern:

TriggerSubmit ConversionWaitCheck StatusIF CompleteUse Result

Here's the reusable core:

Submit Conversion (HTTP Request node)

  • Method: POST

  • URL: https://renderio.dev/api/v1/run-ffmpeg-command

  • Authentication: Header Auth (X-API-KEY: your_key)

  • Body: JSON (varies by conversion)

Check Status (HTTP Request node)

  • Method: GET

  • URL: https://renderio.dev/api/v1/commands/{{ $('Submit Conversion').item.json.command_id }}

  • Authentication: Header Auth

IF node

  • Condition: {{ $json.status }} equals completed

  • True: Continue

  • False: Loop back to Wait

Conversion recipes

MOV to MP4

The most common conversion. iPhone recordings to web-ready MP4.

{
  "ffmpeg_command": "-i {{in_video}} -c:v libx264 -preset fast -crf 22 -c:a aac -b:a 128k -movflags +faststart {{out_video}}",
  "input_files": { "in_video": "{{ $json.videoUrl }}" },
  "output_files": { "out_video": "converted.mp4" }
}

-movflags +faststart moves the metadata to the beginning of the file. This enables progressive playback in browsers (the video starts playing before fully downloaded).

MP4 to WebM

For web delivery. VP9 is 30-50% more efficient than H.264 at the same quality.

{
  "ffmpeg_command": "-i {{in_video}} -c:v libvpx-vp9 -crf 30 -b:v 0 -c:a libopus -b:a 128k {{out_video}}",
  "input_files": { "in_video": "{{ $json.videoUrl }}" },
  "output_files": { "out_video": "web-ready.webm" }
}

VP9 encoding is slower than H.264. A 5-minute video might take 8-12 minutes to encode. Plan your workflow timing accordingly.

MKV to MP4

MKV files often contain H.264 video and AAC audio already. If so, you can remux without re-encoding:

{
  "ffmpeg_command": "-i {{in_video}} -c:v copy -c:a copy {{out_video}}",
  "input_files": { "in_video": "{{ $json.videoUrl }}" },
  "output_files": { "out_video": "remuxed.mp4" }
}

This is nearly instant. If the codecs aren't compatible, fall back to re-encoding (the FFmpeg transcoding guide explains when you need to transcode vs remux):

{
  "ffmpeg_command": "-i {{in_video}} -c:v libx264 -crf 22 -c:a aac {{out_video}}",
  "input_files": { "in_video": "{{ $json.videoUrl }}" },
  "output_files": { "out_video": "converted.mp4" }
}

AVI to MP4

Old AVI files need full re-encoding:

{
  "ffmpeg_command": "-i {{in_video}} -c:v libx264 -preset medium -crf 23 -c:a aac -b:a 128k {{out_video}}",
  "input_files": { "in_video": "{{ $json.videoUrl }}" },
  "output_files": { "out_video": "modern.mp4" }
}

WMV to MP4

Windows Media files to universal MP4:

{
  "ffmpeg_command": "-i {{in_video}} -c:v libx264 -crf 23 -c:a aac -b:a 128k {{out_video}}",
  "input_files": { "in_video": "{{ $json.videoUrl }}" },
  "output_files": { "out_video": "converted.mp4" }
}

MP4 to GIF

Need animated GIFs from your videos? The key is palette optimization for decent quality:

{
  "ffmpeg_command": "-i {{in_video}} -t 5 -vf \"fps=10,scale=480:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse\" {{out_gif}}",
  "input_files": { "in_video": "{{ $json.videoUrl }}" },
  "output_files": { "out_gif": "preview.gif" }
}

This creates a 5-second, 480px-wide GIF with optimized colors. For the full breakdown of palette options, dithering methods, and when to use WebP instead, see the MP4 to GIF with FFmpeg guide.

GIF to MP4

Going the other direction — converting animated GIFs to browser-compatible MP4:

{
  "ffmpeg_command": "-i {{in_gif}} -movflags faststart -pix_fmt yuv420p -vf \"scale=trunc(iw/2)*2:trunc(ih/2)*2\" -c:v libx264 -crf 20 {{out_video}}",
  "input_files": { "in_gif": "{{ $json.gifUrl }}" },
  "output_files": { "out_video": "converted.mp4" }
}

The -pix_fmt yuv420p and even-dimension scale filter are required or the output won't play on most devices. The GIF to MP4 conversion guide covers codec choices, quality tuning, transparency handling, and batch processing.

MP4 to MP3 (extract audio)

Pull the audio track out of a video:

{
  "ffmpeg_command": "-i {{in_video}} -vn -acodec libmp3lame -q:a 2 {{out_audio}}",
  "input_files": { "in_video": "{{ $json.videoUrl }}" },
  "output_files": { "out_audio": "audio.mp3" }
}

Dynamic conversion based on input format

You can build a smart workflow that detects the input format and applies the right conversion. Use a Switch node after your trigger:

Switch node conditions based on file extension:

  • If {{ $json.videoUrl }} ends with .mov → MOV to MP4 conversion

  • If {{ $json.videoUrl }} ends with .mkv → MKV to MP4 (try copy first)

  • If {{ $json.videoUrl }} ends with .avi → AVI to MP4 conversion

  • Default → Generic to MP4 conversion

Each branch uses its own HTTP Request body optimized for that format.

Preserving quality

The CRF (Constant Rate Factor) value controls quality vs file size:

  • CRF 18: Visually lossless. Large files.

  • CRF 22: High quality. Good for archiving.

  • CRF 23: Default. Good balance.

  • CRF 28: Smaller files. Slight quality loss.

  • CRF 32: Small files. Noticeable quality loss.

For most conversions, CRF 22-23 is the right choice. If file size matters more than quality (email attachments, chat), use CRF 28.

Handling conversion errors

Common conversion failures and how to handle them in n8n:

Unsupported codec in source: The API returns a "failed" status with an FFmpeg error message. Add an error branch in your IF node that sends a notification.

Corrupted input file: FFmpeg can sometimes repair minor corruption. Add -err_detect ignore_err before the input:

{
  "ffmpeg_command": "-err_detect ignore_err -i {{in_video}} -c:v libx264 -crf 22 -c:a aac {{out_video}}",
  "input_files": { "in_video": "{{ $json.videoUrl }}" },
  "output_files": { "out_video": "repaired.mp4" }
}

Input URL not accessible: Validate the URL before submitting. Add an HTTP Request node with HEAD method to check accessibility.

Output naming with timestamps

Generate unique output filenames using n8n expressions:

{
  "output_files": {
    "out_video": "converted_{{ $now.format('yyyyMMdd_HHmmss') }}.mp4"
  }
}

This prevents filename collisions when processing multiple videos.

Get started

The Starter plan at $9/mo includes 500 commands -- enough to build and test your conversion workflow. Read the complete n8n video processing integration for more details.