Релиз v1.0.0

This commit is contained in:
2026-08-09 11:07:22 +03:00
commit 30d344ad84
6 changed files with 714 additions and 0 deletions
+486
View File
@@ -0,0 +1,486 @@
@echo off
chcp 65001 >nul
setlocal EnableExtensions EnableDelayedExpansion
rem ============================================================
rem Express Video Encoder
rem Подготовка видео для отправки через мессенджер Express
rem ============================================================
set "TARGET_BYTES=39500000"
set "TARGET_MB=39.5"
set "AUDIO_KBPS=128"
set "OVERHEAD_KBPS=20"
set "FIRST_PASS_PRESET=8"
set "SECOND_PASS_PRESET=3"
if "%~1"=="" (
echo.
echo Перетащите видеофайл на encode-for-express.bat.
echo.
pause
exit /b 1
)
if not exist "%~f1" (
echo.
echo ОШИБКА: исходный файл не найден.
echo.
pause
exit /b 1
)
rem ============================================================
rem Поиск FFmpeg
rem ============================================================
set "FFMPEG="
set "FFPROBE="
if exist "%~dp0ffmpeg\ffmpeg.exe" set "FFMPEG=%~dp0ffmpeg\ffmpeg.exe"
if exist "%~dp0ffmpeg\ffprobe.exe" set "FFPROBE=%~dp0ffmpeg\ffprobe.exe"
if not defined FFMPEG (
where ffmpeg.exe >nul 2>&1
if not errorlevel 1 set "FFMPEG=ffmpeg.exe"
)
if not defined FFPROBE (
where ffprobe.exe >nul 2>&1
if not errorlevel 1 set "FFPROBE=ffprobe.exe"
)
if not defined FFMPEG (
echo.
echo ОШИБКА: ffmpeg.exe не найден.
echo Положите его в папку:
echo %~dp0ffmpeg
echo или добавьте FFmpeg в системный PATH.
echo.
pause
exit /b 1
)
if not defined FFPROBE (
echo.
echo ОШИБКА: ffprobe.exe не найден.
echo Положите его в папку:
echo %~dp0ffmpeg
echo или добавьте FFmpeg в системный PATH.
echo.
pause
exit /b 1
)
"%FFMPEG%" -hide_banner -encoders 2>nul | findstr /I /C:"libsvtav1" >nul
if errorlevel 1 (
echo.
echo ОШИБКА: эта сборка FFmpeg не содержит libsvtav1.
echo Нужна сборка FFmpeg с поддержкой SVT-AV1.
echo.
pause
exit /b 1
)
rem ============================================================
rem Чтение параметров исходного файла
rem Используем временные файлы вместо FOR /F вокруг команды ffprobe.
rem Это надежно работает с пробелами и русскими символами в путях.
rem ============================================================
set "PROBE_DIR=%TEMP%\express_video_encoder_%RANDOM%_%RANDOM%"
mkdir "%PROBE_DIR%" >nul 2>&1
set "SRC_VCODEC=Н/Д"
set "SRC_PROFILE=Н/Д"
set "SRC_WIDTH=Н/Д"
set "SRC_HEIGHT=Н/Д"
set "SRC_FPS_RAW=Н/Д"
set "SRC_FPS=Н/Д"
set "SRC_PIXFMT=Н/Д"
set "SRC_VBIT_BPS="
set "SRC_VBIT_KBPS=Н/Д"
set "DURATION="
"%FFPROBE%" -v error -select_streams v:0 -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1 "%~f1" > "%PROBE_DIR%\vcodec.txt" 2>nul
"%FFPROBE%" -v error -select_streams v:0 -show_entries stream=profile -of default=noprint_wrappers=1:nokey=1 "%~f1" > "%PROBE_DIR%\profile.txt" 2>nul
"%FFPROBE%" -v error -select_streams v:0 -show_entries stream=width -of default=noprint_wrappers=1:nokey=1 "%~f1" > "%PROBE_DIR%\width.txt" 2>nul
"%FFPROBE%" -v error -select_streams v:0 -show_entries stream=height -of default=noprint_wrappers=1:nokey=1 "%~f1" > "%PROBE_DIR%\height.txt" 2>nul
"%FFPROBE%" -v error -select_streams v:0 -show_entries stream=avg_frame_rate -of default=noprint_wrappers=1:nokey=1 "%~f1" > "%PROBE_DIR%\fps.txt" 2>nul
"%FFPROBE%" -v error -select_streams v:0 -show_entries stream=pix_fmt -of default=noprint_wrappers=1:nokey=1 "%~f1" > "%PROBE_DIR%\pixfmt.txt" 2>nul
"%FFPROBE%" -v error -select_streams v:0 -show_entries stream=bit_rate -of default=noprint_wrappers=1:nokey=1 "%~f1" > "%PROBE_DIR%\vbit.txt" 2>nul
"%FFPROBE%" -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "%~f1" > "%PROBE_DIR%\duration.txt" 2>nul
set /p SRC_VCODEC=<"%PROBE_DIR%\vcodec.txt"
set /p SRC_PROFILE=<"%PROBE_DIR%\profile.txt"
set /p SRC_WIDTH=<"%PROBE_DIR%\width.txt"
set /p SRC_HEIGHT=<"%PROBE_DIR%\height.txt"
set /p SRC_FPS_RAW=<"%PROBE_DIR%\fps.txt"
set /p SRC_PIXFMT=<"%PROBE_DIR%\pixfmt.txt"
set /p SRC_VBIT_BPS=<"%PROBE_DIR%\vbit.txt"
set /p DURATION=<"%PROBE_DIR%\duration.txt"
if not defined DURATION (
rd /s /q "%PROBE_DIR%" >nul 2>&1
echo.
echo ОШИБКА: не удалось определить длительность видео.
echo.
pause
exit /b 1
)
for /f "delims=" %%A in ('powershell.exe -NoProfile -Command "$p='!SRC_FPS_RAW!'.Split('/'); if($p.Count -eq 2 -and [double]$p[1] -ne 0){[math]::Round([double]$p[0]/[double]$p[1],3)}else{'!SRC_FPS_RAW!'}"') do set "SRC_FPS=%%A"
if defined SRC_VBIT_BPS (
for /f "delims=" %%A in ('powershell.exe -NoProfile -Command "[math]::Round([double]'!SRC_VBIT_BPS!'/1000)"') do set "SRC_VBIT_KBPS=%%A"
)
rem ============================================================
rem Аудио
rem ============================================================
set "SRC_ACODEC=Нет"
set "SRC_ABIT_BPS="
set "SRC_ABIT_KBPS=Н/Д"
set "SRC_SAMPLE_RATE=Н/Д"
set "SRC_CHANNELS=Н/Д"
set "HAS_AUDIO=0"
"%FFPROBE%" -v error -select_streams a:0 -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1 "%~f1" > "%PROBE_DIR%\acodec.txt" 2>nul
for %%F in ("%PROBE_DIR%\acodec.txt") do if %%~zF GTR 0 set "HAS_AUDIO=1"
if "!HAS_AUDIO!"=="1" (
set /p SRC_ACODEC=<"%PROBE_DIR%\acodec.txt"
"%FFPROBE%" -v error -select_streams a:0 -show_entries stream=bit_rate -of default=noprint_wrappers=1:nokey=1 "%~f1" > "%PROBE_DIR%\abit.txt" 2>nul
"%FFPROBE%" -v error -select_streams a:0 -show_entries stream=sample_rate -of default=noprint_wrappers=1:nokey=1 "%~f1" > "%PROBE_DIR%\arate.txt" 2>nul
"%FFPROBE%" -v error -select_streams a:0 -show_entries stream=channels -of default=noprint_wrappers=1:nokey=1 "%~f1" > "%PROBE_DIR%\channels.txt" 2>nul
set /p SRC_ABIT_BPS=<"%PROBE_DIR%\abit.txt"
set /p SRC_SAMPLE_RATE=<"%PROBE_DIR%\arate.txt"
set /p SRC_CHANNELS=<"%PROBE_DIR%\channels.txt"
if defined SRC_ABIT_BPS (
for /f "delims=" %%A in ('powershell.exe -NoProfile -Command "[math]::Round([double]'!SRC_ABIT_BPS!'/1000)"') do set "SRC_ABIT_KBPS=%%A"
)
)
rd /s /q "%PROBE_DIR%" >nul 2>&1
for /f "delims=" %%A in ('powershell.exe -NoProfile -Command "$s=[double]::Parse('!DURATION!',[Globalization.CultureInfo]::InvariantCulture); [TimeSpan]::FromSeconds($s).ToString('hh\:mm\:ss\.fff')"') do set "DURATION_FORMATTED=%%A"
cls
echo.
echo ============================================================
echo ИСХОДНЫЙ ФАЙЛ
echo ============================================================
echo Файл : %~nx1
echo Длительность : !DURATION_FORMATTED!
echo.
echo ВИДЕО
echo Кодек : !SRC_VCODEC!
echo Профиль : !SRC_PROFILE!
echo Разрешение : !SRC_WIDTH!x!SRC_HEIGHT!
echo Частота кадров : !SRC_FPS! FPS
echo Формат пикселей : !SRC_PIXFMT!
echo Видеобитрейт : !SRC_VBIT_KBPS! кбит/с
echo.
echo АУДИО
echo Кодек : !SRC_ACODEC!
echo Аудиобитрейт : !SRC_ABIT_KBPS! кбит/с
echo Частота : !SRC_SAMPLE_RATE! Гц
echo Каналы : !SRC_CHANNELS!
echo ============================================================
echo.
pause
rem ============================================================
rem Выбор разрешения
rem ============================================================
cls
echo.
echo ============================================================
echo ВЫБЕРИТЕ ВЫХОДНОЕ РАЗРЕШЕНИЕ
echo ============================================================
echo [1] 1920x1080 - Full HD
echo [2] 1600x900
echo [3] 1536x864
echo [4] 1280x720 - HD
echo [5] Указать вручную
echo ============================================================
echo.
:resolution_menu
set "RES_CHOICE="
set /p "RES_CHOICE=Выберите 1, 2, 3, 4 или 5: "
if "!RES_CHOICE!"=="1" (
set "OUT_WIDTH=1920"
set "OUT_HEIGHT=1080"
goto resolution_selected
)
if "!RES_CHOICE!"=="2" (
set "OUT_WIDTH=1600"
set "OUT_HEIGHT=900"
goto resolution_selected
)
if "!RES_CHOICE!"=="3" (
set "OUT_WIDTH=1536"
set "OUT_HEIGHT=864"
goto resolution_selected
)
if "!RES_CHOICE!"=="4" (
set "OUT_WIDTH=1280"
set "OUT_HEIGHT=720"
goto resolution_selected
)
if "!RES_CHOICE!"=="5" goto custom_resolution
echo.
echo Неверный выбор. Введите число от 1 до 5.
echo.
goto resolution_menu
:custom_resolution
echo.
set /p "OUT_WIDTH=Введите ширину: "
set /p "OUT_HEIGHT=Введите высоту: "
if not defined OUT_WIDTH goto invalid_resolution
if not defined OUT_HEIGHT goto invalid_resolution
echo(!OUT_WIDTH!| findstr /R "^[0-9][0-9]*$" >nul || goto invalid_resolution
echo(!OUT_HEIGHT!| findstr /R "^[0-9][0-9]*$" >nul || goto invalid_resolution
goto resolution_selected
:invalid_resolution
echo.
echo ОШИБКА: ширина и высота должны быть целыми положительными числами.
echo.
pause
exit /b 1
:resolution_selected
rem ============================================================
rem Выбор FPS
rem ============================================================
cls
echo.
echo ============================================================
echo ВЫБЕРИТЕ ЧАСТОТУ КАДРОВ
echo ============================================================
echo Исходная частота: !SRC_FPS! FPS
echo.
echo [1] 24 FPS
echo [2] 30 FPS
echo [3] Оставить исходную
echo [4] Указать вручную
echo ============================================================
echo.
:fps_menu
set "FPS_CHOICE="
set /p "FPS_CHOICE=Выберите 1, 2, 3 или 4: "
if "!FPS_CHOICE!"=="1" (
set "FPS=24"
goto fps_selected
)
if "!FPS_CHOICE!"=="2" (
set "FPS=30"
goto fps_selected
)
if "!FPS_CHOICE!"=="3" (
set "FPS=!SRC_FPS!"
goto fps_selected
)
if "!FPS_CHOICE!"=="4" goto custom_fps
echo.
echo Неверный выбор. Введите число от 1 до 4.
echo.
goto fps_menu
:custom_fps
echo.
set /p "FPS=Введите FPS: "
if not defined FPS (
echo.
echo ОШИБКА: FPS не указан.
echo.
pause
exit /b 1
)
:fps_selected
if "!HAS_AUDIO!"=="0" set "AUDIO_KBPS=0"
rem ============================================================
rem Расчет видеобитрейта
rem ============================================================
for /f "delims=" %%B in ('powershell.exe -NoProfile -Command "$d=[double]::Parse('!DURATION!',[Globalization.CultureInfo]::InvariantCulture); [math]::Floor((!TARGET_BYTES!*8/1000/$d)-!AUDIO_KBPS!-!OVERHEAD_KBPS!)"') do set "VIDEO_KBPS=%%B"
if not defined VIDEO_KBPS (
echo.
echo ОШИБКА: не удалось рассчитать видеобитрейт.
echo.
pause
exit /b 1
)
if !VIDEO_KBPS! LSS 300 (
echo.
echo ОШИБКА: рассчитанный видеобитрейт слишком низкий.
echo Получено: !VIDEO_KBPS! кбит/с
echo Выберите меньшее разрешение или увеличьте целевой размер.
echo.
pause
exit /b 1
)
for /f "delims=" %%I in ('powershell.exe -NoProfile -Command "Get-Date -Format yyyy-MM-dd_HH-mm-ss"') do set "TODAY=%%I"
set "OUTPUT_DIR=%~dp0output"
if not exist "!OUTPUT_DIR!" mkdir "!OUTPUT_DIR!" >nul 2>&1
set "OUT=!OUTPUT_DIR!\!TODAY!_Express_!OUT_WIDTH!x!OUT_HEIGHT!_!FPS!fps.mp4"
set "PASSLOG=%TEMP%\express_svtpass_!RANDOM!_!RANDOM!"
set "VIDEO_FILTER=fps=!FPS!,scale=!OUT_WIDTH!:!OUT_HEIGHT!:force_original_aspect_ratio=decrease:flags=lanczos,pad=!OUT_WIDTH!:!OUT_HEIGHT!:(ow-iw)/2:(oh-ih)/2"
cls
echo.
echo ============================================================
echo ПОДГОТОВКА ВИДЕО ДЛЯ EXPRESS
echo ============================================================
echo Разрешение : !OUT_WIDTH!x!OUT_HEIGHT!
echo Частота кадров : !FPS! FPS
echo Видеокодек : AV1 (SVT-AV1)
echo Видеобитрейт : !VIDEO_KBPS! кбит/с
if "!HAS_AUDIO!"=="1" (
echo Аудио : AAC, !AUDIO_KBPS! кбит/с, стерео
) else (
echo Аудио : отсутствует
)
echo Формат пикселей : yuv420p10le
echo Целевой размер : около !TARGET_MB! МБ
echo Первый проход : preset !FIRST_PASS_PRESET!
echo Второй проход : preset !SECOND_PASS_PRESET!
echo.
echo Результат будет сохранен в:
echo !OUTPUT_DIR!
echo ============================================================
echo.
:confirm_menu
set "CONFIRM="
set /p "CONFIRM=Начать кодирование? [Y/N]: "
if /I "!CONFIRM!"=="Y" goto start_encoding
if /I "!CONFIRM!"=="N" (
echo.
echo Кодирование отменено.
echo.
pause
exit /b 0
)
echo.
echo Введите Y или N.
echo.
goto confirm_menu
:start_encoding
echo.
echo [1/2] Анализ видео...
echo.
"%FFMPEG%" -y -i "%~f1" ^
-map 0:v:0 ^
-vf "!VIDEO_FILTER!" ^
-c:v libsvtav1 ^
-b:v !VIDEO_KBPS!k ^
-preset !FIRST_PASS_PRESET! ^
-pass 1 ^
-passlogfile "!PASSLOG!" ^
-pix_fmt yuv420p10le ^
-an ^
-f null NUL
if errorlevel 1 goto error
echo.
echo [2/2] Кодирование видео...
echo.
if "!HAS_AUDIO!"=="1" (
"%FFMPEG%" -y -i "%~f1" ^
-map 0:v:0 ^
-map 0:a:0? ^
-vf "!VIDEO_FILTER!" ^
-c:v libsvtav1 ^
-b:v !VIDEO_KBPS!k ^
-preset !SECOND_PASS_PRESET! ^
-pass 2 ^
-passlogfile "!PASSLOG!" ^
-pix_fmt yuv420p10le ^
-tag:v av01 ^
-c:a aac ^
-b:a !AUDIO_KBPS!k ^
-ac 2 ^
-movflags +faststart ^
-f mp4 ^
"!OUT!"
) else (
"%FFMPEG%" -y -i "%~f1" ^
-map 0:v:0 ^
-vf "!VIDEO_FILTER!" ^
-c:v libsvtav1 ^
-b:v !VIDEO_KBPS!k ^
-preset !SECOND_PASS_PRESET! ^
-pass 2 ^
-passlogfile "!PASSLOG!" ^
-pix_fmt yuv420p10le ^
-tag:v av01 ^
-an ^
-movflags +faststart ^
-f mp4 ^
"!OUT!"
)
if errorlevel 1 goto error
del /q "!PASSLOG!*" >nul 2>&1
for %%F in ("!OUT!") do set "FINAL_BYTES=%%~zF"
for /f "delims=" %%M in ('powershell.exe -NoProfile -Command "[math]::Round(!FINAL_BYTES!/1000000,2)"') do set "FINAL_MB=%%M"
echo.
echo ============================================================
echo ГОТОВО
echo ============================================================
echo Файл : !OUT!
echo Размер : !FINAL_MB! МБ
echo ============================================================
echo.
pause
exit /b 0
:error
del /q "!PASSLOG!*" >nul 2>&1
if defined OUT if exist "!OUT!" del /q "!OUT!" >nul 2>&1
echo.
echo ============================================================
echo ОШИБКА КОДИРОВАНИЯ
echo ============================================================
echo FFmpeg завершил работу с ошибкой.
echo.
pause
exit /b 1