水印不适用于带有感叹号的视频

Watermark Not Working For Videos With Exclamation Marks

我制作了一个 .bat 脚本来为视频添加水印,其中的徽标从右到左在视频中缓慢滑动。这是我的代码:

set ffmpeg="C:\ffmpeg\ffmpeg.exe"
set ffprobe="C:\ffmpeg\ffprobe.exe"

@echo off
setlocal enableextensions enabledelayedexpansion
for %%A in ("H: - 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: - 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: - 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: - 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: - 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: - Watermark Process\After\!NAME!.mp4"
    )
    endlocal
)

pause 10

根据您提供的信息,这是一个未经测试的示例:

@Echo Off
SetLocal EnableExtensions DisableDelayedExpansion

Set "Source=H: - 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

你应该只需要修改孤立的Set组中的变量值。 请注意,我对 .png 文件使用了 %CD%,因为您没有提供位置。但是,由于您也没有设置当前目录,因此您实际上可能将这些文件与 运行 脚本放在同一目录中。如果是这种情况,您真的应该将两者都从 %CD% 更改为 %~dp0.