Релиз v1.0.0
This commit is contained in:
+22
@@ -0,0 +1,22 @@
|
|||||||
|
# Результаты кодирования
|
||||||
|
*.mp4
|
||||||
|
*.mkv
|
||||||
|
*.webm
|
||||||
|
|
||||||
|
# Временные файлы FFmpeg
|
||||||
|
ffmpeg2pass-*.log
|
||||||
|
ffmpeg2pass-*.log.mbtree
|
||||||
|
*.tmp
|
||||||
|
*.temp
|
||||||
|
|
||||||
|
# Локальные бинарные файлы FFmpeg
|
||||||
|
ffmpeg/*.exe
|
||||||
|
!ffmpeg/.gitkeep
|
||||||
|
|
||||||
|
# Windows
|
||||||
|
Thumbs.db
|
||||||
|
Desktop.ini
|
||||||
|
|
||||||
|
# Результаты кодирования
|
||||||
|
output/*
|
||||||
|
!output/.gitkeep
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2026
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
@@ -0,0 +1,185 @@
|
|||||||
|
# Express Video Encoder
|
||||||
|
|
||||||
|
BAT-скрипт для Windows для подготовки видео к отправке через мессенджер **Express**. Скрипт перекодирует видео в **AV1** с помощью **FFmpeg / SVT-AV1** и автоматически подбирает видеобитрейт под заданный размер файла.
|
||||||
|
|
||||||
|
По умолчанию скрипт старается получить итоговый MP4 размером около **39,5 МБ**.
|
||||||
|
|
||||||
|
## Возможности
|
||||||
|
|
||||||
|
- кодирование видео в AV1 через `libsvtav1`;
|
||||||
|
- двухпроходное кодирование;
|
||||||
|
- автоматический расчет видеобитрейта по длительности ролика;
|
||||||
|
- целевой размер файла около 39,5 МБ;
|
||||||
|
- выбор разрешения;
|
||||||
|
- выбор частоты кадров;
|
||||||
|
- 10-битный формат `yuv420p10le`;
|
||||||
|
- AAC-аудио 128 кбит/с, стерео;
|
||||||
|
- чтение характеристик исходника через FFprobe;
|
||||||
|
- сохранение пропорций исходного изображения;
|
||||||
|
- удобный запуск перетаскиванием видео на BAT-файл.
|
||||||
|
|
||||||
|
## Требования
|
||||||
|
|
||||||
|
Необходима Windows с PowerShell и FFmpeg, содержащим:
|
||||||
|
|
||||||
|
- `ffmpeg.exe`;
|
||||||
|
- `ffprobe.exe`;
|
||||||
|
- кодировщик `libsvtav1`.
|
||||||
|
|
||||||
|
### Скачать FFmpeg для Windows
|
||||||
|
|
||||||
|
Готовую полную сборку FFmpeg для Windows можно скачать здесь:
|
||||||
|
|
||||||
|
[Скачать FFmpeg Release Full (.7z)](https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-full.7z)
|
||||||
|
|
||||||
|
После распаковки архива найдите в папке `bin` файлы:
|
||||||
|
|
||||||
|
```text
|
||||||
|
ffmpeg.exe
|
||||||
|
ffprobe.exe
|
||||||
|
```
|
||||||
|
|
||||||
|
Их можно скопировать в папку:
|
||||||
|
|
||||||
|
```text
|
||||||
|
express-video-encoder/ffmpeg/
|
||||||
|
```
|
||||||
|
|
||||||
|
Скрипт ищет FFmpeg в следующем порядке:
|
||||||
|
|
||||||
|
1. В локальной папке `ffmpeg` внутри репозитория.
|
||||||
|
2. В системной переменной `PATH`.
|
||||||
|
|
||||||
|
Для автономного варианта положите файлы сюда:
|
||||||
|
|
||||||
|
```text
|
||||||
|
express-video-encoder/ffmpeg/ffmpeg.exe
|
||||||
|
express-video-encoder/ffmpeg/ffprobe.exe
|
||||||
|
```
|
||||||
|
|
||||||
|
Если этих файлов нет, скрипт попробует использовать установленный в системе FFmpeg.
|
||||||
|
|
||||||
|
### Проверка SVT-AV1
|
||||||
|
|
||||||
|
Откройте PowerShell или CMD и выполните:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
ffmpeg -encoders | findstr svtav1
|
||||||
|
```
|
||||||
|
|
||||||
|
В списке должен присутствовать `libsvtav1`.
|
||||||
|
|
||||||
|
|
||||||
|
## Пути к файлам
|
||||||
|
|
||||||
|
Скрипт поддерживает пути, содержащие пробелы и русские символы. Видео можно хранить, например, в папках вида:
|
||||||
|
|
||||||
|
```text
|
||||||
|
E:\Моя библиотека\Видео\
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Совместимость с путями
|
||||||
|
|
||||||
|
Для чтения параметров видео скрипт использует временные файлы, поэтому корректно обрабатывает исходные файлы, расположенные в каталогах с пробелами и русскими символами.
|
||||||
|
|
||||||
|
## Использование
|
||||||
|
|
||||||
|
1. Скачайте или клонируйте репозиторий.
|
||||||
|
2. Положите `ffmpeg.exe` и `ffprobe.exe` в папку `ffmpeg`.
|
||||||
|
3. Убедитесь, что используемая сборка FFmpeg поддерживает SVT-AV1.
|
||||||
|
4. Перетащите нужный видеофайл мышью на `encode-for-express.bat`.
|
||||||
|
5. Проверьте информацию об исходном видео.
|
||||||
|
6. Выберите выходное разрешение.
|
||||||
|
7. Выберите частоту кадров.
|
||||||
|
8. Подтвердите запуск кодирования.
|
||||||
|
9. Дождитесь завершения двух проходов.
|
||||||
|
|
||||||
|
Готовый MP4 сохраняется в папку `output` внутри проекта:
|
||||||
|
|
||||||
|
```text
|
||||||
|
express-video-encoder/output/
|
||||||
|
```
|
||||||
|
|
||||||
|
Папка создаётся автоматически при первом запуске, если её ещё нет.
|
||||||
|
|
||||||
|
Пример имени:
|
||||||
|
|
||||||
|
```text
|
||||||
|
2026-08-09_09-45-12_Express_1920x1080_24fps.mp4
|
||||||
|
```
|
||||||
|
|
||||||
|
## Доступные разрешения
|
||||||
|
|
||||||
|
- 1920×1080 — Full HD;
|
||||||
|
- 1600×900;
|
||||||
|
- 1536×864;
|
||||||
|
- 1280×720 — HD;
|
||||||
|
- произвольная ширина и высота.
|
||||||
|
|
||||||
|
При масштабировании пропорции исходного видео сохраняются. Если соотношение сторон отличается от выбранного, недостающее пространство заполняется полями.
|
||||||
|
|
||||||
|
## Частота кадров
|
||||||
|
|
||||||
|
Можно выбрать:
|
||||||
|
|
||||||
|
- 24 FPS;
|
||||||
|
- 30 FPS;
|
||||||
|
- исходную частоту кадров;
|
||||||
|
- произвольное значение.
|
||||||
|
|
||||||
|
## Параметры кодирования
|
||||||
|
|
||||||
|
По умолчанию:
|
||||||
|
|
||||||
|
| Параметр | Значение |
|
||||||
|
|---|---|
|
||||||
|
| Видеокодек | AV1 / SVT-AV1 |
|
||||||
|
| Контейнер | MP4 |
|
||||||
|
| Pixel format | `yuv420p10le` |
|
||||||
|
| Целевой размер | ~39,5 МБ |
|
||||||
|
| Аудиокодек | AAC |
|
||||||
|
| Аудиобитрейт | 128 кбит/с |
|
||||||
|
| Аудиоканалы | 2 (стерео) |
|
||||||
|
| Первый проход | preset 8 |
|
||||||
|
| Второй проход | preset 3 |
|
||||||
|
|
||||||
|
Основные настройки находятся в начале `encode-for-express.bat`:
|
||||||
|
|
||||||
|
```bat
|
||||||
|
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"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Как рассчитывается размер
|
||||||
|
|
||||||
|
Скрипт получает длительность видео через FFprobe и рассчитывает доступный видеобитрейт с учетом:
|
||||||
|
|
||||||
|
- целевого размера файла;
|
||||||
|
- длительности ролика;
|
||||||
|
- аудиобитрейта;
|
||||||
|
- небольшого запаса на контейнер MP4.
|
||||||
|
|
||||||
|
Итоговый размер может немного отличаться от 39,5 МБ.
|
||||||
|
|
||||||
|
Если рассчитанный видеобитрейт оказывается ниже 300 кбит/с, кодирование не запускается. В таком случае рекомендуется выбрать меньшее разрешение либо увеличить целевой размер.
|
||||||
|
|
||||||
|
## Двухпроходное кодирование
|
||||||
|
|
||||||
|
Первый проход анализирует видео и создает служебную статистику.
|
||||||
|
|
||||||
|
Второй проход выполняет итоговое кодирование AV1 с использованием рассчитанного битрейта. Временные файлы статистики удаляются после завершения.
|
||||||
|
|
||||||
|
## Примечания
|
||||||
|
|
||||||
|
AV1 обеспечивает высокую эффективность сжатия, но кодирование может занимать значительно больше времени, чем H.264 или H.265.
|
||||||
|
|
||||||
|
Скорость особенно зависит от разрешения видео, длительности ролика, процессора и значения `preset`.
|
||||||
|
|
||||||
|
## Лицензия
|
||||||
|
|
||||||
|
Проект распространяется по лицензии MIT. См. файл `LICENSE`.
|
||||||
@@ -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
|
||||||
Reference in New Issue
Block a user