Advertisement
muc-izhnet

video-2small-FFMPEG

May 28th, 2025 (edited)
642
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Batch 22.37 KB | None | 0 0
  1. @echo off
  2. :: Froz 25.05.2025 + ИИ Qwen
  3. :: Заготовка, требует тестирования !!!
  4.  
  5. :: === Блок: Настройки кодирования ===
  6.  
  7. :: Масштабирование видео (scale):
  8. ::    1280:720 - масштабировать до конкретного разрешения
  9. ::    1280:-1   - сохранить пропорции, ширина=1280, высота автоматическая.
  10. ::        Также можно и для высоты: -1:720.
  11. ::    если указанный здесь совпадёт с исходным,
  12. ::    или если не задано - размер остаётся без изменений
  13. set "SCALE=1280:720"
  14.  
  15. :: Поворот видео (Rotation tag).
  16. :: ВАЖНО: Аппаратные кодеки hevc_qsv и hevc_d3d12va НЕ подддерживают поворот - будет ошибка.
  17. :: Кодек hevc_amf может иметь ошибки с поворотом
  18. :: Возможные значения:
  19. ::    90 - поворот по часовой стрелке на 90 градусов
  20. ::    180 - поворот на 180 градусов
  21. ::    270 - поворот против часовой стрелки на 90 градусов
  22. ::    если не задано - поворот берётся из файла (rotation tag)
  23. set "ROTATION="
  24.  
  25. :: Аудио-настройки - по умолчанию копирование аудиодорожки
  26. :: Можно использовать "-c:a libopus -b:a 128k" для уменьшения размера
  27. set "AUDIO_ARGS=-c:a copy"
  28.  
  29. :: CRF (уровень качества).
  30. :: Рекомендуемые значения по убыванию качества и размера файла:
  31. ::    Для HEVC:  24-28
  32. ::    Для H.264: 20-23
  33. :: Если не задано - выбирает кодек.
  34. set "CRF="
  35.  
  36. :: Кодек и параметры кодирования:
  37. :: HEVC (H.265) кодеки:
  38. ::    hevc_nvenc   - NVIDIA GPU (рекомендуемый)
  39. ::    hevc_amf     - AMD GPU
  40. ::    hevc_qsv     - Intel Quick Sync Video
  41. ::    hevc_d3d12va - Windows Direct 12 (DXVA2), аппаратная поддержка
  42. ::    libx265      - software кодирование HEVC (очень медленно)
  43. :: H.264 кодеки:
  44. ::    h264_nvenc   - NVIDIA GPU (рекомендуемый)
  45. ::    h264_amf     - AMD GPU
  46. ::    h264_qsv     - Intel Quick Sync Video
  47. ::    libx264      - software кодирование H.264 (медленный)
  48. set "CODEC=hevc_nvenc"
  49.  
  50. :: Профиль кодирования.
  51. ::    для HEVC: main10 - 10 bit, main - 8 bit.
  52. ::    для H.264: автоматически выбирается high, независимо от указанного здесь.
  53. :: Если не задано - выбирает кодек.
  54. :: main10 поддерживают: hevc_nvenc, hevc_amf, libx265
  55. :: main10 может не воспроизводиться в старых проигрывателях и устройствах!
  56. set "PROFILE=main10"
  57.  
  58. :: Preset для hevc_nvenc (скорость/качество). Возможные значения: p1-p7 (скорость-качество).
  59. :: Если не задано - выбирает кодек (hevc_nvenc обычно p4/p5)
  60. set "PRESET="
  61.  
  62. :: Допустимые значения: .mkv (универсальнее) или .mp4.
  63. :: Для аппаратных кодеков H.264 - лучше выбрать .mp4.
  64. set "OUTPUT_EXT=.mkv"
  65.  
  66. :: Приставка к выходному имени файла (можно изменять или оставить пустой)
  67. set "NAME_APPEND=_sm"
  68.  
  69. :: === Окончание блока настроек ===
  70.  
  71.  
  72.  
  73.  
  74.  
  75. :: === Блок: Проверки ===
  76. :: Проверка архитектуры ОС
  77. :: Если переменная ProgramFiles(x86) не определена - система 32-битная (не поддерживается)
  78. if "%ProgramFiles(x86)%"=="" (
  79.     echo Windows 32-bit не поддерживается.
  80.     echo.
  81.     pause
  82.     exit /b
  83. )
  84.  
  85.  
  86. :: Проверка наличия входных файлов
  87. if "%~1" == "" (
  88.     echo.
  89.     echo Использование: перетяните иил вставьте видеофайлы на этот файл.
  90.     echo.
  91.     pause
  92.     exit /b
  93. )
  94.  
  95.  
  96. :: Переход в папку со скриптом, это важно для корректного вызова bin\ffmpeg.exe и bin\ffprobe.exe
  97. pushd "%~dp0"
  98. :: ВАЖНО - если будет enabledelayedexpansion - она должна быть после PUSHD
  99. :: иначе некорректно обработаются пути с "!".
  100. :: ВАЖНО - не используем комментарии с :: внутри if for else - там пишем rem Текст
  101.  
  102. :: Проверка наличия необходимых утилит
  103. :: ffmpeg - для конвертации видео
  104. :: ffprobe - для извлечения информации о видеофайле
  105. if not exist "bin\ffmpeg.exe" (
  106.     echo bin\ffmpeg.exe не найден, выходим.
  107.     exit /b
  108. )
  109. if not exist "bin\ffprobe.exe" (
  110.     echo bin\ffprobe.exe не найден, выходим.
  111.     exit /b
  112. )
  113.  
  114.  
  115.  
  116.  
  117. :: === Начинаем обработку файлов ===
  118. :FILE_LOOP
  119. if "%~1" == "" goto :FILE_LOOP_END
  120.  
  121.  
  122. ::  === Блок: Подготовка ===
  123. :: Подготовка путей
  124. :: Формируем имя выходного файла и путь к логу
  125. :: Проверяем, существует ли уже обработанный файл - если да, пропускаем
  126. :: Жёстко задаём формат видеоконтейнера MKV, как наиболее беспроблемный в сочетаниях видов видео-аудио дорожек
  127. set "OUTPUT_DIR=%~dp1"
  128. set "OUTPUT_NAME=%~n1%NAME_APPEND%"
  129. set "OUTPUT=%OUTPUT_DIR%OUTPUT_NAME%%OUTPUT_EXT%"
  130. set "OUTPUT=%OUTPUT_DIR%%OUTPUT_NAME%%OUTPUT_EXT%"
  131. set "LOG_DIR=%OUTPUT_DIR%logs\"
  132. set "FFMPEG_LOG=%LOG_DIR%%~n1%NAME_APPEND%_log.txt"
  133.  
  134. :: Проверяем что конечный файл уже может существовать
  135. if exist "%OUTPUT%" (
  136.     echo Файл %OUTPUT% уже существует, пропускаем.
  137.     shift
  138.     goto :FILE_LOOP
  139. )
  140.  
  141. :: Создаём папку для логов, если не существует
  142. if not exist "%LOG_DIR%" mkdir "%LOG_DIR%" 2>nul
  143. if not exist "%LOG_DIR%" (
  144.     echo Не удалось создать папку для логов: %LOG_DIR%. Выходим.
  145.     pause
  146.     exit /b 1
  147. )
  148.  
  149. :: Теперь можно выводить сообщения и в консоль и в лог
  150. type nul > "%FFMPEG_LOG%" 2>nul
  151. call :log ---------------------------------------------------------------------
  152. call :log [LOG START: %DATE% %TIME%]
  153. call :log [FILE] Начата обработка файла "%~nx1"...
  154.  
  155. :: Проверяем что исходный файл существует
  156. if not exist "%~1" (
  157.     call :log [ERROR] Файл "%~1" не найден.
  158.     shift
  159.     goto :FILE_LOOP
  160. )
  161.  
  162.  
  163.  
  164.  
  165. :: === Блок: COLOR_RANGE и PIX_FMT ===
  166.  
  167. :: Получаем pix_fmt через ffprobe
  168. set "PIX_FMT="
  169. set "TMP_FILE=%TEMP%\ffprobe_pix_fmt.tmp"
  170. "bin\ffprobe.exe" -v error -select_streams v:0 -show_entries stream=pix_fmt -of default=nw=1 "%~1" > "%TMP_FILE%" 2>nul
  171. if exist "%TMP_FILE%" (
  172.     set /p PIX_FMT= < "%TMP_FILE%"
  173.     del "%TMP_FILE%"
  174. ) else (
  175.     set "PIX_FMT="
  176. )
  177.  
  178. :: Определение цветового пространства (color_range)
  179. set "COLOR_RANGE="
  180.  
  181. :: Если pix_fmt = yuvj420p - это full-range JPEG, устанавливаем color_range=jpeg
  182. if "%PIX_FMT%" == "yuvj420p" (
  183.     set "COLOR_RANGE=-color_range jpeg"
  184.     call :log [INFO] Найден формат пикселей: %PIX_FMT% - будет использован %COLOR_RANGE%.
  185.     goto :SKIP_COLORRANGE
  186. )
  187. :: Если pix_fmt определён, но не yuvj420p - на случай связки yuv420p + color_range jpeg
  188. :: пытаемся получить color_range из metadata
  189. set "TMP_FILE=%TEMP%\ffprobe_color_range.tmp"
  190. "bin\ffprobe.exe" -v error -select_streams v:0 -show_entries stream=color_range -of default=nw=1 "%~1" > "%TMP_FILE%" 2>nul
  191. if exist "%TMP_FILE%" (
  192.     set /p COLOR_RANGE_RAW= < "%TMP_FILE%"
  193.     del "%TMP_FILE%"
  194.     if /i "%COLOR_RANGE_RAW%" == "jpeg" (
  195.         call :log [INFO] В metadata найден цветовой диапазон jpeg - будет учтён при кодировании.
  196.     )
  197.     set "COLOR_RANGE=-color_range %COLOR_RANGE_RAW%"
  198. )
  199. :: === Отключаем color_range для несовместимых кодеков ===
  200. set "USE_COLOR_RANGE=%COLOR_RANGE%"
  201. set "NO_COLOR_RANGE_CODECS=hevc_qsv hevc_d3d12va h264_qsv h264_d3d12va"
  202. echo.%NO_COLOR_RANGE_CODECS% | findstr /i /c:"%CODEC%" >nul && goto :DISABLE_COLOR_RANGE
  203. :: Если мы здесь - кодек поддерживает color_range
  204. goto :SKIP_COLORRANGE
  205. :DISABLE_COLOR_RANGE
  206. set "USE_COLOR_RANGE="
  207. :SKIP_COLORRANGE
  208.  
  209.  
  210.  
  211.  
  212.  
  213.  
  214. :: === Блок: ROTATION ===
  215. :: Определение поворота из метаданных и формирование фильтра transpose
  216. set "ROTATION_FILTER="
  217.  
  218. :: Проверяем, задан ли ROTATION вручную
  219. if defined ROTATION goto :APPLY_ROTATION_MANUAL
  220.  
  221. :: Если нет - пытаемся получить тег rotate из metadata
  222. set "TMP_FILE=%TEMP%\ffprobe_rotation.tmp"
  223. "bin\ffprobe.exe" -v error -show_entries stream_tags=rotate -of default=nw=1 "%~1" > "%TMP_FILE%" 2>nul
  224.  
  225. if not exist "%TMP_FILE%" goto :NO_ROTATION_TAG
  226. set /p ROTATION_TAG= < "%TMP_FILE%"
  227. del "%TMP_FILE%"
  228.  
  229. if not defined ROTATION_TAG goto :NO_ROTATION_TAG
  230. set "ROTATION=%ROTATION_TAG%"
  231.  
  232. :CHECK_ROTATION_SUPPORT
  233. set "UNSUPPORTED_ROTATION_CODECS=hevc_qsv hevc_d3d12va h264_qsv h264_d3d12va"
  234. echo.%UNSUPPORTED_ROTATION_CODECS% | find /i " %CODEC% " >nul && (
  235.     call :log [INFO] Кодек "%CODEC%" НЕ поддерживает поворот - значение игнорируется.
  236.     set "ROTATION="
  237.     set "ROTATION_TAG="
  238.     set "ROTATION_FILTER="
  239.     goto :SKIP_ROTATION
  240. )
  241.  
  242. :: Формируем фильтр поворота
  243. if "%ROTATION%" == "90" (
  244.     call :log [INFO] В metadata найден поворот на 90 гр. по часовой стрелке - будет учтён кодером.
  245.     set "ROTATION_FILTER=transpose=1"
  246.     goto :ROTATION_APPLIED
  247. )
  248. if "%ROTATION%" == "180" (
  249.     call :log [INFO] В metadata найден поворот на 180 гр. - будет учтён кодером.
  250.     set "ROTATION_FILTER=transpose=2,transpose=2"
  251.     goto :ROTATION_APPLIED
  252. )
  253. if "%ROTATION%" == "270" (
  254.     call :log [INFO] В metadata найден поворот на 90 гр. против часовой стрелки - будет учтён кодером.
  255.     set "ROTATION_FILTER=transpose=2"
  256.     goto :ROTATION_APPLIED
  257. )
  258.  
  259. :NO_ROTATION_TAG
  260. call :log [INFO] В metadata не найден тег rotate или он пуст.
  261. set "ROTATION="
  262.  
  263. :ROTATION_APPLIED
  264. :SKIP_ROTATION
  265.  
  266.  
  267.  
  268.  
  269.  
  270. :: === Блок: SCALE ===
  271. :: Обработка масштабирования видео (scale)
  272. set "SCALE_EXPR="
  273. set "TARGET_W="
  274. set "TARGET_H="
  275. :: Если SCALE не задан пользователем - пропускаем обработку
  276. if not defined SCALE goto :SKIP_SCALE
  277. :: Проверяем SCALE на формат число:число или -1:число
  278. echo.%SCALE% | findstr /r "^[0-9\-]*:[0-9\-]*$" >nul || (
  279.     call :log [INFO] Неверный формат SCALE: "%SCALE%" - должен быть например 1280:720 или 1280:-1
  280.     goto :SKIP_SCALE
  281. )
  282. :: Разбираем TARGET_W и TARGET_H из SCALE
  283. for /f "tokens=1,2 delims=:" %%w in ("%SCALE%") do (
  284.     set "TARGET_W=%%w"
  285.     set "TARGET_H=%%h"
  286. )
  287. :: Проверяем TARGET_W и TARGET_H на числа или -1
  288. echo.%TARGET_W% | findstr /r "^[0-9\-][0-9]*$" >nul || (
  289.     call :log [ERROR] TARGET_W некорректен: %TARGET_W%
  290.     goto :SKIP_SCALE
  291. )
  292. echo.%TARGET_H% | findstr /r "^[0-9\-][0-9]*$" >nul || (
  293.     call :log [ERROR] TARGET_H некорректен: %TARGET_H%
  294.     goto :SKIP_SCALE
  295. )
  296. :: Если есть поворот на 90 или 270 - меняем местами TARGET_W и TARGET_H
  297. if "%ROTATION%" == "90" (
  298.     set "TMP=%TARGET_W%"
  299.     set "TARGET_W=%TARGET_H%"
  300.     set "TARGET_H=%TMP%"
  301.     goto :AFTER_ROTATION_SWAP
  302. )
  303. if "%ROTATION%" == "270" (
  304.     set "TMP=%TARGET_W%"
  305.     set "TARGET_W=%TARGET_H%"
  306.     set "TARGET_H=%TMP%"
  307.     goto :AFTER_ROTATION_SWAP
  308. )
  309. :AFTER_ROTATION_SWAP
  310.  
  311. :: Пытаемся получить текущее разрешение через ffprobe (до поворота)
  312. :: Используем временный файл, так как здесь вывод ffprobe может содержать:
  313. ::     - пробелы (например, "1920 1080")
  314. ::     - специальные символы (например, escape-символы, двоеточия)
  315. ::     - пустые строки или ошибки
  316. :: Примеры, которые сломают цикл for /f:
  317. ::     - "1920 1080" > при нормализации становится "19201080" (неверно)
  318. ::     - "error" > будет считаться как ширина/высота
  319. :: Поэтому безопаснее читать через set /p < file
  320. set "CURRENT_DIM="
  321. set "TMP_FILE=%TEMP%\video_info.tmp"
  322. "bin\ffprobe.exe" -v error -select_streams v:0 -show_entries stream=width,height -of csv=p=0 "%~1" > "%TMP_FILE%" 2>nul
  323. if not exist "%TMP_FILE%" (
  324.     call :log [ERROR] Не удалось получить информацию о размере видео.
  325.     goto :SKIP_SCALE
  326. )
  327. set /p CURRENT_DIM= < "%TMP_FILE%"
  328. del "%TMP_FILE%"
  329. :: Проверяем формат вывода width,height
  330. echo.%CURRENT_DIM% | findstr /r /c:"^[0-9][0-9]*,[0-9][0-9]*$" >nul || (
  331.     call :log [ERROR] Неверный формат вывода ширины/высоты от ffprobe, пропускаем: "%CURRENT_DIM%"
  332.     goto :SKIP_SCALE
  333. )
  334. :: Разбираем значения ширины и высоты из файла
  335. for /f "tokens=1,2 delims=," %%a in ("%CURRENT_DIM%") do (
  336.     set "CURRENT_W=%%a"
  337.     set "CURRENT_H=%%b"
  338. )
  339. :: Если целевой размер совпадает с исходным - не масштабируем
  340. if "%CURRENT_W%" == "%TARGET_W%" if "%CURRENT_H%" == "%TARGET_H%" (
  341.     call :log [INFO] Размер совпадает с целевым. Масштабирование отключено.
  342.     goto :SKIP_SCALE
  343. )
  344. :: Формируем scale по условию
  345. if "%TARGET_H%" == "-1" (
  346.     set "SCALE_EXPR=scale=%TARGET_W%:-2"
  347.     call :log [INFO] Делаем масштабирование по ширине: %SCALE_EXPR%
  348.     goto :SCALE_DONE
  349. )
  350. if "%TARGET_W%" == "-1" (
  351.     set "SCALE_EXPR=scale=-2:%TARGET_H%"
  352.     call :log [INFO] Делаем масштабирование по высоте: %SCALE_EXPR%
  353.     goto :SCALE_DONE
  354. )
  355. :: Если указано точное разрешение - используем force_original_aspect_ratio + pad
  356. set "SCALE_EXPR=scale=%TARGET_W%:%TARGET_H%:force_original_aspect_ratio=decrease,pad=%TARGET_W%:%TARGET_H%:(ow-iw)/2:(oh-ih)/2"
  357. call :log [INFO] Делаем масштабирование с сохранением пропорций: %SCALE_EXPR%
  358. :SCALE_DONE
  359. :SKIP_SCALE
  360.  
  361.  
  362.  
  363.  
  364.  
  365. :: === Блок: FPS ===
  366. :: Получение частоты кадров (r_frame_rate) через ffprobe
  367. set "RAW_FPS="
  368. set "FPS="
  369. set "TMP_FILE=%TEMP%\ffprobe_fps.tmp"
  370. "bin\ffprobe.exe" -v error -select_streams v:0 -show_entries stream=r_frame_rate -of default=nw=1 "%~1" > "%TMP_FILE%" 2>nul
  371. if not exist "%TMP_FILE%" (
  372.     call :log [INFO] Не удалось получить r_frame_rate из файла.
  373.     goto :SKIP_FPS
  374. )
  375. set /p RAW_FPS= < "%TMP_FILE%"
  376. del "%TMP_FILE%"
  377.  
  378.  
  379. :: Проверяем формат вывода FPS на N/A, 0/0, .../0, 0/...
  380. echo.%RAW_FPS% | findstr /r "^[0-9]\+/[0-9]\+$" >nul || (
  381.     call :log [INFO] Неверный формат FPS: %RAW_FPS% - значение игнорируется.
  382.     goto :SKIP_FPS
  383. )
  384. for /f "tokens=1,2 delims=/" %%a in ("%RAW_FPS%") do (
  385.     if "%%a" == "0" (
  386.         call :log [INFO] Числитель FPS равен 0 - значение игнорируется.
  387.         goto :SKIP_FPS
  388.     )
  389.     if "%%b" == "0" (
  390.         call :log [INFO] Знаменатель FPS равен 0 - значение игнорируется.
  391.         goto :SKIP_FPS
  392.     )
  393. )
  394. :: Если всё верно - применяем
  395. set "FPS=fps=%RAW_FPS%,"
  396. call :log [INFO] Найден FPS: %RAW_FPS%.
  397. :SKIP_FPS
  398.  
  399.  
  400.  
  401.  
  402.  
  403. :: === Блок: Сборка видефильтра (-vf) ===
  404. :: Объединяем rotate, scale, fps
  405. set "FILTER_LIST="
  406. if defined ROTATION_FILTER set "FILTER_LIST=%FILTER_LIST%%ROTATION_FILTER%,"
  407. if defined SCALE_EXPR set "FILTER_LIST=%FILTER_LIST%%SCALE_EXPR%,"
  408. if defined FPS set "FILTER_LIST=%FILTER_LIST%%FPS%"
  409. :: Убираем завершающую запятую
  410. :: иначе строка -vf будет некорректна (например: "scale=1280:720,fps=30,)"
  411. if not "%FILTER_LIST%" == "" (
  412.     if "%FILTER_LIST:~-1%" == "," set "FILTER_LIST=%FILTER_LIST:~0,-1%"
  413. )
  414. if defined FILTER_LIST set "VF=-vf %FILTER_LIST%"
  415.  
  416.  
  417.  
  418.  
  419.  
  420. :: === Блок: Формат пикселей (pix_fmt) ===
  421. set "PIX_FMT_ARGS="
  422. :: Эти кодеки поддерживают p010le
  423. if /i "%CODEC%" == "hevc_nvenc" (
  424.     set "PIX_FMT_ARGS=-pix_fmt p010le"
  425.     goto :PIX_FMT_DONE
  426. )
  427. if /i "%CODEC%" == "libx265" (
  428.     set "PIX_FMT_ARGS=-pix_fmt yuv420p10le"
  429.     goto :PIX_FMT_DONE
  430. )
  431. if /i "%CODEC%" == "libx264" (
  432.     set "PIX_FMT_ARGS=-pix_fmt yuv420p"
  433.     goto :PIX_FMT_DONE
  434. )
  435. :: Эти кодеки НЕ поддерживают p010le
  436. if /i "%CODEC%" == "hevc_qsv" goto :PIX_FMT_DONE
  437. if /i "%CODEC%" == "hevc_d3d12va" goto :PIX_FMT_DONE
  438. if /i "%CODEC%" == "h264_qsv" goto :PIX_FMT_DONE
  439. if /i "%CODEC%" == "h264_d3d12va" goto :PIX_FMT_DONE
  440. :: По умолчанию используем yuv420p для H.264
  441. if /i "%CODEC:~0,5%" == "h264_" (
  442.     set "PIX_FMT_ARGS=-pix_fmt yuv420p"
  443. )
  444. :PIX_FMT_DONE
  445.  
  446.  
  447.  
  448.  
  449. :: === Блок: Профиль кодирования (profile:v) ===
  450. set "USE_PROFILE=main"
  451. if /i "%CODEC%" == "hevc_qsv" goto :PROFILE_DONE
  452. if /i "%CODEC%" == "hevc_d3d12va" goto :PROFILE_DONE
  453. set "USE_PROFILE=high"
  454. if /i "%CODEC%" == "h264_nvenc" goto :PROFILE_DONE
  455. if /i "%CODEC%" == "h264_amf" goto :PROFILE_DONE
  456. if /i "%CODEC%" == "h264_qsv" goto :PROFILE_DONE
  457. if /i "%CODEC%" == "libx264" goto :PROFILE_DONE
  458. set "USE_PROFILE=main10"
  459. if /i "%PROFILE%" == "main" set "USE_PROFILE=main"
  460. :PROFILE_DONE
  461.  
  462.  
  463.  
  464.  
  465. :: === Блок: Формирование команды ffmpeg ===
  466. set "FINAL_KEYS=-hide_banner -c:v %CODEC% -profile:v %USE_PROFILE% %VF% %PIX_FMT_ARGS% %USE_COLOR_RANGE% %AUDIO_ARGS% -c:s copy"
  467. :: --- CRF и аналоги по кодекам ---
  468. if not defined CRF goto :SKIP_CRF
  469. if /i "%CODEC%" == "libx265" (
  470.     set "FINAL_KEYS=%FINAL_KEYS% -crf %CRF%"
  471.     goto :SKIP_CRF
  472. )
  473. if /i "%CODEC%" == "hevc_nvenc" (
  474.     set "FINAL_KEYS=%FINAL_KEYS% -cq %CRF%"
  475.     goto :SKIP_CRF
  476. )
  477. if /i "%CODEC%" == "hevc_amf" (
  478.     set "FINAL_KEYS=%FINAL_KEYS% -quality %CRF%"
  479.     goto :SKIP_CRF
  480. )
  481. if /i "%CODEC%" == "hevc_qsv" (
  482.     set "FINAL_KEYS=%FINAL_KEYS% -global_quality %CRF%"
  483.     goto :SKIP_CRF
  484. )
  485. if /i "%CODEC%" == "libx264" (
  486.     set "FINAL_KEYS=%FINAL_KEYS% -crf %CRF%"
  487.     goto :SKIP_CRF
  488. )
  489. if /i "%CODEC%" == "h264_nvenc" (
  490.     set "FINAL_KEYS=%FINAL_KEYS% -cq %CRF%"
  491.     goto :SKIP_CRF
  492. )
  493. if /i "%CODEC%" == "h264_amf" (
  494.     set "FINAL_KEYS=%FINAL_KEYS% -quality %CRF%"
  495.     goto :SKIP_CRF
  496. )
  497. if /i "%CODEC%" == "h264_qsv" (
  498.     set "FINAL_KEYS=%FINAL_KEYS% -global_quality %CRF%"
  499.     goto :SKIP_CRF
  500. )
  501. :SKIP_CRF
  502.  
  503.  
  504.  
  505.  
  506. : === Блок: Preset и hwaccel ===
  507. :: Для HEVC и H.264
  508. if /i "%CODEC%" == "hevc_nvenc" if defined PRESET set "FINAL_KEYS=%FINAL_KEYS% -preset %PRESET%"
  509. if /i "%CODEC%" == "h264_nvenc" if defined PRESET set "FINAL_KEYS=%FINAL_KEYS% -preset %PRESET%"
  510. if /i "%CODEC%" == "hevc_amf" if defined PRESET set "FINAL_KEYS=%FINAL_KEYS% -quality %PRESET%"
  511. if /i "%CODEC%" == "h264_amf" if defined PRESET set "FINAL_KEYS=%FINAL_KEYS% -quality %PRESET%"
  512. if /i "%CODEC%" == "hevc_qsv" if defined PRESET set "FINAL_KEYS=%FINAL_KEYS% -preset %PRESET%"
  513. if /i "%CODEC%" == "h264_qsv" if defined PRESET set "FINAL_KEYS=%FINAL_KEYS% -preset %PRESET%"
  514. :: HWACCEL для некоторых кодеков
  515. if /i "%CODEC%" == "hevc_d3d12va" set "FINAL_KEYS=-hwaccel d3d12va %FINAL_KEYS%"
  516. if /i "%CODEC%" == "hevc_qsv" set "FINAL_KEYS=-hwaccel qsv %FINAL_KEYS%"
  517. if /i "%CODEC%" == "h264_d3d12va" set "FINAL_KEYS=-hwaccel d3d12va %FINAL_KEYS%"
  518. if /i "%CODEC%" == "h264_qsv" set "FINAL_KEYS=-hwaccel qsv %FINAL_KEYS%"
  519. :: Level и Tune (для H.264)
  520. if /i "%CODEC%" == "libx264" set "FINAL_KEYS=%FINAL_KEYS% -tune film"
  521. if /i "%CODEC:~0,5%" == "h264_" set "FINAL_KEYS=%FINAL_KEYS% -level 4.0"
  522.  
  523.  
  524.  
  525.  
  526. :: === Блок: Запуск ffmpeg ===
  527. call :log [INFO] Кодек: %CODEC%, Профиль: %USE_PROFILE%, CRF: %CRF%, Preset: %PRESET%
  528. call :log [CMD] %FINAL_KEYS% "%OUTPUT%"
  529. set "CMD_LINE=bin\ffmpeg.exe -i "%~1" %FINAL_KEYS% "%OUTPUT%""
  530. call :log [CMD] %CMD_LINE%
  531. call :log  --------------------------------------------------
  532. "%~dp0%bin\ffmpeg.exe" -i "%~1" %FINAL_KEYS% "%OUTPUT%" 2>> "%FFMPEG_LOG%"
  533. set "FFMPEG_EXIT_CODE=%errorlevel%"
  534. :: Анализ результата выполнения
  535. if %FFMPEG_EXIT_CODE% equ 0 goto :FFMPEG_SUCCESS
  536.     echo [ERROR] FFmpeg завершился с кодом ошибки %FFMPEG_EXIT_CODE% >> "%FFMPEG_LOG%"
  537.     goto :FFMPEG_DONE
  538. :FFMPEG_SUCCESS
  539.     echo [SUCCESS] Обработка успешно завершена >> "%FFMPEG_LOG%"
  540. :FFMPEG_DONE
  541.     echo [LOG END: %DATE% %TIME%] >> "%FFMPEG_LOG%"
  542. :: Переход к следующему файлу
  543. shift
  544. goto :FILE_LOOP
  545. :: Завершение работы
  546. :FILE_LOOP_END
  547.     echo Информация: Все файлы обработаны. Результаты и ошибки см. в логах.
  548.     popd
  549.     exit /b 0
  550.  
  551.  
  552.  
  553.  
  554. :: ---------------------
  555. :: Подпрограммы для CALL
  556. :: ---------------------
  557. :: Логирование в консоль и в файл
  558. :log
  559. echo:%~1
  560. if exist "%FFMPEG_LOG%" echo:%~1 >> "%FFMPEG_LOG%"
  561. exit /b
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement