Skip to content

Instantly share code, notes, and snippets.

@steveseguin
Last active October 2, 2024 05:43
Show Gist options
  • Save steveseguin/13c12958aa7e5371035f709f685659ce to your computer and use it in GitHub Desktop.
Save steveseguin/13c12958aa7e5371035f709f685659ce to your computer and use it in GitHub Desktop.
Compress a BluRay MKV Rip further; 30mbps -> 3mbps. Drag and Drop video onto batch file. VERY SLOW 2-PASS TRANSCODING.. Needs FFMPEG
@echo off
setlocal enabledelayedexpansion
if "%~1"=="" (
echo Drag and drop an MKV file onto this batch file to convert it.
pause
exit /b
)
set "input=%~1"
set "output=%~dpn1_hevc.mkv"
set "passlogfile=%~dpn1-passlog"
echo CPU Information:
wmic cpu get NumberOfCores, NumberOfLogicalProcessors
rem Set default CRF value and allow user to change it
set "crf=20"
set /p "crf=Enter CRF value (0-51, lower is better quality, default 20): " || set "crf=20"
rem Preview option
set "preview=N"
set /p "preview=Do you want to preview encode (3 minutes)? (Y/N, default N): " || set "preview=N"
rem Get video duration
for /f %%a in ('ffprobe -v error -show_entries format^=duration -of default^=noprint_wrappers^=1:nokey^=1 "%input%" 2^>^&1') do set "duration_raw=%%a"
if not defined duration_raw (
echo Error: Unable to determine video duration.
echo Raw ffprobe output:
ffprobe -v error -show_entries format^=duration -of default^=noprint_wrappers^=1:nokey^=1 "%input%"
pause
exit /b
)
echo Raw duration: %duration_raw%
rem Convert duration to seconds without using arithmetic
set "duration_seconds=%duration_raw:.=%"
set "duration_seconds=%duration_seconds:~0,-3%"
echo Video duration: %duration_seconds% seconds
rem Calculate preview start time (halfway through the movie, up to a max of 5 minutes)
set /a "midpoint=%duration_seconds% / 2"
set /a "max_start=300"
if %midpoint% gtr %max_start% (
set "previewstart=%max_start%"
) else (
set "previewstart=%midpoint%"
)
echo Preview will start at %previewstart% seconds
if /i "%preview%"=="Y" (
set "output=%~dpn1_preview_hevc.mkv"
set "ffmpeg_extra_args=-ss !previewstart! -t 180"
) else (
set "ffmpeg_extra_args="
)
if exist "%passlogfile%-0.log" (
echo Existing passlog file found.
set /p "resume=Do you want to resume from the second pass? (Y/N): "
if /i "!resume!"=="Y" goto second_pass
)
:first_pass
echo Starting first pass...
ffmpeg -y -i "%input%" !ffmpeg_extra_args! -c:v libx265 -crf %crf% ^
-preset slower -pass 1 -passlogfile "%passlogfile%" ^
-threads 0 -an -f null NUL
if %errorlevel% neq 0 (
echo First pass failed with error code %errorlevel%
pause
exit /b
)
:second_pass
echo Starting second pass...
ffmpeg -i "%input%" !ffmpeg_extra_args! -c:v libx265 -crf %crf% ^
-preset slower -pass 2 -passlogfile "%passlogfile%" ^
-threads 0 ^
-c:a libopus -b:a 256k -ac 2 ^
-map 0:v:0 -map 0:a:0 ^
-metadata:s:a:0 language=eng ^
-c:s copy ^
"%output%"
if %errorlevel% neq 0 (
echo Second pass failed with error code %errorlevel%
) else (
echo Conversion complete. Output file: %output%
rem Calculate and display estimated full size
if /i "%preview%"=="Y" (
for %%I in ("%output%") do set "previewsize=%%~zI"
if defined previewsize (
set /a "estimatedsize=%previewsize% * %duration_seconds% / 180"
set /a "estimatedsizeMB=%estimatedsize% / 1048576"
echo.
echo Preview encode complete.
echo Preview file size: %previewsize% bytes
echo Estimated full video size: %estimatedsizeMB% MB
) else (
echo Error: Unable to determine preview file size.
)
)
set /p "cleanup=Do you want to delete the passlog files? (Y/N): "
if /i "!cleanup!"=="Y" (
del "%passlogfile%-0.log" 2>nul
del "%passlogfile%-0.log.mbtree" 2>nul
)
)
pause
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment