I made a .bat script to watermark videos with the logo slowly sliding across the video from the right to the left. Here is my code:
set ffmpeg="C:\ffmpeg\ffmpeg.exe"
set ffprobe="C:\ffmpeg\ffprobe.exe"
@echo off
setlocal enableextensions enabledelayedexpansion
for %%A in ("H:\4 - Watermark Process\Before\*.mp4") do (
echo "________________________________________________________________________________________________________________________"
echo _ Filename _: %%A
rem Find videoDuration
for /F "delims=" %%G in ('ffprobe.exe -v error -show_entries format^=duration -of default^=noprint_wrappers^=1:nokey^=1 "%%A" 2^>^&1') do (
set /A videoDuration=%%G/1
echo _ Video Duration _: !videoDuration!
)
rem Find videoWidth
for /F "delims=" %%I in ('ffprobe -v error -show_entries stream^=width -of csv^=p^=0:s^=x "%%A"') do (
set videoWidth=%%I
echo _ Video Width _: !videoWidth!
)
rem Find videoHeight
for /F "delims=" %%J in ('ffprobe -v error -show_entries stream^=height -of csv^=s^=x:p^=0 "%%A"') do (
set videoHeight=%%J
echo _ Video Height _: !videoHeight!
)
rem Scale logo watermark according to video Width and Height
if !videoHeight! LSS !videoWidth! (
echo "_ videoHeight LESS THAN videoWidth _"
set /A scaleWidth = !videoWidth!/10
ffmpeg -i logo.png -y -v verbose -vf scale=!scaleWidth!:-1 scaled.png
) else (
echo "_ videoHeight GREATER THAN videoWidth _"
set /A scaleWidth = !videoWidth!/4
ffmpeg -i logo.png -y -v verbose -vf scale=!scaleWidth!:-1 scaled.png
)
rem Place logo watermark based on video Duration
if !videoDuration! LSS 10 (
echo "_ videoDuration LESS THAN 10 seconds _"
echo "________________________________________________________________________________________________________________________"
ffmpeg -i "%%A" -i scaled.png -filter_complex "overlay=10:main_h-overlay_h" "H:\4 - Watermark Process\After\%%~nA.mp4"
echo "______________________________________________LESS THAN 10SEC CONVERSION COMPLETE__________________________________________________________________________"
)
if !videoDuration! GEQ 10 (
set /A "videoDurationOneThird=(videoDuration*2)/3"
echo _ videoDuration One Third _: !videoDurationOneThird!
echo "________________________________________________________________________________________________________________________"
ffmpeg -i "%%A" -i scaled.png -filter_complex "[0:v][1:v] overlay='if(gte(t,!videoDurationOneThird!), (main_w-(w+(t-!videoDurationOneThird!)*20)), NAN)':(main_h-overlay_h)/2:enable=between'(t,!videoDurationOneThird!,!videoDuration!)'" "H:\4 - Watermark Process\After\%%~nA.mp4"
)
)
pause 10
Problem is I get a an error on videos with exclamation points in them saying: No such file or directory
I read that enabling delayed expansion removes the exclamation point but I need it for the script to work correctly. How can I fix this?
The failed solution I've tried is below:
set ffmpeg="C:\ffmpeg\ffmpeg.exe"
set ffprobe="C:\ffmpeg\ffprobe.exe"
@echo off
setlocal enableextensions disabledelayedexpansion
for %%A in ("H:\4 - Watermark Process\BeforeWide\*.mp4") do (
set FILE=%%~A
set NAME=%%~nA
echo "________________________________________________________________________________________________________________________"
echo _ Filename _: !FILE!
setlocal enabledelayedexpansion
rem Find videoDuration
for /F "delims=" %%G in ('ffprobe.exe -v error -show_entries format^=duration -of default^=noprint_wrappers^=1:nokey^=1 !FILE! 2^>^&1') do (
set /A videoDuration=%%G/1
echo _ Video Duration _: !videoDuration!
)
rem Find videoWidth
for /F "delims=" %%I in ('ffprobe -v error -show_entries stream^=width -of csv^=p^=0:s^=x !FILE!') do (
set videoWidth=%%I
echo _ Video Width _: !videoWidth!
)
rem Find videoHeight
for /F "delims=" %%J in ('ffprobe -v error -show_entries stream^=height -of csv^=s^=x:p^=0 !FILE!') do (
set videoHeight=%%J
echo _ Video Height _: !videoHeight!
)
rem Scale logo watermark according to video Width and Height
if !videoHeight! LSS !videoWidth! (
echo "_ videoHeight LESS THAN videoWidth _"
set /A scaleWidth = !videoWidth!/10
ffmpeg -i logo.png -y -v verbose -vf scale=!scaleWidth!:-1 scaled.png
) else (
echo "_ videoHeight GREATER THAN videoWidth _"
set /A scaleWidth = !videoWidth!/4
ffmpeg -i logo.png -y -v verbose -vf scale=!scaleWidth!:-1 scaled.png
)
rem Place logo watermark based on video Duration
if !videoDuration! LSS 10 (
echo "_ videoDuration LESS THAN 10 seconds _"
echo "________________________________________________________________________________________________________________________"
ffmpeg -i !FILE! -i scaled.png -filter_complex "overlay=10:main_h-overlay_h" "H:\4 - Watermark Process\After\!NAME!.mp4"
echo "______________________________________________LESS THAN 10SEC CONVERSION COMPLETE__________________________________________________________________________"
)
if !videoDuration! GEQ 10 (
set /A "videoDurationOneThird=(videoDuration*2)/3"
echo _ videoDuration One Third _: !videoDurationOneThird!
echo "________________________________________________________________________________________________________________________"
ffmpeg -i !FILE! -i scaled.png -filter_complex "[0:v][1:v] overlay='if(gte(t,!videoDurationOneThird!), (main_w-(w+(t-!videoDurationOneThird!)*20)), NAN)':(main_h-overlay_h)/2:enable=between'(t,!videoDurationOneThird!,!videoDuration!)'" "H:\4 - Watermark Process\After\!NAME!.mp4"
)
endlocal
)
pause 10
Here's an untested example for you, based upon the information you provided:
@Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
Set "Source=H:\4 - Watermark Process"
Set "Before=BeforeWide"
Set "After=After"
Set "Glob=*.mp4"
Set "ffmpeg=C:\ffmpeg\ffmpeg.exe"
Set "ffprobe=C:\ffmpeg\ffprobe.exe"
Set "logo=%CD%\logo.png"
Set "scaled=%CD%\scaled.png"
For %%A In ("%Source%\%Before%\%Glob%") Do (
Set "FullName=%%A"
Set "NameOnly=%%~nxA"
If Not Exist "%Source%\%After%\" MD "%Source%\%After%" || GoTo :EOF 2> NUL
SetLocal EnableDelayedExpansion
Echo ________________________________________________________________________________________________________________________
Echo _ Filename _: !FullName!
Set /A "videoDuration=videoWidth=videoHeight=0"
Rem Find videoDuration
For /F Delims^=^ EOL^= %%G In (
'^""%ffprobe%" -v error -show_entries format^=duration -of default^=noprint_wrappers^=1:nokey^=1 "!FullName!" 2^>^&1^"'
) Do Set /A "videoDuration=%%G / 1" 2> NUL
Echo _ Video Duration _: !videoDuration!
Rem Find videoWidth
For /F Delims^=^ EOL^= %%I In (
'^""%ffprobe%" -v error -show_entries stream^=width -of csv^=p^=0:s^=x "!FullName!"^"'
) Do Set /A "videoWidth=%%I" 2> NUL
Echo _ Video Width _: !videoWidth!
Rem Find videoHeight
For /F Delims^=^ EOL^= %%J In (
'^""%ffprobe%" -v error -show_entries stream^=height -of csv^=s^=x:p^=0 "!FullName!"^"'
) Do Set /A "videoHeight=%%J" 2> NUL
Echo _ Video Height _: !videoHeight!
Rem Scale logo watermark according to video Width and Height
If !videoHeight! Lss !videoWidth! (
Echo _ videoHeight LESS THAN videoWidth _
Set /A "scaleWidth=videoWidth / 10"
) Else (
Echo _ videoHeight GREATER THAN videoWidth _
Set /A "scaleWidth=videoWidth / 4"
)
"%ffmpeg%" -i "%logo%" -y -v verbose -vf scale=!scaleWidth!:-1 "%scaled%"
Rem Place logo watermark based on video Duration
If !videoDuration! Lss 10 (
Echo _ videoDuration LESS THAN 10 seconds _
Echo ________________________________________________________________________________________________________________________
"%ffmpeg%" -i "!FullName!" -i "%scaled%" -filter_complex "overlay=10:main_h-overlay_h" "%Source%\%After%\!NameOnly!"
Echo __________________________________________LESS THAN 10SEC CONVERSION COMPLETE___________________________________________
)
If !videoDuration! GEq 10 (
Set /A "videoDurationOneThird = (videoDuration * 2) / 3"
Echo _ videoDuration One Third _: !videoDurationOneThird!
Echo ________________________________________________________________________________________________________________________
"%ffmpeg%" -i "!FullName!" -i "%scaled%" -filter_complex "[0:v][1:v] overlay='if(gte(t,!videoDurationOneThird!), (main_w-(w+(t-!videoDurationOneThird!)*20)), NAN)':(main_h-overlay_h)/2:enable=between'(t,!videoDurationOneThird!,!videoDuration!)'" "%Source%\%After%\!NameOnly!"
)
EndLocal
)
%SystemRoot%\System32\timeout.exe /T 10 /NoBreak 1> NUL
You should only need to modify the variable values, in the isolated Set
group. Please note that I've used %CD%
for the .png
files, as you hadn't provided a location. However, as you've not set the current directory either, you may actually have those files in the same directory as the running script. If that is the case you should really change both from %CD%
to %~dp0
.