ahmadmanga avatar

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

ahmadmanga

Published: 28 Mar 2026 › Updated: 28 Mar 2026Creating a Batch File for Compressing Older Videos (Code Inside)

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

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

Written by

Fly with me out of Reality's boring corners to Imagination's Fascinating Horizons! (Muslim. Writer. Artist.)

Read more #hive-163521 posts


Best Posts From ahmadmanga

We have not curated any of ahmadmanga's posts yet. But you can encourage our curation team to review posts by visiting them regularly and by referring other readers. Because we give priority to frequently read content.

More Posts From ahmadmanga