From c908b22128400040344e83a7e8018c35b332638b Mon Sep 17 00:00:00 2001 From: Stu Leak Date: Sun, 7 Dec 2025 11:37:45 -0500 Subject: [PATCH] Add Windows helper scripts and conversion questionnaire --- TODO.md | 1 + scripts/bat/check-video.bat | 66 ++++++++++ scripts/bat/convert-av1-h265-menu.bat | 126 +++++++++++++++++++ scripts/bat/convert-questionnaire.bat | 171 ++++++++++++++++++++++++++ scripts/install-deps-windows.bat | 63 ++++++++++ 5 files changed, 427 insertions(+) create mode 100644 scripts/bat/check-video.bat create mode 100644 scripts/bat/convert-av1-h265-menu.bat create mode 100644 scripts/bat/convert-questionnaire.bat create mode 100644 scripts/install-deps-windows.bat diff --git a/TODO.md b/TODO.md index 2a9e2bf..2c898f0 100644 --- a/TODO.md +++ b/TODO.md @@ -198,6 +198,7 @@ This file tracks upcoming features, improvements, and known issues. - [ ] Implement color correction filters - [ ] Brightness/Contrast - [ ] Saturation/Hue + - [ ] LUT support (1D/3D .cube load/apply) — primary home in Filters menu; optionally expose quick apply in Convert presets - [ ] Color balance - [ ] Curves/Levels - [ ] Implement enhancement filters diff --git a/scripts/bat/check-video.bat b/scripts/bat/check-video.bat new file mode 100644 index 0000000..47b11d1 --- /dev/null +++ b/scripts/bat/check-video.bat @@ -0,0 +1,66 @@ +@echo off +setlocal enabledelayedexpansion +chcp 65001 >nul +title VideoTools Quick Check + +if "%~1"=="" ( + echo Drag a video file onto this .bat + pause + exit /b 1 +) + +where ffprobe >nul 2>&1 && where ffmpeg >nul 2>&1 +if errorlevel 1 ( + echo ffmpeg/ffprobe not found in PATH. Install via winget/choco/scoop or run setup-windows. + pause + exit /b 1 +) + +cls +echo === VideoTools Quick Check === +echo File: "%~1" +echo. + +ffprobe -v error -hide_banner -i "%~1" ^ + -show_entries format=format_name,duration,size,bit_rate ^ + -show_entries stream=codec_name,codec_type,width,height,avg_frame_rate,channels,sample_rate ^ + -select_streams v:0 -select_streams a:0 ^ + -of default=noprint_wrappers=1:nokey=1 + +echo. +echo Checking interlacing (~first 600 frames)... +set "idetLine=" +for /f "usebackq tokens=*" %%L in (`ffmpeg -v error -hide_banner -i "%~1" -vf idet -frames:v 600 -an -sn -f null NUL 2^>^&1 ^| findstr /i "Multi frame detection"`) do set "idetLine=%%L" + +if not defined idetLine ( + echo (No idet summary found) + echo. + echo Done. + pause + exit /b 0 +) + +rem Example: Multi frame detection: TFF: 0 BFF: 0 Progressive: 898 Undetermined: 0 +for /f "tokens=5,7,9,11 delims=: " %%a in ("!idetLine!") do ( + set "TFF=%%a" + set "BFF=%%b" + set "PROG=%%c" + set "UNDET=%%d" +) + +set /a TOTAL=!TFF!+!BFF!+!PROG!+!UNDET! +if !TOTAL! NEQ 0 ( + set /a PTFF=(!TFF!*100)/!TOTAL! + set /a PBFF=(!BFF!*100)/!TOTAL! + set /a PPROG=(!PROG!*100)/!TOTAL! + set /a PUN=(!UNDET!*100)/!TOTAL! +) + +echo !idetLine! +if !TOTAL! GTR 0 ( + echo TFF: !TFF! (^~!PTFF!%%^) ^| BFF: !BFF! (^~!PBFF!%%^) ^| Progressive: !PROG! (^~!PPROG!%%^) ^| Undetermined: !UNDET! (^~!PUN!%%^) +) + +echo. +echo Done. +pause diff --git a/scripts/bat/convert-av1-h265-menu.bat b/scripts/bat/convert-av1-h265-menu.bat new file mode 100644 index 0000000..d50f38f --- /dev/null +++ b/scripts/bat/convert-av1-h265-menu.bat @@ -0,0 +1,126 @@ +@echo off +setlocal enabledelayedexpansion +chcp 65001 >nul +title AV1 / H265 Converter — Bitrate Menu + +REM Simple ffmpeg/ffprobe check +where ffmpeg >nul 2>&1 && where ffprobe >nul 2>&1 +if errorlevel 1 ( + echo ffmpeg/ffprobe not found in PATH. Install via winget/choco/scoop or run setup-windows. + pause + exit /b 1 +) + +set "SRC=%~dp0" +set "OUT=%SRC%Converted" +if not exist "%OUT%" md "%OUT%" + +cls +echo. +echo ======================================================== +echo Choose codec: +echo 1 = AV1 (av1_amf hardware) +echo 2 = H265 (hevc_amf hardware) +echo ======================================================== +choice /c 12 /n /m "Press 1 or 2: " + +set "codec=av1_amf" +set "codec_name=AV1" +if errorlevel 2 ( + set "codec=hevc_amf" + set "codec_name=H265" +) + +set "lossless=0" +if "%codec%"=="hevc_amf" ( + echo. + echo Optional: H.265 lossless uses CPU libx265 and ignores bitrate/CRF. + choice /c YN /n /m "Use H.265 lossless (libx265)? (Y/N): " + if not errorlevel 2 ( + set "lossless=1" + set "codec=libx265" + set "codec_name=H265 lossless (CPU)" + ) +) + +set "BITRATE=" +if "%lossless%"=="0" ( + echo. + echo Select target bitrate for %codec_name%: + if "%codec%"=="av1_amf" ( + echo 1 = 1200k (Grok 1080p sweet spot) + echo 2 = 1400k (safe default) + echo 3 = 1800k (extra headroom) + choice /c 123C /n /m "Pick 1-3 or C for custom: " + if errorlevel 4 ( + set /p BITRATE="Enter bitrate (e.g. 1600k or 8M): " + ) else if errorlevel 3 ( + set "BITRATE=1800k" + ) else if errorlevel 2 ( + set "BITRATE=1400k" + ) else ( + set "BITRATE=1200k" + ) + ) else ( + echo 1 = 1800k (lean 1080p H.265) + echo 2 = 2000k (balanced default) + echo 3 = 2400k (noisy sources) + choice /c 123C /n /m "Pick 1-3 or C for custom: " + if errorlevel 4 ( + set /p BITRATE="Enter bitrate (e.g. 2200k or 10M): " + ) else if errorlevel 3 ( + set "BITRATE=2400k" + ) else if errorlevel 2 ( + set "BITRATE=2000k" + ) else ( + set "BITRATE=1800k" + ) + ) +) + +echo. +echo Using %codec_name% output to "%OUT%" +if "%lossless%"=="0" ( + echo Target bitrate: %BITRATE% +) else ( + echo Mode: lossless (libx265 -x265-params lossless=1) +) +echo. + +set "found=0" + +for %%f in ("%SRC%*.mkv" "%SRC%*.mp4" "%SRC%*.mov" "%SRC%*.avi" "%SRC%*.wmv" "%SRC%*.mpg" "%SRC%*.mpeg" "%SRC%*.ts" "%SRC%*.m2ts") do ( + if exist "%%f" ( + set /a found+=1 + if exist "%OUT%\%%~nf__cv.mkv" ( + echo [SKIP] "%%~nxf" + ) else ( + echo Encoding: "%%~nxf" + for /f %%h in ('ffprobe -v error -select_streams v^:0 -show_entries stream^=height -of csv^=p^=0 "%%f" 2^>nul') do set h=%%h + + if "%lossless%"=="1" ( + if !h! LSS 1080 ( + ffmpeg -i "%%f" -vf scale=1920:1080:flags=lanczos -c:v libx265 -preset medium -x265-params lossless=1 -c:a copy "%OUT%\%%~nf__cv.mkv" + ) else ( + ffmpeg -i "%%f" -c:v libx265 -preset medium -x265-params lossless=1 -c:a copy "%OUT%\%%~nf__cv.mkv" + ) + ) else ( + if !h! LSS 1080 ( + ffmpeg -i "%%f" -vf scale=1920:1080:flags=lanczos -c:v %codec% -b:v %BITRATE% -maxrate %BITRATE% -bufsize 3600k -c:a copy "%OUT%\%%~nf__cv.mkv" + ) else ( + ffmpeg -i "%%f" -c:v %codec% -b:v %BITRATE% -maxrate %BITRATE% -bufsize 3600k -c:a copy "%OUT%\%%~nf__cv.mkv" + ) + ) + echo DONE: "%%~nf__cv.mkv" + ) + echo. + ) +) + +if %found%==0 echo No files found. + +echo. +echo ======================================================== +echo All finished! +echo ======================================================== +pause diff --git a/scripts/bat/convert-questionnaire.bat b/scripts/bat/convert-questionnaire.bat new file mode 100644 index 0000000..b868bb2 --- /dev/null +++ b/scripts/bat/convert-questionnaire.bat @@ -0,0 +1,171 @@ +@echo off +setlocal enabledelayedexpansion +chcp 65001 >nul +title VideoTools Helper — MKV Encode Questionnaire + +REM ------------------------------------------------------------ +REM Converts videos to MKV with selectable codec/bitrate, while +REM preserving all streams (audio/subtitle/attachments) and +REM copying color tags + pixel format to avoid color shifts. +REM ------------------------------------------------------------ + +where ffmpeg >nul 2>&1 && where ffprobe >nul 2>&1 +if errorlevel 1 ( + echo ffmpeg or ffprobe not found in PATH. Install them, then rerun. + pause + exit /b 1 +) + +echo. +set /p INPUT_PATH="Drag a file or folder here, then press Enter: " +if not defined INPUT_PATH ( + echo No input provided. Exiting. + exit /b 1 +) +set "INPUT_PATH=%INPUT_PATH:"=%" + +if exist "%INPUT_PATH%" ( + if exist "%INPUT_PATH%\" ( + set "MODE=folder" + set "INPUT_DIR=%INPUT_PATH%" + ) else ( + set "MODE=file" + set "INPUT_FILE=%INPUT_PATH%" + set "INPUT_DIR=%~dpINPUT_PATH%" + ) +) else ( + echo Path not found: %INPUT_PATH% + exit /b 1 +) + +set /p OUTPUT_DIR="Output folder (Enter for default 'Converted' next to inputs): " +if not defined OUTPUT_DIR ( + if "%MODE%"=="file" ( + set "OUTPUT_DIR=%~dpINPUT_FILE%Converted" + ) else ( + set "OUTPUT_DIR=%INPUT_DIR%Converted" + ) +) +if not exist "%OUTPUT_DIR%" md "%OUTPUT_DIR%" + +echo. +echo ======================================================== +echo Select video codec: +echo 1 = AV1 (libaom-av1) +echo 2 = H.265/HEVC (libx265) +echo 3 = Copy video (remux only) +echo ======================================================== +choice /c 123 /n /m "Choose 1-3: " +if errorlevel 3 ( + set "VCODEC=copy" + set "VCODEC_NAME=Copy" +) else if errorlevel 2 ( + set "VCODEC=libx265" + set "VCODEC_NAME=H.265" +) else ( + set "VCODEC=libaom-av1" + set "VCODEC_NAME=AV1" +) + +set "LOSSLESS=0" +if "%VCODEC%"=="libx265" ( + choice /c YN /n /m "Use H.265 lossless (CRF 0, lossless=1)? (Y/N): " + if not errorlevel 2 set "LOSSLESS=1" +) else if "%VCODEC%"=="libaom-av1" ( + choice /c YN /n /m "Use AV1 lossless (CRF 0, -b:v 0)? (Y/N): " + if not errorlevel 2 set "LOSSLESS=1" +) + +set "BITRATE=" +if "%VCODEC%"=="copy" ( + set "MODE_TEXT=Remux (no re-encode)" +) else if "%LOSSLESS%"=="1" ( + set "MODE_TEXT=Lossless" +) else ( + echo. + echo Enter target video bitrate (examples: 1400k, 2000k, 8M): + set /p BITRATE="Bitrate: " + if not defined BITRATE ( + echo No bitrate entered, defaulting to 2000k. + set "BITRATE=2000k" + ) + set "MODE_TEXT=Bitrate %BITRATE%" +) + +echo. +echo ======================================================== +echo Input : %INPUT_PATH% +echo Output: %OUTPUT_DIR% +echo Codec : %VCODEC_NAME% (%MODE_TEXT%) +echo ======================================================== +echo. +choice /c YN /n /m "Proceed? (Y/N): " +if errorlevel 2 exit /b 0 + +REM Build file list +set "LIST_FILE=%temp%\\vt_list.txt" +if exist "%LIST_FILE%" del "%LIST_FILE%" + +if "%MODE%"=="file" ( + echo "%INPUT_FILE%">"%LIST_FILE%" +) else ( + for %%f in ("%INPUT_DIR%\*.mkv" "%INPUT_DIR%\*.mp4" "%INPUT_DIR%\*.mov" "%INPUT_DIR%\*.avi" "%INPUT_DIR%\*.mpg" "%INPUT_DIR%\*.mpeg" "%INPUT_DIR%\*.ts" "%INPUT_DIR%\*.m2ts" "%INPUT_DIR%\*.wmv") do ( + if exist "%%~f" echo "%%~f">>"%LIST_FILE%" + ) +) + +for /f "usebackq delims=" %%f in ("%LIST_FILE%") do ( + set "IN=%%~f" + set "BASE=%%~nf" + set "OUT=%OUTPUT_DIR%\%%~nf__enc.mkv" + + echo -------------------------------------------------------- + echo Source: !IN! + echo Output: !OUT! + + call :probe_video "!IN!" PIX_FMT COLOR_PRIM COLOR_TRC COLOR_SPACE COLOR_RANGE + + set "PIX_ARG=" + if defined PIX_FMT set "PIX_ARG=-pix_fmt !PIX_FMT!" + + set "COLOR_ARGS=" + if defined COLOR_PRIM set "COLOR_ARGS=!COLOR_ARGS! -color_primaries !COLOR_PRIM!" + if defined COLOR_TRC set "COLOR_ARGS=!COLOR_ARGS! -color_trc !COLOR_TRC!" + if defined COLOR_SPACE set "COLOR_ARGS=!COLOR_ARGS! -colorspace !COLOR_SPACE!" + if defined COLOR_RANGE set "COLOR_ARGS=!COLOR_ARGS! -color_range !COLOR_RANGE!" + + if "%VCODEC%"=="copy" ( + ffmpeg -y -i "!IN!" -map 0 -c copy -map_metadata 0 -map_chapters 0 !PIX_ARG! !COLOR_ARGS! "!OUT!" + ) else if "%LOSSLESS%"=="1" ( + if "%VCODEC%"=="libx265" ( + ffmpeg -y -i "!IN!" -map 0 -c:v libx265 -crf 0 -preset medium -x265-params lossless=1 !PIX_ARG! !COLOR_ARGS! -c:a copy -c:s copy -c:d copy -map_metadata 0 -map_chapters 0 "!OUT!" + ) else ( + ffmpeg -y -i "!IN!" -map 0 -c:v libaom-av1 -crf 0 -b:v 0 -cpu-used 4 -row-mt 1 !PIX_ARG! !COLOR_ARGS! -c:a copy -c:s copy -c:d copy -map_metadata 0 -map_chapters 0 "!OUT!" + ) + ) else ( + ffmpeg -y -i "!IN!" -map 0 -c:v %VCODEC% -b:v %BITRATE% -maxrate %BITRATE% -bufsize %BITRATE% !PIX_ARG! !COLOR_ARGS! -c:a copy -c:s copy -c:d copy -map_metadata 0 -map_chapters 0 "!OUT!" + ) + echo DONE: !OUT! +) + +if exist "%LIST_FILE%" del "%LIST_FILE%" +echo. +echo All jobs finished. +pause +exit /b 0 + +:probe_video +REM Usage: call :probe_video "file" PIX_VAR PRIM_VAR TRC_VAR SPACE_VAR RANGE_VAR +set "P_FILE=%~1" +set "%2=" +set "%3=" +set "%4=" +set "%5=" +set "%6=" + +for /f "usebackq delims=" %%i in (`ffprobe -v error -select_streams v^:0 -show_entries stream^=pix_fmt -of csv^=p^=0 "%P_FILE%" 2^>nul`) do set "%2=%%i" +for /f "usebackq delims=" %%i in (`ffprobe -v error -select_streams v^:0 -show_entries stream^=color_primaries -of csv^=p^=0 "%P_FILE%" 2^>nul`) do set "%3=%%i" +for /f "usebackq delims=" %%i in (`ffprobe -v error -select_streams v^:0 -show_entries stream^=color_transfer -of csv^=p^=0 "%P_FILE%" 2^>nul`) do set "%4=%%i" +for /f "usebackq delims=" %%i in (`ffprobe -v error -select_streams v^:0 -show_entries stream^=color_space -of csv^=p^=0 "%P_FILE%" 2^>nul`) do set "%5=%%i" +for /f "usebackq delims=" %%i in (`ffprobe -v error -select_streams v^:0 -show_entries stream^=color_range -of csv^=p^=0 "%P_FILE%" 2^>nul`) do set "%6=%%i" +goto :eof diff --git a/scripts/install-deps-windows.bat b/scripts/install-deps-windows.bat new file mode 100644 index 0000000..df37e92 --- /dev/null +++ b/scripts/install-deps-windows.bat @@ -0,0 +1,63 @@ +@echo off +setlocal +chcp 65001 >nul +title VideoTools Windows Dependency Installer + +echo ======================================================== +echo VideoTools Windows Dependency Installer (.bat) +echo Installs Go, MinGW (GCC), Git, and FFmpeg +echo ======================================================== +echo. + +REM Prefer Chocolatey if available; otherwise fall back to winget. +where choco >nul 2>&1 +if %errorlevel%==0 ( + echo Using Chocolatey... + call :install_choco + goto :verify +) + +where winget >nul 2>&1 +if %errorlevel%==0 ( + echo Chocolatey not found; using winget... + call :install_winget + goto :verify +) + +echo Neither Chocolatey nor winget found. +echo Please install Chocolatey (recommended): https://chocolatey.org/install +echo Then re-run this script. +pause +exit /b 1 + +:install_choco +echo. +echo Installing dependencies via Chocolatey... +choco install -y golang mingw git ffmpeg +goto :eof + +:install_winget +echo. +echo Installing dependencies via winget... +REM Winget package IDs can vary; these are common defaults. +winget install -e --id GoLang.Go +winget install -e --id Git.Git +winget install -e --id GnuWin32.Mingw +winget install -e --id Gyan.FFmpeg +goto :eof + +:verify +echo. +echo ======================================================== +echo Verifying installs +echo ======================================================== +where go >nul 2>&1 && go version +where gcc >nul 2>&1 && gcc --version | findstr /R /C:"gcc" +where git >nul 2>&1 && git --version +where ffmpeg >nul 2>&1 && ffmpeg -version | head -n 1 + +echo. +echo Done. If any tool is missing, ensure its bin folder is in PATH +echo (restart terminal after installation). +pause +exit /b 0