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:
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
- Chained Echoes [Let's Play] - 37 - The Seven True Kings
- Chained Echoes [Let's Play] - 36 - Discovering Gate to Nhysa
- Dino Crisis 2 [Let's Play] - 09
- Dino Crisis 2 [Let's Play] - 08
- Chained Echoes [Let's Play] - 35 - True Threat of Vaen
- Chained Echoes [Let's Play] - 34 - The Vaen
- Dino Crisis 2 [Let's Play] - 07
- Chained Echoes [Let's Play] - 33 - The End of the Oath
- Dino Crisis 2 [Let's Play] - 06
- Chained Echoes [Let's Play] - 32 - Flames of Godfrey