Add Watermark
Overlay images or text on video as watermarks.
Add Watermark
Adding a watermark to video is essential for branding, copyright protection, and content attribution. FFmpeg's overlay filter lets you position an image anywhere on the video frame with full control over placement and opacity.
Image watermark (bottom-right)
Overlay a logo image in the bottom-right corner with a 10-pixel margin from the edges.
ffmpeg -i {{in_video}} -i {{in_logo}} -filter_complex "overlay=W-w-10:H-h-10" {{out_video}}In the overlay expression:
WandHare the main video width and heightwandhare the overlay image width and heightW-w-10places the logo 10 pixels from the right edgeH-h-10places the logo 10 pixels from the bottom edge
Image watermark (top-left)
Place the logo in the top-left corner with a 10-pixel margin.
ffmpeg -i {{in_video}} -i {{in_logo}} -filter_complex "overlay=10:10" {{out_video}}Other common positions:
- Top-right:
overlay=W-w-10:10 - Bottom-left:
overlay=10:H-h-10 - Center:
overlay=(W-w)/2:(H-h)/2
Image watermark with opacity
Make the watermark semi-transparent by adjusting the alpha channel. The colorchannelmixer=aa=0.5 sets 50% opacity.
ffmpeg -i {{in_video}} -i {{in_logo}} -filter_complex "[1:v]format=rgba,colorchannelmixer=aa=0.5[logo];[0:v][logo]overlay=W-w-10:H-h-10" {{out_video}}This filter chain:
- Takes the second input (
[1:v], the logo) and converts it to RGBA format - Adjusts the alpha channel to 50% opacity
- Labels the result as
[logo] - Overlays
[logo]onto the main video ([0:v]) in the bottom-right corner
Full API example
Add a logo watermark to the bottom-right corner of a video. This example uses two input files: the source video and the logo image.
curl -X POST https://renderio.dev/api/v1/run-ffmpeg-command \
-H "Content-Type: application/json" \
-H "X-API-KEY: ffsk_your_api_key_here" \
-d '{
"input_files": {
"in_video": "https://example.com/source.mp4",
"in_logo": "https://example.com/logo.png"
},
"output_files": {
"out_video": "watermarked.mp4"
},
"ffmpeg_command": "ffmpeg -i {{in_video}} -i {{in_logo}} -filter_complex \"overlay=W-w-10:H-h-10\" -c:a copy {{out_video}}"
}'import requests
response = requests.post(
"https://renderio.dev/api/v1/run-ffmpeg-command",
headers={
"Content-Type": "application/json",
"X-API-KEY": "ffsk_your_api_key_here",
},
json={
"input_files": {
"in_video": "https://example.com/source.mp4",
"in_logo": "https://example.com/logo.png",
},
"output_files": {
"out_video": "watermarked.mp4",
},
"ffmpeg_command": 'ffmpeg -i {{in_video}} -i {{in_logo}} -filter_complex "overlay=W-w-10:H-h-10" -c:a copy {{out_video}}',
},
)
data = response.json()
print("Command ID:", data["command_id"])interface RunCommandResponse {
command_id: string;
}
const response = await fetch("https://renderio.dev/api/v1/run-ffmpeg-command", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-KEY": "ffsk_your_api_key_here",
},
body: JSON.stringify({
input_files: {
in_video: "https://example.com/source.mp4",
in_logo: "https://example.com/logo.png",
},
output_files: {
out_video: "watermarked.mp4",
},
ffmpeg_command:
'ffmpeg -i {{in_video}} -i {{in_logo}} -filter_complex "overlay=W-w-10:H-h-10" -c:a copy {{out_video}}',
}),
});
const { command_id } = (await response.json()) as RunCommandResponse;
console.log("Command ID:", command_id);const response = await fetch("https://renderio.dev/api/v1/run-ffmpeg-command", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-KEY": "ffsk_your_api_key_here",
},
body: JSON.stringify({
input_files: {
in_video: "https://example.com/source.mp4",
in_logo: "https://example.com/logo.png",
},
output_files: {
out_video: "watermarked.mp4",
},
ffmpeg_command:
'ffmpeg -i {{in_video}} -i {{in_logo}} -filter_complex "overlay=W-w-10:H-h-10" -c:a copy {{out_video}}',
}),
});
const { command_id } = await response.json();
console.log("Command ID:", command_id);<?php
$ch = curl_init("https://renderio.dev/api/v1/run-ffmpeg-command");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Content-Type: application/json",
"X-API-KEY: ffsk_your_api_key_here",
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
"input_files" => [
"in_video" => "https://example.com/source.mp4",
"in_logo" => "https://example.com/logo.png",
],
"output_files" => [
"out_video" => "watermarked.mp4",
],
"ffmpeg_command" => 'ffmpeg -i {{in_video}} -i {{in_logo}} -filter_complex "overlay=W-w-10:H-h-10" -c:a copy {{out_video}}',
]));
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
echo "Command ID: " . $data["command_id"] . "\n";Notice that input_files contains two entries: in_video for the source video and in_logo for the watermark image. Both are referenced in the ffmpeg_command using {{in_video}} and {{in_logo}} placeholders.
The API returns a command_id immediately. Poll GET /api/v1/commands/:commandId to check when the watermarking is complete, then download the output from the storage_url in the response.
Tips and variations
-c:a copy: Adding-c:a copycopies the audio stream without re-encoding, which is faster and preserves the original audio quality.- Logo sizing: Resize the logo within the filter chain before overlaying:
[1:v]scale=100:-1[logo];[0:v][logo]overlay=W-w-10:H-h-10. This scales the logo to 100 pixels wide with automatic height. - PNG with transparency: Use PNG format for your logo to take advantage of built-in alpha transparency. The overlay filter respects PNG alpha channels automatically.
- Tiled watermark: Repeat a watermark across the entire frame for stronger protection. Use the
overlayfilter with theshortest=1flag and a tiled input generated with thetilefilter. - Time-limited watermark: Show the watermark only during a specific time range by adding
enable='between(t,5,30)'to the overlay filter, which shows it from 5 to 30 seconds.
Related guides
- Chained Workflow -- combine resizing and watermarking in a multi-step pipeline
- Compress Video -- reduce file size after adding your watermark
Further reading
- FFmpeg Commands List with API Examples -- watermark commands with matching API calls
- FFmpeg REST API Tutorial -- step-by-step guide to calling the API from Python, Node.js, and curl