Creating a Batch File for Compressing Older Videos (Code Inside)

In this article I'll talk about the Batch file I created to convert my Videos to the AV1 encoding.

My external HDD was getting full, so I spent a day to delete files I don't need anymore, but that wasn't enough. So, with what I learned from my earlier research on AV1 Encoding, I figured I could compress the older videos of my Let's Play game footage with AV1 encoding... I won't need most of them again, but I want to keep them all just in case.

So, I did some research (hint: conversations with AI) and guided AI to crate a batch code to do the job for me.

This code converts .mp4 files to .mkv files and vice-versa. The generated AV1 file does have less quality, but the size tradeoff for videos I probably won't need again, it wasn't a bad compromise.

Since this is just a batch code there are limits to how complex it can be. If I knew it'll become this long, I would've used python, but at least for now it does the job. The conversion on my PC takes about 9 minutes for an hour long video (at 720p) and twice as long in larger videos (1080p.) As I said above the quality is compromised, so I'll probably update this code to generate better quality.

What do you think?


The Code:

@echo off
setlocal enabledelayedexpansion

:: ============================================
:: Parse Command Line Arguments
:: ============================================
set "qvbr_quality=30"
set "resolution="
set "scale_filter="

:parse_args
if "%~1"=="" goto :done_args
if /i "%~1"=="-q" (
    set "qvbr_quality=%~2"
    shift
    shift
    goto :parse_args
)
if /i "%~1"=="--qvbr" (
    set "qvbr_quality=%~2"
    shift
    shift
    goto :parse_args
)
if /i "%~1"=="-r" (
    set "resolution=%~2"
    shift
    shift
    goto :parse_args
)
if /i "%~1"=="--resolution" (
    set "resolution=%~2"
    shift
    shift
    goto :parse_args
)
shift
goto :parse_args
:done_args

:: Build scale filter if resolution specified
if defined resolution (
    set "scale_filter=scale=-2:%resolution%,"
)

:: ============================================
:: Setup Log File
:: ============================================
for %%I in (.) do set "foldername=%%~nxI"

:: Use WMIC for locale-independent date/time
for /f "tokens=2 delims==" %%a in ('wmic os get localdatetime /value ^| find "="') do set "dt=%%a"
set "logfile=VidConvert-Log-!foldername!-!dt:~0,4!-!dt:~4,2!-!dt:~6,2!-!dt:~8,2!-!dt:~10,2!.txt"

:: Initialize log file with header
>> "%logfile%" echo ============================================
>> "%logfile%" echo    AV1 Batch Converter Log
>> "%logfile%" echo ============================================
>> "%logfile%" echo Date: !dt:~0,4!-!dt:~4,2!-!dt:~6,2! !dt:~8,2!:!dt:~10,2!:!dt:~12,2!
>> "%logfile%" echo Quality Level: %qvbr_quality%
if defined resolution >> "%logfile%" echo Resolution: %resolution%p
>> "%logfile%" echo.

echo ============================================
echo    AV1 Batch Converter for MKV/MP4 Files
echo ============================================
echo.
echo Settings:
echo   QVBR Quality: %qvbr_quality%
if defined resolution (
    echo   Resolution:   %resolution%p (scaled)
) else (
    echo   Resolution:   Original
)
echo   Log File:     %logfile%
echo.

:: Initialize counters and totals
set /a completed=0
set /a remaining=0
set /a current=0
set /a skipped=0
set /a errors=0
set /a total_input_size=0
set /a total_output_size=0

:: Count files that need conversion
for %%f in (*.mkv) do (
    if not exist "%%~nf.mp4" set /a remaining+=1
)
for %%f in (*.mp4) do (
    if not exist "%%~nf.mkv" set /a remaining+=1
)

set /a total=%remaining%

if %total%==0 (
    echo No files need conversion. All MKV/MP4 pairs already exist.
    >> "%logfile%" echo No files need conversion. All MKV/MP4 pairs already exist.
    goto :end
)

echo Files to convert: %total%
echo.

:: ============================================
:: Convert MKV to MP4
:: ============================================
for %%f in (*.mkv) do (
    set "input=%%f"
    set "basename=%%~nf"
    set "output=%%~nf.mp4"
    
    if exist "!output!" (
        echo [SKIP] !output! already exists
        set /a skipped+=1
    ) else (
        set /a current+=1
        
        :: Get input file size in bytes
        for %%a in ("!input!") do set /a input_size=%%~za
        
        echo.
        echo ============================================
        echo [!current!/%total%] Converting: !input!
        echo ============================================
        echo Input size: !input_size! bytes
        echo Encoding in progress...
        echo.
        
        :: Log start of conversion
        >> "%logfile%" echo [%date% %time%] START: !input!
        
        :: Run FFmpeg with AMF AV1 encoder (output to terminal only)
        ffmpeg -y -xerror -i "!input!" -c:v av1_amf -rc qvbr -qvbr_quality_level %qvbr_quality% -preset high_quality -aq_mode caq -preencode true -preanalysis true -pa_lookahead_buffer_depth 40 -pa_taq_mode 2 -pa_adaptive_mini_gop true -bf 3 -g 180 -vf "!scale_filter!hqdn3d=2:2:0:0" -c:a copy "!output!"
        
        if errorlevel 1 (
            echo.
            echo [ERROR] FFmpeg failed on !input!
            if exist "!output!" del "!output!"
            set /a errors+=1
            >> "%logfile%" echo [%date% %time%] ERROR: !input! - Conversion failed
            >> "%logfile%" echo.
        ) else (
            :: Get output file size
            for %%a in ("!output!") do set /a output_size=%%~za
            
            :: Calculate compression ratio (fixed point math with 2 decimals)
            set /a ratio_num=input_size*100/output_size
            set /a ratio_whole=ratio_num/100
            set /a ratio_dec=ratio_num%%100
            set /a saved_percent=100-(output_size*100/input_size)
            
            :: Apply creation date from input to output
            powershell -command "try { $src = Get-Item '!input!'; $dst = Get-Item '!output!'; $dst.CreationTime = $src.CreationTime } catch {}"
            
            set /a completed+=1
            set /a total_input_size+=input_size
            set /a total_output_size+=output_size
            
            echo.
            echo ----------------------------------------
            echo [DONE] !input! -^> !output!
            echo ----------------------------------------
            echo Input:  !input_size! bytes
            echo Output: !output_size! bytes
            echo Ratio:  !ratio_whole!.!ratio_dec!x (!saved_percent%% smaller)
            echo ----------------------------------------
            
            :: Log successful conversion
            >> "%logfile%" echo [%date% %time%] DONE: !input! -^> !output!
            >> "%logfile%" echo   Input:  !input_size! bytes
            >> "%logfile%" echo   Output: !output_size! bytes
            >> "%logfile%" echo   Ratio:  !ratio_whole!.!ratio_dec!x (!saved_percent%% smaller)
            >> "%logfile%" echo.
        )
        
        set /a remaining=total-completed-skipped-errors
        echo Progress: Completed=%completed% Remaining=!remaining! Errors=%errors%
        
        if !completed! GTR 0 (
            set /a mod=completed%%3
            if !mod!==0 (
                echo.
                echo ****************************************
                echo  STATUS: %completed% done, !remaining! remaining, %errors% errors
                echo ****************************************
                echo.
            )
        )
    )
)

:: ============================================
:: Convert MP4 to MKV
:: ============================================
for %%f in (*.mp4) do (
    set "input=%%f"
    set "basename=%%~nf"
    set "output=%%~nf.mkv"
    
    if exist "!output!" (
        echo [SKIP] !output! already exists
        set /a skipped+=1
    ) else (
        set /a current+=1
        
        :: Get input file size in bytes
        for %%a in ("!input!") do set /a input_size=%%~za
        
        echo.
        echo ============================================
        echo [!current!/%total%] Converting: !input!
        echo ============================================
        echo Input size: !input_size! bytes
        echo Encoding in progress...
        echo.
        
        :: Log start of conversion
        >> "%logfile%" echo [%date% %time%] START: !input!
        
        :: Run FFmpeg with AMF AV1 encoder (output to terminal only)
        ffmpeg -y -xerror -i "!input!" -c:v av1_amf -rc qvbr -qvbr_quality_level %qvbr_quality% -preset high_quality -aq_mode caq -preencode true -preanalysis true -pa_lookahead_buffer_depth 40 -pa_taq_mode 2 -pa_adaptive_mini_gop true -bf 3 -g 180 -vf "!scale_filter!hqdn3d=2:2:0:0" -c:a copy "!output!"
        
        if errorlevel 1 (
            echo.
            echo [ERROR] FFmpeg failed on !input!
            if exist "!output!" del "!output!"
            set /a errors+=1
            >> "%logfile%" echo [%date% %time%] ERROR: !input! - Conversion failed
            >> "%logfile%" echo.
        ) else (
            :: Get output file size
            for %%a in ("!output!") do set /a output_size=%%~za
            
            :: Calculate compression ratio (fixed point math with 2 decimals)
            set /a ratio_num=input_size*100/output_size
            set /a ratio_whole=ratio_num/100
            set /a ratio_dec=ratio_num%%100
            set /a saved_percent=100-(output_size*100/input_size)
            
            :: Apply creation date from input to output
            powershell -command "try { $src = Get-Item '!input!'; $dst = Get-Item '!output!'; $dst.CreationTime = $src.CreationTime } catch {}"
            
            set /a completed+=1
            set /a total_input_size+=input_size
            set /a total_output_size+=output_size
            
            echo.
            echo ----------------------------------------
            echo [DONE] !input! -^> !output!
            echo ----------------------------------------
            echo Input:  !input_size! bytes
            echo Output: !output_size! bytes
            echo Ratio:  !ratio_whole!.!ratio_dec!x (!saved_percent%% smaller)
            echo ----------------------------------------
            
            :: Log successful conversion
            >> "%logfile%" echo [%date% %time%] DONE: !input! -^> !output!
            >> "%logfile%" echo   Input:  !input_size! bytes
            >> "%logfile%" echo   Output: !output_size! bytes
            >> "%logfile%" echo   Ratio:  !ratio_whole!.!ratio_dec!x (!saved_percent%% smaller)
            >> "%logfile%" echo.
        )
        
        set /a remaining=total-completed-skipped-errors
        echo Progress: Completed=%completed% Remaining=!remaining! Errors=%errors%
        
        if !completed! GTR 0 (
            set /a mod=completed%%3
            if !mod!==0 (
                echo.
                echo ****************************************
                echo  STATUS: %completed% done, !remaining! remaining, %errors% errors
                echo ****************************************
                echo.
            )
        )
    )
)

:end
echo.
echo ============================================
echo  CONVERSION COMPLETE
echo ============================================
echo  Files converted: %completed%
echo  Files skipped:   %skipped%
echo  Files failed:    %errors%
echo.

if %completed% GTR 0 (
    :: Calculate total compression stats
    set /a total_ratio_num=total_input_size*100/total_output_size
    set /a total_ratio_whole=total_ratio_num/100
    set /a total_ratio_dec=total_ratio_num%%100
    set /a total_saved_percent=100-(total_output_size*100/total_input_size)
    
    echo  TOTAL COMPRESSION SUMMARY
    echo  ----------------------------------------
    echo  Input size:  %total_input_size% bytes
    echo  Output size: %total_output_size% bytes
    echo  Ratio:       !total_ratio_whole!.!total_ratio_dec!x
    echo  Space saved: !total_saved_percent!%%
    echo ============================================
    
    :: Write final summary to log
    >> "%logfile%" echo ============================================
    >> "%logfile%" echo  FINAL SUMMARY
    >> "%logfile%" echo ============================================
    >> "%logfile%" echo Files converted: %completed%
    >> "%logfile%" echo Files skipped:   %skipped%
    >> "%logfile%" echo Files failed:    %errors%
    >> "%logfile%" echo Input size:  %total_input_size% bytes
    >> "%logfile%" echo Output size: %total_output_size% bytes
    >> "%logfile%" echo Ratio:       !total_ratio_whole!.!total_ratio_dec!x
    >> "%logfile%" echo Space saved: !total_saved_percent!%%
    >> "%logfile%" echo ============================================
)

echo Log saved to: %logfile%
echo.
echo Press any key to close...
pause >nul

Posted Using INLEO



0
0
0.000
0 comments