批量编码,然后比较文件大小与原始大小并删除较大的文件

时间:2019-11-05 15:25:34

标签: windows batch-file cmd ffmpeg

当前正在运行批处理脚本以批量转换媒体剪辑,以节省一些存储空间。我还要在脚本中添加自动化功能,该脚本将在转换后删除最终会成为较大文件的脚本。不太确定如何在每次转换结束时最好地进行设置。

pushd "%2"

::Default variables
SET paths=paths.txt
::paths lets you put a bunch of folder paths in a text file and run this across those, instead of individually. I use this to run overnight on a LOT of footage folders at once. Thanks to Aayla for a lot of these upgrades
::Fun tip - select your folders (15 max at a time) and shift+right-click and click "copy as paths"
SET /A ffmpeg_qv=24
::change CQP value here so you only have to type it once. 22 is lossless for HEVC.

::for /R %%A in (*.mp4, *.avi, *.mov, *.wmv, *.ts, *.m2ts, *.mkv, *.mts) do (
::    echo Processing %%A
::    ffmpeg -hwaccel auto -i "%%A" -pix_fmt p010le -map 0:v -map 0:a -c:v hevc_nvenc -rc constqp -qp 21 -b:v 0K -c:a libfdk_aac -vbr 5 -movflags +faststart "%%A~dnpA_CRF%ffmpeg_qv%_HEVC.mp4"
::    echo Processed %%A
::)
::pause
::Test if the paths file exists and iterate through it
if EXIST %paths% (
    for /f "tokens=*" %%a in (%paths%) do (
        echo Changing to directory %%a
        pushd "%%a"
        CALL :ffmpeg
    )
) else (
    ::It doesn't exist
    CALL :ffmpeg
)
pause
EXIT /B %ERRORLEVEL%
::Don't run the function when they're first defined because that's a thing Batch does for some reason???
:ffmpeg
    for /R %%A in (*.mp4, *.avi, *.mov, *.wmv, *.ts, *.m2ts, *.mkv, *.mts) do (
        echo Processing "%%A"
        ffmpeg -hwaccel auto -i "%%A" -pix_fmt yuv420p -map 0:v -map 0:a -map_metadata 0 -c:v hevc_nvenc -rc constqp -qp %ffmpeg_qv% -b:v 0K -c:a aac -b:a 128k -movflags +faststart -movflags use_metadata_tags "%%A~dnpA_CRF%ffmpeg_qv%_HEVC.mp4"
        :: "-map_metadata 0" copies all metadata from source file
        :: "-movflags +faststart" helps with audio streaming
        echo Processed %%A
        :: echo inFile %%A outFile %%A~dnpA_CRF%ffmpeg_qv%_HEVC.mp4
        :: code here to check if A>B or B<A 
        :: then delete the larger of the two
    )
GOTO :EOF

1 个答案:

答案 0 :(得分:0)

这将满足需要。

请注意,由于您正在处理视频文件,因此它们很有可能大于32位整数限制,因此我需要编写代码来以防止该问题的方式相互检查文件。

@( SETLOCAL EnableDelayedExpansion
  ECHO OFF
  REM Default variables
  SET "_eLvl=0"
  SET "_Media_Extentions*.mp4, *.avi, *.mov, *.wmv, *.ts, *.m2ts, *.mkv, *.mts"
  SET /A "ffmpeg_qv=24" & REM change CQP value here so you only have to type it once. 22 is lossless for HEVC.
  SET "paths=C:\Folder\paths.txt" & REM File Containing several paths to work on, allows running many footage folders at once.
  REM SET "paths=C:\Jobs\paths.txt" & REM File Containing several paths to work on, allows running many footage folders at once.
  REM NOTE: - In Windows Explorer you can select as many folders as you like, then hold shift and right-click on them, this will give the option "copy as paths".
  REM NOTE: - you can also just put the list of paths directly into the FOR Loop section below instead of using a separate file.
  REM   Thanks to Aayla for a lot of these upgrades
)

REM Call main function, pass any arguments provided to the script.
CALL :Main %*

( ENDLOCAL
  EXIT /B %_eLvl%
)


:Main
  REM Test if the paths file exists and iterate through it
  IF NOT EXIST "%paths%" (
    ECHO=  "%paths%" Does Not Exist Adding either "%~2" or "%~dp0"
    IF /I "%~2" NEQ "" (
      ECHO=  "%~2" Was provided, adding that value.
      ECHO=%~2>"%paths%"
    ) ELSE (
      ECHO=  "%~2" Was blank, adding "%~dp0".
      ECHO="%~dp0">"%paths%"
    )
  )
  IF NOT EXIST "%paths%" (
    ECHO= ERROR!  Somehow the Paths File could not be created at "%paths%"
    ECHO= Exiting!
    SET "eLvl=100"
  ) ELSE (
    FOR /F "Tokens=*" %%_ in ('
      type "%paths%"
    ') DO (
      IF EXIST "%%~_" (
        ECHO Checking Media in Path "%%~_"
        CALL :ffmpeg "%%~_"
      ) ELSE (
        ECHO= This Path does Not Exist!
        SET "eLvl=110"
      )
    )
  )

GOTO :EOF


:ffmpeg
  ECHO= Entered %0, Path Found: "%~1"
  FOR /R "%~1" %%_ IN ( %_Media_Extentions% ) DO (
    echo Processing "%%~_"
    ffmpeg -hwaccel auto -i "%%~_" -pix_fmt yuv420p -map 0:v -map 0:a -map_metadata 0 -c:v hevc_nvenc -rc constqp -qp %ffmpeg_qv% -b:v 0K -c:a aac -b:a 128k -movflags +faststart -movflags use_metadata_tags "%%~dpn__CRF%ffmpeg_qv%_HEVC.mp4"
    echo Processed "%%~_"
    ECHO= Outer Loop - Checking if "%%~_" is Larger or Smaller than "%%~dpn__CRF%ffmpeg_qv%_HEVC.mp4"
    FOR %%# IN ("%%~dpn__CRF%ffmpeg_qv%_HEVC.mp4") DO (
      SET "_Deleted="
      ECHO=
      ECHO= Inner Loop - Checking if "%%~n_" is Larger or Smaller than "%%~n#"
      ECHO= Old FILE: "%%~nx_" Size: "%%~z_"
      ECHO= New FILE: "%%~nx#" Size: "%%~z#"
      IF /I "%%~z_" EQU "%%~z#" (
        SET "eLvl=200"
        ECHO= Size of the files are equal...  Deleting "%%~f#"
        DEL /F /Q "%%~f#"
      ) ELSE (
        ECHO= Sizes are Different, Checking Which is Larger.
        SET "_TmpSize_=%%~z_"
        SET "_TmpSize#=%%~z#"
        FOR %%A IN (0 1 2 3 4 5 6 7 8 9) DO (
          SET "_TmpSize_=!_TmpSize_:%%A=%%A !"
          SET "_TmpSize#=!_TmpSize#:%%A=%%A !"
        )
        FOR %%A IN (!_TmpSize_!) DO (
          CALL SET /A "_TmpSize_Count+=1"  )
        FOR %%A IN (!_TmpSize#!) DO (
          CALL SET /A "_TmpSize#Count+=1"  )
        ECHO= Checking the length of Each Number:
        IF !_TmpSize_Count! LSS !_TmpSize#Count! (
          ECHO= Smaller File is the Old File...  Deleting "%%~f#"
          DEL /F /Q "%%~f#"
        ) ELSE (
          IF !_TmpSize_Count! GTR !_TmpSize#Count! (
            ECHO= Smaller File is the New File...  Deleting "%%~f_"
            DEL /F /Q "%%~f_"
          ) ELSE (
            ECHO= File Sizes are the Same Number of Characters.  Need to try advanced checking.
            SET "_TmpSize_=!_TmpSize_: =!"
            SET "_TmpSize#=!_TmpSize#: =!"
            FOR /L %%L IN (1,1,!_TmpSize_Count!) DO (
              IF NOT DEFINED _Deleted (
                SET /A "_Tst_=!_TmpSize_:~%%L,1!"
                SET /A "_Tst#=!_TmpSize#:~%%L,1!"
                IF !_Tst_! NEQ !_Tst#! (
                  IF !_Tst_! LSS !_Tst#! (
                    ECHO= Smaller File is the Old File...  Deleting "%%~f#"
                    DEL /F /Q "%%~f#"
                  ) ELSE (
                    ECHO= Smaller File is the New File...  Deleting "%%~f_"
                    DEL /F /Q "%%~f_"
                  )
                  SET "_Deleted=1"
                )
              )
            )
          )
        )
      )
    )
    ECHO Finished Check
  )
  SET "eLvl=!ERRORLEVEL!"
GOTO :EOF