Я сделал скрипт .bat для водяных знаков видео с логотипом, медленно скользящим по видео справа налево. Вот мой код:
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
Проблема в том, что я получаю сообщение об ошибке на видео с восклицательными знаками: Нет такого файла или каталога.
Я читал, что включение отложенного расширения удаляет восклицательный знак, но мне это нужно для правильной работы скрипта. Как я могу это исправить?
Неудачное решение, которое я пробовал, приведено ниже:
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
for
%%A
, когда включено отложенное расширение, поэтому любые!
потребляются отложенным расширением; чтобы решить эту проблему, вам нужно отключить отложенное расширение до того, как наступит циклfor %%A in …
, а затем в теле цикла сначала установить несколько переменных (например,set "FILE=%%~A" & set "NAME=%%~nA"
), затем включить отложенное расширение, а затем использовать эти переменные (поэтому используйте!FILE!
вместо%%A
и!NAME!
вместо%%~nA
) и, наконец, поставитьendlocal
последней командой в теле цикла… - person aschipfl   schedule 08.10.2020set /A videoDuration=%%G/1
действительно интересна. В результате SET выводит сообщение об ошибке для обработки STDERR для значения с плавающей запятой, например,20.43
назначается переменной циклаG
, а затем определяется переменная средыvideoDuration
со значением20
. . Эта командная строка с арифметическим выражением вообще не понадобится при использованииfor /F "delims=. " %%G in ...
. - person Mofi   schedule 08.10.2020pause 10
и простоpause
? Командаpause
не поддерживает аргумент, отличный от/?
, что приводит к печати небольшой справки для этой простой команды.timeout
может лучше подойти для вашей задачи. Запуститеtimeout /?
для справки по этой команде, доступной по умолчанию, начиная с Windows Vista, которая является внешней командой, т.е. представляет собой исполняемый файл с полным именем файла%SystemRoot%\System32\timeout.exe
. - person Mofi   schedule 08.10.2020if !videoHeight! LSS !videoWidth! (echo "_ videoHeight LESS THAN videoWidth _") else echo "_ videoHeight GREATER THAN videoWidth _"
Что произойдет, если они оба одинаковы? Вы не учли этот сценарий, поэтому он будет рассматриваться какGREATER THAN
. Если это то, что вы намеревались, измените компаратор/порядок по мере необходимости. - person Compo   schedule 08.10.2020set /A scaleWidth = !videoWidth!/10
, а вместо этого используйтеset /A scaleWidth=videoWidth/10
, который лучше и всегда работает даже наvideoWidth
, который вообще не определен. Переменные среды могут быть указаны внутри арифметического выражения только их именами. Нет необходимости в%VariableName%
или!VariableName!
внутри арифметического выражения, которое является строкой послеset /A
. Это объясняется выводом команды SET при запускеset /?
в окне командной строки. - person Mofi   schedule 08.10.2020echo
ed120
символы подчеркивания, (ширина символа окна cmd.exe по умолчанию). Однако вы также включили заключающие двойные кавычки, что означает, что те строки, которые в любом случае не нужны, будут переноситься и выглядеть плохо. Поэтому вы должны удалить по крайней мере два из них в каждом экземпляре. - person Compo   schedule 08.10.2020echo _ Filename _: !FILE!
во втором коде не работает, так как отложенное расширение не включено дляcmd.exe
обработки этой командной строки. Вы должны использовать здесьecho _ Filename _: %%~A
. Вы знаете, что командаecho
выводит также все"
? Вы действительно хотите вывести все эти"
в начале и конце несколькихecho
строк аргументов? Кстати: я рекомендую назвать один видеофайл;Development & Test !File!.mp4
и посмотреть, сможет ли окончательный пакетный файл правильно обработать этот видеофайл с очень необычным именем. - person Mofi   schedule 08.10.2020"!FILE!"
вместо только!FILE!
, и вам лучше использовать в начале такжеset "FILE=%%~A"
иset "NAME=%%~nA"
. По причинам см. проблемы в этом длинном ответе и примите во внимание, что для каждой командной строки заключенный в'
командной строкиfor /F
, еще один командный процесс запускается с%ComSpec% /c
в фоновом режиме с полностью развернутой и обработанной командной строкой, добавленной в качестве дополнительных аргументов для запуска фономcmd
. - person Mofi   schedule 08.10.2020