ffmpeg - Bitare 기반의 가변 CRF

ffmpeg - Bitare 기반의 가변 CRF

저는 ffmpeg를 사용하여 다양한 스트리밍 사이트에서 다운로드한 일부 비디오를 HEVC로 인코딩합니다. Windows에서는 배치 파일을 사용하여 디렉터리의 모든 파일을 변환합니다.

ffmpeg -n -i input.mp4 -c:v libx265 -crf 22 -c:a libopus -b:a 48k -vbr on -compression_level 10 -frame_duration 60 -application audio output.mkv

이러한 비디오의 전체 비트 전송률은 300kb/s에서 1500kb/s 사이입니다. 이러한 모든 비디오에 대해 동일한 CRF를 사용한 테스트에서 높은 비트 전송률 비디오의 경우 더 큰 출력 파일이 생성되거나 낮은 비트 전송률의 경우 낮은 품질의 비디오가 생성되었습니다. 그래서 비슷한 비트 전송률 비디오 모음에 대해 CRF를 수동으로 변경합니다. 배치 파일을 사용하여 어떻게 이를 달성할 수 있습니까? 마찬가지로, 전체 비트 전송률이 950보다 크면 crf 26 = 전체 비트 전송률이 750에서 949 사이이면 crf 24 = 전체 비트 전송률이 500에서 749 사이이면 crf 24 = 전체 비트 전송률이 499 미만이면 crf 22 = crf 18

답변1

@echo off & color 0A & cls 

cd /d "%~dp0" && setlocal enabledelayedexpansion
set "_ffmpeg=F:\2020-SU\Q1569837\ffmpeg\bin\ffmpeg.exe"
set "_ffprobe=F:\2020-SU\Q1569837\ffmpeg\bin\ffprobe.exe"
set "_range_crf=99999-950-26,949-750-24,749-500-22,499-0-18"

for %%# in (*.mp4)do echo; && set /a "_c+=1+0" && for /f tokens^=2^,6^delims^=^,^  %%i in ('
2^>^&1 "!_ffprobe!" -show_entries stream^=bit_rate "%%~f#"^|%__APPDIR__%findstr.exe /e [0-9].kb/s
')do echo\Check File: "%%~nx#" ^| Bite Rate: %%~j kb/s && call :^) "!_range_crf!" "%%~j" "%%~n#" "%%~f#" 

echo\ & <con: rem./ && echo\Total Files: 000!_c! && %__APPDIR__%timeout.exe /t -1 & endlocal && goto=:EOF

:^) 
echo\ && for %%i in (%~1)do for /f "tokens=1-3delims=-" %%a in ('echo\%%~i
')do if %~2 leq %%~a if %~2 geq %%~b title<nul & title .:^| File Name:"..\%~nx4" ^| Bite Rate: %~2 kb/s ^|:. && (
       "!_ffmpeg!" -y -i "%~4" -hide_banner -v error -stats -c:v libx265 -crf %%~c -c:a libopus -b:a 48k -vbr on ^
          -compression_level 10 -frame_duration 60 -application audio "%~3.mkv" && exit /b 0 )
  • 뒤에 정비공 forifs...
       %2       %%a         %2      %%b              %%c         
:: if 951 leq 99999 and if 951 GEQ  950 = True  crf = 26 then Exit /loop :label
:: if 951 leq   949 and if 951 GEQ  750         crf = 24 then      /loop :label 
:: if 951 leq   749 and if 951 GEQ  500         crf = 22 then      /loop :label 
:: if 951 leq   499 and if 951 GEQ    0         crf = 18 then      /loop :label 
::
:: if 800 leq   999 and if 800 GEQ  950 = False crf = 26 then Keep /loop :label
:: if 800 leq   949 and if 800 GEQ  750 = True  crf = 24 then Exit /loop :label
:: if 800 leq   749 and if 800 GEQ  500         crf = 22 then      /loop :label 
:: if 800 leq   499 and if 500 GEQ    0         crf = 18 then      /loop :label 
::
:: if 600 leq   999 and if 600 GEQ  950 = False crf = 26 then Keep /loop :label
:: if 600 leq   949 and if 600 GEQ  750 = False crf = 24 then Keep /loop :label
:: if 600 leq   749 and if 600 GEQ  500 = True  crf = 22 then Exit /loop :label 
:: if 600 leq   499 and if 600 GEQ    0         crf = 18 then      /loop :label 
::
:: if 501 leq   999 and if 501 GEQ  950 = False crf = 26 then Keep /loop :label
:: if 501 leq   949 and if 501 GEQ  750 = False crf = 24 then Keep /loop :label
:: if 501 leq   749 and if 501 GEQ  500 = True  crf = 22 then Exit /loop :label
:: if 501 leq   499 and if 501 GEQ    0         crf = 18 then      /loop :label 
:: 
:: if 498 leq   999 and if 498 GEQ  950 = False crf = 26 then Keep /loop :label
:: if 498 leq   949 and if 498 GEQ  750 = False crf = 24 then Keep /loop :label
:: if 498 leq   749 and if 498 GEQ  500 = False crf = 22 then Keep /loop :label
:: if 498 leq   499 and if 498 GEQ    0 = True  crf = 18 then Exit /loop :label

관찰: 1있다두 개의 공백~ 사이^=^,^⟵⟶%%i안에: delims^=^,^spacespace%%i

for %%# in (*.mp4)do for /f tokens^=2^,6^delims^=^,^spacespace%%i in (...


1.- 재택근무: 시나리오에 맞는 방식으로 아래 변수를 바꾸고 bat 폴더로 이동합니다.

set "_ffmpeg=F:\2020-SU\Q1569837\ffmpeg\bin\ffmpeg.exe"
set "_ffprobe=F:\2020-SU\Q1569837\ffmpeg\bin\ffprobe.exe"

cd /d "%~dp0"

rem :: if your *.pm4 files are not in the same directory 
rem :: as your bat file, use the full path to drive/folder 
rem :: Example for drive D: folder/subfolder \Media\MP4\Convert 

cd /d "D:\Midia\MP4\Convet"

2.이 배치는 다중을 사용합니다 for loop. 작동하려면 Deleyed Expansion변수가 런타임에 업데이트/확장된 값을 수신하도록 활성화해야 합니다.

Setlocal EnableDelayedExpansion

삼.최대값, 최소값 및 호환 crf로 작업할 수 있도록 쉼표로 구분되고 구분 기호 사이에 루프 if내 에서 사용할 값을 포함하는 변수를 정의합니다 .for

set "_range_crf= max-min-crf,max-min-24,max-500-22,499-0-18"
set "_range_crf=99999-950-26,949-750-24,749-500-22,499-0-18"

4.간단한 for루프와 루프를 사용하여 목록을 작성하세요..mp4파일을 사용하고 추가로 카운터(set /a "_c+=1+0")실행이 끝날 때 총계를 얻으려면 다음을 수행하십시오.

for %%# in (*.mp4)do echo; && set /a "_c+=1+0"
  • 관찰: 2그만큼echo;줄을 끊고 시각화를 더 쉽게 실행하기 위해 루프에 구분선을 만드는 데만 사용됩니다.

5.추가 항목을 사용 하여 mp4 파일의 전체 경로/이름( )을 얻은 이 루프 변수(에서)를 사용 하고 이 루프를 이미 정의된 입력으로 전달합니다 (설명됨).for /f1st/for/var==%%#%%~f#ffprobe항목 5.), 해당 명령에서 사용할 토큰 및 구분 기호입니다.

for /f tokens^=2^,6^delims^=^,^  %%i in (ffmprobe ...  %%~f# ... 

6.그만큼ffprobe루프 에 사용되는 명령은 다음과 같습니다for /f

..\ffprobe.exe -show_entries stream=bit_rate "Google Chrome - Now Everywhere.mp4"

7.스위치 를 사용하여 필터링할 출력 으로 StdErr리디렉션 하는 것부터 시작합니다.StdOutffprobefindstr/End of a lineregex숫자 ([0-9])를 문자열과 연결 .kb/s하고 적절한 스케이핑을 사용합니다.for고리:

2^>^&1 "!_ffprobe!" -show_entries stream^=bit_rate "%%~f#" ^| "%__APPDIR__%findstr.exe" /e [0-9].kb/s

8.위의 확장 명령을 이스케이프 없이 실행하면 다음과 같은 결과가 발생합니다.

2>&1 ..\ffprobe.exe -show_entries stream=bit_rate "Google Chrome - Now Everywhere.mkv" | "%__APPDIR__%findstr.exe" /e [0-9].kb/s

9.필터로 처리된 위 명령의 출력은 findstr다음과 같습니다.

지속 시간: 00:01:00.08, 시작: -0.007000, 비트 전송률: 350kb/s

10.필터로 처리된 위 명령의 출력은 findstr다음과 같습니다.

지속 시간: 00:01:00.08, 시작: -0.007000, 비트 전송률: 350kb/s

11.여러 구분 기호를 사용하면%%i그리고%%j출력은00:01:00.08그리고350: 마지막 명령 출력을 위한 것입니다.00:01:00.08그리고350:

... for /f tokens^=2^,6^delims^=^,^space %%i in (...
Duration: 00:01:00.08, start: -0.007000, bitrate: 350 kb/s

여기에 이미지 설명을 입력하세요

12.

한계 값이 다음과 같다고 가정합니다.350(포함한if) 바이트 속도의 경우 작업 부분에서 일부 옵션을 사용해야 합니다 .

 if %%~j > Bit_Rate      ∕∕ the same:  if %%~j > 349  (349 exclusive) 
 if %%~j  Bit_Rate      ∕∕ the same:  if %%~j  350  (350 inclusive) 

 set "_bit_rate=349"
 if %%~j > %_bit_rate%   ∕∕ the same:  if %%~j > 349  (349 exclusive) 

 set "_bit_rate=350"
 if %%~j  %_bit_rate%   ∕∕ the same:  if %%~j  350  (350 inclusive) 


 if LSS - Less Than                if [integer or int(var)]  < [integer or int(var)]
 if GTR - Greater Than             if [integer or int(var)]  > [integer or int(var)]
 if LEQ - Less Than or Equals      if [integer or int(var)]   [integer or int(var)]
 if GEQ - Greater Than or Equals   if [integer or int(var)]   [integer or int(var)]

13.결과if~이다true또는false, 사례에 따라 작업을 수행합니다. 교훈적인 목적으로 현재 파일을true사례:

 if %%~j GTR 349 (
      case true
      ffmpeg transcode file mp4
    ) else (
      case false
      skip this file .mp4
      save the full path name 
    )
  •  if %%~j gtr 349 2>&1 ("!_ffmpeg!" -y -i "%%~f#" -hide_banner -v error -stats -c:v libx265 -crf 22 ^
       -c:a libopus -b:a 48k -vbr on -compression_level 10 -frame_duration 60 -application audio "%%~n#.mkv"
  • 관찰:2캐릭터:space^는 줄 끝, 줄 바꿈 바로 옆에 있습니다. 여기서 실행 시 명령 해석기는 적용된 줄 바꿈을 이스케이프 처리하여 이를 단일 줄로 처리합니다.

// 죄송합니다. 설명은 내일 계속하겠습니다...

관련 정보