Add Watermarks to Video in n8n Automatically

March 6, 2026 · RenderIO

Brand every video without opening an editor

You produce 20 videos a week. Each one needs your logo in the corner. Opening Premiere Pro or DaVinci Resolve for a 5-second watermark operation is a waste of time.

An n8n workflow does it automatically. New video uploaded? Logo applied. Batch of videos from a shoot? All watermarked. Client delivery folder? Every file branded.

This guide focuses on the n8n workflow side. If you want the full breakdown of FFmpeg watermark filters — positioning, scale2ref, opacity, text overlays, animated watermarks, and subtitle burn-in — see the FFmpeg watermark guide.

Use the RenderIO n8n node

The quickest way to add watermarks in n8n is RenderIO's partner-verified community node. Install from Settings → Community Nodes → search "renderio". It provides a visual interface for FFmpeg commands without HTTP Request configuration.

The watermark examples below use HTTP Request nodes for full flexibility, but the same FFmpeg overlay commands work with the native node.

The FFmpeg watermark command

FFmpeg's overlay filter places one video (or image) on top of another. Here's the basic command:

-i {video} -i {logo} -filter_complex "overlay=W-w-10:H-h-10" {output}
  • W = main video width

  • w = logo width

  • H = main video height

  • h = logo height

  • -10 = 10 pixel padding from the edge

This places the logo in the bottom-right corner with 10px padding.

Position reference

PositionFFmpeg overlay value
Top-leftoverlay=10:10
Top-rightoverlay=W-w-10:10
Bottom-leftoverlay=10:H-h-10
Bottom-rightoverlay=W-w-10:H-h-10
Centeroverlay=(W-w)/2:(H-h)/2

Basic workflow: Watermark a single video

Node 1: Trigger

Webhook, Google Drive trigger, or any trigger that provides:

  • videoUrl: URL of the video to watermark

  • logoUrl: URL of the logo/watermark image (PNG with transparency)

Node 2: Submit watermark command (HTTP Request)

  • Method: POST

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

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

  • Body:

{
  "ffmpeg_command": "-i {{in_video}} -i {{logo}} -filter_complex \"overlay=W-w-10:H-h-10\" -c:v libx264 -crf 22 -c:a copy {{out_output}}",
  "input_files": {
    "in_video": "{{ $json.videoUrl }}",
    "logo": "{{ $json.logoUrl }}"
  },
  "output_files": {
    "out_output": "watermarked.mp4"
  }
}

Node 3-5: Standard polling loop

Wait → Check Status → IF Complete → use result.

The output video has your logo permanently embedded in the bottom-right corner.

Semi-transparent watermark

A fully opaque logo can be distracting. Reduce opacity to 30%:

{
  "ffmpeg_command": "-i {{in_video}} -i {{logo}} -filter_complex \"[1:v]format=rgba,colorchannelmixer=aa=0.3[wm];[0:v][wm]overlay=W-w-10:H-h-10\" -c:v libx264 -crf 22 -c:a copy {{out_output}}",
  "input_files": {
    "in_video": "{{ $json.videoUrl }}",
    "logo": "{{ $json.logoUrl }}"
  },
  "output_files": {
    "out_output": "watermarked.mp4"
  }
}

colorchannelmixer=aa=0.3 sets the alpha channel to 30%. The logo is visible but not overpowering.

Resized watermark

If your logo is too large or too small for the video, scale it first:

{
  "ffmpeg_command": "-i {{in_video}} -i {{logo}} -filter_complex \"[1:v]scale=150:-1[wm];[0:v][wm]overlay=W-w-10:H-h-10\" -c:v libx264 -crf 22 -c:a copy {{out_output}}",
  "input_files": {
    "in_video": "{{ $json.videoUrl }}",
    "logo": "{{ $json.logoUrl }}"
  },
  "output_files": {
    "out_output": "watermarked.mp4"
  }
}

scale=150:-1 resizes the logo to 150px wide, maintaining aspect ratio.

Combine scaling with transparency:

{
  "ffmpeg_command": "-i {{in_video}} -i {{logo}} -filter_complex \"[1:v]scale=150:-1,format=rgba,colorchannelmixer=aa=0.3[wm];[0:v][wm]overlay=W-w-20:H-h-20\" -c:v libx264 -crf 22 -c:a copy {{out_output}}",
  "input_files": {
    "in_video": "{{ $json.videoUrl }}",
    "logo": "{{ $json.logoUrl }}"
  },
  "output_files": {
    "out_output": "watermarked.mp4"
  }
}

Dynamic positioning with n8n

Let users choose watermark position through your trigger:

Code node to map position to FFmpeg values:

const positions = {
  "top-left": "10:10",
  "top-right": "W-w-10:10",
  "bottom-left": "10:H-h-10",
  "bottom-right": "W-w-10:H-h-10",
  "center": "(W-w)/2:(H-h)/2"
};

const pos = positions[$input.first().json.position] || positions["bottom-right"];

return [{
  json: {
    ...$input.first().json,
    overlayPosition: pos
  }
}];

Then reference {{ $json.overlayPosition }} in your FFmpeg command.

Text watermark (no image needed)

If you don't have a logo image, use FFmpeg's drawtext filter:

{
  "ffmpeg_command": "-i {{in_video}} -vf \"drawtext=text='{{ $json.brandName }}':fontsize=24:fontcolor=white@0.5:x=w-tw-10:y=h-th-10\" -c:v libx264 -crf 22 -c:a copy {{out_output}}",
  "input_files": {
    "in_video": "{{ $json.videoUrl }}"
  },
  "output_files": {
    "out_output": "text-watermarked.mp4"
  }
}

fontcolor=white@0.5 makes the text white at 50% opacity. x=w-tw-10 positions it 10px from the right edge.

Batch watermarking

Process an entire folder of videos with the same watermark:

Step 1: Video list (from spreadsheet, database, or API)

const videos = $input.first().json.videos;  // Array of URLs
const logoUrl = "https://example.com/brand-logo.png";

return videos.map((url, i) => ({
  json: {
    videoUrl: url,
    logoUrl,
    outputName: `branded_${i + 1}.mp4`
  }
}));

Step 2: Split in Batches (size: 5)

Step 3: Submit watermark for each

{
  "ffmpeg_command": "-i {{in_video}} -i {{logo}} -filter_complex \"[1:v]scale=150:-1,format=rgba,colorchannelmixer=aa=0.3[wm];[0:v][wm]overlay=W-w-20:H-h-20\" -c:v libx264 -crf 22 -c:a copy {{out_output}}",
  "input_files": {
    "in_video": "{{ $json.videoUrl }}",
    "logo": "{{ $json.logoUrl }}"
  },
  "output_files": {
    "out_output": "{{ $json.outputName }}"
  }
}

Step 4: Poll and collect results

Timed watermark (appears/disappears)

Show the watermark only during the first 5 seconds:

{
  "ffmpeg_command": "-i {{in_video}} -i {{logo}} -filter_complex \"[1:v]format=rgba,colorchannelmixer=aa=0.3[wm];[0:v][wm]overlay=W-w-10:H-h-10:enable='between(t,0,5)'\" -c:v libx264 -crf 22 -c:a copy {{out_output}}",
  "input_files": {
    "in_video": "{{ $json.videoUrl }}",
    "logo": "{{ $json.logoUrl }}"
  },
  "output_files": {
    "out_output": "timed-watermark.mp4"
  }
}

enable='between(t,0,5)' shows the overlay from 0 to 5 seconds only.

Watermark with fade-in

Make the watermark fade in over the first 2 seconds:

{
  "ffmpeg_command": "-i {{in_video}} -i {{logo}} -filter_complex \"[1:v]format=rgba,fade=t=in:st=0:d=2:alpha=1,colorchannelmixer=aa=0.4[wm];[0:v][wm]overlay=W-w-10:H-h-10\" -c:v libx264 -crf 22 -c:a copy {{out_output}}",
  "input_files": {
    "in_video": "{{ $json.videoUrl }}",
    "logo": "{{ $json.logoUrl }}"
  },
  "output_files": {
    "out_output": "fade-watermark.mp4"
  }
}

Best practices for watermark images

  • Use PNG with transparency: JPG doesn't support transparency. Your logo needs an alpha channel.

  • Size appropriately: Logo should be 10-15% of the video width. For 1080p, that's 108-162px wide.

  • White or light colors: Works on most video content. Add a slight drop shadow in your PNG for videos with bright scenes.

  • Host on a reliable URL: The logo URL must be accessible when the API downloads it. Use S3, Cloudflare R2, or any CDN.

Get started

The Starter plan at $9/mo includes 500 commands -- enough to test watermarking workflows.