7

I would like to scale a watermark to 5% of the video width.

I need something like that:

ffmpeg -i 1.mp4 -i logo.png -filter_complex "[1:v] scale=1_MP4_VIDEO_WIDTH*0.05:-1 [logo1]; [0:v][logo1] overlay=0:0" -y -b 1600k -c:v libx264 -profile high -level 4.1 -c:a libfaac -q:a 128k 2.mp4

How can I reference the video width?

Journeyman Geek
  • 127,463
  • 52
  • 260
  • 430
face
  • 143
  • 1
  • 1
  • 6

3 Answers3

11

This can now be performed directly using the scale2ref filter.

ffmpeg -i 1.mp4 -i logo.png \
-filter_complex "[1:v][0:v]scale2ref=iw*0.05:-1[logo1][base]; \
 [base][logo1]overlay=0:0[v]" \
-map [v] -map 0:a -y -b:v 1600k -c:v libx264 -profile high -level 4.1 \
-c:a libfaac -b:a 128k 2.mp4
Gyan
  • 34,439
  • 6
  • 56
  • 98
  • Hey, your command work and thanks, but it doesn't maintain the aspect ratio of watermark, it stretch it to the video size. How to fix it ? – Emad Ghasemi Jan 06 '17 at 14:06
  • @EmadGhasemi if u want aspect ratio. firstly you have to calculate watermark ratio(height/width). Then change this [1:v][0:v]scale2ref=iw*0.05:(iw*0.05)*watermark_ratio[logo1][base] –  Mar 30 '17 at 00:11
  • See my comment in this answer here: https://superuser.com/a/1100429/85904 You can now do this with one command – bhh1988 Oct 02 '17 at 01:16
  • 1
    I am getting 45 mb video which is previously 5 mb – Pratik Butani Sep 13 '19 at 09:31
  • @PratikButani that has been my issue. When I try to use the scale2ref it makes the file size much bigger. I don't know if that is a bug or it's not used correctly. Gyan any insight? – Panama Jack Aug 28 '22 at 08:26
  • Ask new Q with full command AND logs – Gyan Aug 28 '22 at 08:41
5

Assuming a linux environment (or cygwin on windows), the only way I found is to execute 2 commands.

First to get main video size and perform math on them (note: x/20 == x*0.05:

val=`ffmpeg.exe -i 1.mp4 2>&1 | grep Video: | sed 's_.*, \([0-9]*x[0-9]*\) .*_\1_' | awk 'BEGIN {FS="x"} {print int($1/20)"x"int($2/20)}'`

Second to scale and overlay the video

ffmpeg -i 1.mp4 -i logo.png -filter_complex "[1:v] scale=$val [logo1]; [0:v][logo1] overlay=0:0" -y -b 1600k -c:v libx264 -profile high -level 4.1 -c:a libfaac -q:a 128k 2.mp4

Also, you could just replace $val on second line with the first expression (including backquotes) and get the same result, but I find it a little easier to read splitting command in two.

NuTTyX
  • 2,628
  • 11
  • 15
1

As for Windows, I discovered following method using ffprobe and ffmpeg. Here is a .bat file code:

@echo off
   SetLocal EnableExtensions EnableDelayedExpansion

   for %%a in ("*.mp4") do (
      For /F "usebackq" %%I In (`ffprobe -v error -show_entries stream"="width -of default"="noprint_wrappers"="1:nokey"="1 "%%~a"`) Do (

      Set V=%%~I
      ffmpeg -i "%%a" -i logo.png -b:v 1M -filter_complex "[1:v]scale=(SCALE_FACTOR*!V!):-1 [wm]; [0:v][wm] overlay=x=(main_w-overlay_w):y=(main_h-overlay_h)" -y -v 2 "new\%%~na.mp4"
)

)

Here SLACE_FACTOR is overlay image width divided to some reference video file width (for ex., 320px/1280px).

F'K
  • 11
  • 1