【问题标题】:ffmpeg and ffprobe Nested DelayedExpansion Variableffmpeg 和 ffprobe 嵌套延迟扩展变量
【发布时间】:2021-02-02 01:05:55
【问题描述】:

我正在尝试在我的脚本中获取“已处理的文件数”,但无法获得任何仅总数“已找到”的内容,并且还禁用 ffmpeg 以仅执行与清单或文件检查相同的预扫描使用特定的编解码器。

问题似乎出在嵌套的禁用延迟扩展上,但我在过去 3 个月中一直在学习批处理,并且每天搜索和比较/测试脚本数周,但我似乎无法突破这一点。

和/或使用 Dbenham 的 Return.bat 调用。但是我对 return.bat 犹豫不决,因为仅仅累积一个计数器似乎需要很大的处理/时间开销。

脚本执行以下操作:

  1. 注释掉:记录功能进程,它为每次运行创建一个目录一个文件
  2. 设置目标根驱动器和文件夹:“SET drive=T:\4k.temp”
  3. 设置 \bin 目录和初始变量:FilesFound=0
  4. 运行 for 循环以查找所有 mkv 和 mp4 文件
  5. 内部循环:增加变量 FilesFound+=1 并设置路径和文件名
  6. 嵌套 for 循环分析每个文件的属性以匹配“codec_name”与顶部“Codec1=dts”附近设置的变量。如果匹配,则设置 SkipCodec=1

    设置 EnableDelayedExpansion
  7. 对于每个文件,如果它的 SkipCodec 匹配为 1,它将(需要在 DisableDelayedExpansion 下嵌套 mkdir)创建一个与其当前文件夹树匹配的目录,但在目标根目录上,设置在顶部。

    (调用 :EncoderCounts - 测试/尝试了解如何用户调用函数将变量“携带”到“最终结果”部分)
  8. 处理 FFMpeg 命令或设置 FilesEncoded 计数器

    本地化
  9. Echo 的变量结果

有人能帮我突破这个障碍吗?

setlocal
rem #######1-Destination Drive #############
SET drive=T:\4k.temp
    setlocal EnableExtensions EnableDelayedExpansion
    SET "Codec1=dts"
    SET "FINALCOMMAND="
    setlocal EnableExtensions DisableDelayedExpansion
        SET "ProgramFolder=C:\FFmpeg\bin"
        SET "ProbeOptions=-v quiet -select_streams a:0 -show_entries "stream^^=codec_name" -of json"
        SET "FilesFound=0" & SET "FilesEncoded=0" & SET "FullFileName=" & SET "output="
        
        for /F "delims=" %%I in ('dir *.mkv *.mp4 /A-D-H /B /S 2^>nul') do (
            @ECHO ================Next File: %%I =============
            SET "FullFileName=%%I" &    SET "output=%drive%%%~pI%%~nxI"
            SET /A FilesFound+=1 & SET "AudioCodec=" & SET "SkipCodecs="
            for /F "eol={ tokens=1,2 delims=,:[ ]{} " %%B in ('""%ProgramFolder%\ffprobe.exe" %ProbeOptions% "%%I""') do (
                if "%%~B" == "codec_name" (
                    if not defined AudioCodec (
                        SET "AudioCodec=%%~C"
                    )
                    if "%%~C" == "%Codec1%" (set "SkipCodecs=1"
                    )
                )
            )
            setlocal EnableExtensions EnableDelayedExpansion
                if !SkipCodecs! == 1 (
                    setlocal EnableExtensions DisableDelayedExpansion
                        MKDIR "%drive%%%~pI" 2>null
                    endlocal
                    SET "FINALCOMMAND=ffmpeg -n -hide_banner -loglevel quiet -stats -i "!FullFileName!" -map 0:v -map 0:a:0 -c:v copy -c:a:0 ac3 -b:a:0 640k "!output!""
                        !FINALCOMMAND!&SET /A FilesEncoded+=1
                    ECHO #####COMPLETE############
                ) else ( ECHO #####NOT PROCESSING ############)
                ECHO[
            endlocal
        )
    if %FilesFound% == 1 ( SET "PluralS=" ) else set "PluralS=s"

    @ECHO *********************************************************
    ECHO re-encoded %FilesEncoded% of %FilesFound% video file%PluralS%.
    endlocal
    GOTO :END
:END
endlocal
endlocal
exit /b

【问题讨论】:

  • 您能否考虑发布minimal reproducible example
  • 正如@Squashman 所说,您的示例太复杂了。但可能你不是在搜索return.bat,而是一个简单的FOR endlocal 技术就足够了,检查块,从for /f "delims=" %%p in ("!insert!%%~L!line!") do (开始
  • 谢谢 Jeb,我还在检查中
  • 谢谢 Jeb 你找到了!!一个小问题,似乎使用 CALL 使所有 ffmpeg 进程首先运行,然后显示大部分脚本的所有 ECHO,见这张图。 [换行符]Command Prompt of fixed script
  • @hsgg4,评论区不提供超出您原始问题的额外支持。如果您有新问题,请创建一个新的主题,使用您的代码 minimal reproducible example 提出问题,并提供足够的支持和调试信息以便我们为您提供帮助。

标签: windows batch-file cmd ffmpeg


【解决方案1】:

Jeb 的解决方案有效,这是工作副本:

SETlocal
SET drive=T:\4k.temp
SET string=%CD%
    SETlocal EnableDelayedExpansion
        for %%* in (.) do SET LogFolder=%%~n*
        MD "%drive%\Logs\%LogFolder%"
        SET "LOGFILE=%drive%\Logs\%LogFolder%\Log.log"
    endlocal & SET LOGFILE=%LOGFILE%
        SETlocal EnableExtensions EnableDelayedExpansion
        (call ^:logit)>>"%LOGFILE%"
        :logit
        SET "FINALCOMMAND="
        SET "Codec1=dts"
            SETlocal EnableExtensions DisableDelayedExpansion
                SET "ProgramFolder=C:\Program Files\FFmpeg-v2020\bin"
                SET "ProbeOptions=-v quiet -select_streams a:0 -show_entries "stream^^=codec_name" -of json"
                SET "FilesFound=0" & SET "FilesEncoded=0" & SET "output="
                for /F "delims=" %%I in ('dir *.mkv *.mp4 /A-D-H /B /S 2^>nul') do (
                    @ECHO ================Next File: %%I ========================
                    SET "output=%drive%%%~pI%%~nxI" & SET /A FilesFound+=1 & SET "AudioCodec=" & SET "SkipCodecs="
                    for /F "eol={ tokens=1,2 delims=,:[ ]{} " %%B in ('""%ProgramFolder%\ffprobe.exe" %ProbeOptions% "%%I""') do (
                        if "%%~B" == "codec_name" (
                            if not defined AudioCodec (
                                SET "AudioCodec=%%~C"
                            )
                            if "%%~C" == "%Codec1%" (SET "SkipCodecs=1" &ECHO   This is Codec1:         %Codec1%
                                )
                            )
                        )
                    )
                    SETlocal EnableExtensions EnableDelayedExpansion
                        if !SkipCodecs! == 1 (
                            SETlocal EnableExtensions DisableDelayedExpansion
                                MKDIR "%drive%%%~pI" 2>null
                            endlocal
                        )
                        if !SkipCodecs! == 1 (
                                ECHO    Processing ffmpeg x265 to make AC3 with:    "!Codec1!"
                            SET "FINALCOMMAND=ffmpeg -n -hide_banner -loglevel quiet -stats -i "%%I" -map 0:v -threads 6 -map 0:a:0 -map 0:s? -c:v copy -c:a copy -c:a:0 ac3 -b:a:0 640k "!output!""
                            !FINALCOMMAND!
                            ECHO #####COMPLETE################### &ECHO[ &ECHO[
                            if not %FilesEncoded% == 0 ECHO     This one was a failure. Count Encoded so far: "%FilesEncoded%"
                            
                            for /F "delims=" %%p in ("!SkipCodecs!") do (
                            ENDLOCAL
                                SET /A FilesEncoded=%%p+FilesEncoded
                            )
                        ) ELSE ( ECHO #####)
                )
                if %FilesFound% == 1 ( SET "PluralS=" ) else SET "PluralS=s"
                @ECHO ***************************************************************************************
                ECHO Re-encoded !FilesEncoded! of %FilesFound% video file%PluralS%.
            endlocal
        endlocal
endlocal
exit /b

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-21
    • 2018-03-06
    • 1970-01-01
    • 2021-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多