ffmpeg – Variables CRF basierend auf Bitare

ffmpeg – Variables CRF basierend auf Bitare

Ich verwende ffmpeg, um einige Videos, die ich von verschiedenen Streaming-Sites heruntergeladen habe, in HEVC zu kodieren. Unter Windows verwende ich eine Batchdatei, um alle diese Dateien in einem Verzeichnis zu konvertieren.

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

Die Gesamtbitrate dieser Videos variiert zwischen 300 kb/s und 1500 kb/s. Bei meinen Tests führte die Verwendung desselben CRF für alle diese Videos entweder zu einer größeren Ausgabedatei bei Videos mit hoher Bitrate oder zu Videos mit niedriger Qualität bei Videos mit niedriger Bitrate. Daher ändere ich das CRF für eine Reihe von Videos mit ähnlicher Bitrate manuell. Wie kann ich dies mithilfe einer Batchdatei erreichen? Wenn die Gesamtbitrate beispielsweise über 950 liegt = CRF 26, wenn die Gesamtbitrate zwischen 750 und 949 liegt = CRF 24, wenn die Gesamtbitrate zwischen 500 und 749 liegt = CRF 22, wenn die Gesamtbitrate unter 499 liegt = CRF 18

Antwort1

@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 )
  • Der Mechaniker dahinter forund ifs...
       %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

Beob.: 1Es gibtzwei Leerzeichenzwischen^=^,^⟵⟶%%iIn: delims^=^,^spacespace%%i

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


1.- Ihre Hausaufgabe: Ersetzen Sie die untenstehenden Variablen auf eine mit Ihrem Szenario kompatible Weise und gehen Sie auch zu Ihrem Bat-Ordner:

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.Dieser Batch verwendet mehrere for loop. Damit dies funktioniert, müssen Sie aktivieren, Deleyed Expansiondamit die Variablen zur Laufzeit die aktualisierten/erweiterten Werte erhalten:

Setlocal EnableDelayedExpansion

3.Definieren Sie eine durch Kommas getrennte Variable und geben Sie zwischen den Trennzeichen die Werte ein, die in ifder forSchleife verwendet werden sollen, damit Sie mit Maximalwert, Minimalwert und kompatiblem CRF arbeiten können:

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.Verwenden Sie eine einfache forSchleife und eine zum Auflisten Ihrer.mp4Dateien und verwenden Sie zusätzlich einen Zähler (set /a "_c+=1+0")um am Ende des Laufs eine Gesamtsumme zu erhalten:

for %%# in (*.mp4)do echo; && set /a "_c+=1+0"
  • Beobachtungen: 2Derecho;wird nur verwendet, um die Zeile zu unterbrechen und die Visualisierung bei der Ausführung zu vereinfachen, indem eine Trennlinie in der Schleife erstellt wird.

5.Verwenden Sie eine zusätzliche Variable, um diese Schleife zu verwenden (in der ), in der Sie den vollständigen Pfad/Namen ( ) der mp4-Datei erhalten haben, und übergeben Sie diese Schleife als Eingabe an bereits definierende (erklärt unterfor /f1st/for/var==%%#%%~f#ffprobePunkt 5.), die Token und Trennzeichen, die in diesem Befehl verwendet werden sollen.

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

6.DerffprobeDer in der Schleife verwendete Befehl lautet:for /f

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

7.Beginnend mit der Umleitung StdErrauf StdOutdie ffprobeAusgabe, nach der gefiltert werden soll, findstrmithilfe des Schalters mit dem/End of a lineregexZahlen ([0-9]) mit der Zeichenfolge verknüpft .kb/sund unter Verwendung der richtigen Scaping-Methode inforSchleife:

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

8.Der obige erweiterte Befehl ohne die Escape-Zeichen ergibt:

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

9.Die vom Filter behandelte Ausgabe des obigen Befehls findstrergibt:

Dauer: 00:01:00.08, Beginn: -0.007000, Bitrate: 350 kb/s

10.Die vom Filter behandelte Ausgabe des obigen Befehls findstrergibt:

Dauer: 00:01:00.08, Beginn: -0.007000, Bitrate: 350 kb/s

11.Durch die Verwendung mehrerer Trennzeichen werden die Zeichenfolgen in%%iUnd%%jDie Ausgabe wird00:01:00.08Und350: ist für die letzte Befehlsausgabe, wird00:01:00.08Und350:

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

Bildbeschreibung hier eingeben

12.

Angenommen, Ihr Grenzwert ist350(inklusive) für die Bissrate müssen Sie ifim Arbeitsteil einige Optionen verwenden:

 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.Das Ergebnis vonifIsttrueoderfalse, und führt je nach Fall Aktionen aus. Aus didaktischen Gründen betrachten wir die aktuelle Datei alstrueFall:

 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"
  • Obs.:2Die Charaktere:space^, befinden sich am Ende der Zeile, direkt am Zeilenumbruch, wo der Befehlsinterpreter sie bei der Ausführung als einzelne Zeile behandelt und den angewendeten Zeilenumbruch umgeht.

// Entschuldigung, die Erklärungen werden morgen fortgesetzt …

verwandte Informationen