ffmpeg - Datei überspringen, wenn die Bitrate niedriger als ein bestimmter Wert ist

ffmpeg - Datei überspringen, wenn die Bitrate niedriger als ein bestimmter Wert ist

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 diese Dateien zu konvertieren.

FOR /F "tokens=*" %%G IN ('dir /b *.mp4') DO ffmpeg -n -i "%%G" -c:v libx265 -crf 22 -c:a libopus -b:a 48k -vbr on -compression_level 10 -frame_duration 60 -application audio "%%~nG.mkv"

Einige dieser Dateien haben eine sehr niedrige Bitrate und ich möchte diese nicht anfassen. Gibt es in ffmpeg eine Möglichkeit, diese Dateien zu überspringen? Oder einen Befehl, den ich in die Batchdatei einfügen kann, z. B. um ffprobedie Bitrate abzurufen und sie mit dem Befehl zu überspringen.

Antwort1

@echo off 

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"

for %%# in (*.mp4)do 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 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" 
     )else set/a "_c+=1+0" && <con: call set "_skp_!_c!=Skipped File: %%~nx# Duration: %%~i Bit Rate: %%~j"
      
echo;& (for /f tokens^=2^delims^=^= %%i in ('set _skp_ 2^>nul')do echo\%%~i) & %__APPDIR__%timeout.exe -1 & endlocal
  • Ausgabe:
x265 [info]: HEVC encoder version 3.4+2-73ca1d7be377
x265 [info]: build info [Windows][GCC 9.3.1][64 bit] 8bit+10bit
x265 [info]: using cpu capabilities: MMX2 SSE2Fast LZCNT SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2
x265 [info]: Main profile, Level-3.1 (Main tier)
x265 [info]: Thread pool created using 4 threads
x265 [info]: Slices                              : 1
x265 [info]: frame threads / pool features       : 2 / wpp(12 rows)
x265 [info]: Coding QT: max CU size, min CU size : 64 / 8
x265 [info]: Residual QT: max TU size, max depth : 32 / 1 inter / 1 intra
x265 [info]: ME / range / subpel / merge         : hex / 57 / 2 / 3
x265 [info]: Keyframe min / max / scenecut / bias  : 23 / 250 / 40 / 5.00
x265 [info]: Lookahead / bframes / badapt        : 20 / 4 / 2
x265 [info]: b-pyramid / weightp / weightb       : 1 / 1 / 0
x265 [info]: References / ref-limit  cu / depth  : 3 / off / on
x265 [info]: AQ: mode / str / qg-size / cu-tree  : 2 / 1.0 / 32 / 1
x265 [info]: Rate Control / qCompress            : CRF-22.0 / 0.60
x265 [info]: tools: rd=3 psy-rd=2.00 early-skip rskip mode=1 signhide tmvp
x265 [info]: tools: b-intra strong-intra-smoothing lslices=4 deblock sao
frame= 1440 fps= 55 q=29.8 Lsize=    2570kB time=00:01:00.11 bitrate= 350.3kbits/s speed=2.32x
x265 [info]: frame I:      6, Avg QP:22.93  kb/s: 1138.86
x265 [info]: frame P:    705, Avg QP:25.55  kb/s: 498.87
x265 [info]: frame B:    729, Avg QP:28.95  kb/s: 98.52
x265 [info]: Weighted P-Frames: Y:0.9% UV:0.6%
x265 [info]: consecutive B-frames: 58.8% 11.0% 11.4% 6.6% 12.2%

encoded 1440 frames in 25.96s (55.47 fps), 298.86 kb/s, Avg QP:27.26

Skipped File: Live_TV_-_Bloomberg.mp4 Duration: 00:00:36.42 Bit Rate: 315
Skipped File: HVDC Light - ABB 3D.mp4 Duration: 00:03:32.16 Bit Rate: 336

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.Leider ist Ihre aktuellefor /f ... dir .mp4 ...hilft nicht viel, also ersetzen Sie es durch ein einfaches, forum alle.mp4in einer Schleife aufgelistet:

for %%# in (*.mp4)do ....

4.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# ... 

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

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

6.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

7.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

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

Dauer: 00:01:00.08, Beginn: -0.007000, Bitrate: 350 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.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

11.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)]

12.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.

13.Für Dateien mit niedrigeren Bitraten, d.h.falseFälle in derifBefehl haben Sie die Möglichkeit, die Dateien zu speichern, die von derffmpegKonvertierung und werden am Ende des Laufs aufgelistet:

 if %%~j GTR 349 (
      case true
      ffmpeg transcode file mp4
    ) else (
      case false
      skip this file .mp4
      save the full path name
    )
  • Obs.:3Deriffunktioniert auch in verschiedenen Layouts wie:

    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 (case true && ffmpeg transcode file mp4 ) else (
        case false && skip this file .mp4 && save the full path name )
    if %%~j GTR 349 (case true && ffmpeg transcode file mp4
        )else case false && skip this file .mp4 && save the full path name 

14.Mithilfe der Werte in der%%~f#,%%~iUnd%%~jVariablen, wobei jeweils der Pfad und der vollständige Name der aktuellen Datei, ihre Dauer und ihre Bitrate angegeben sind. Wir können einfach einen Zähler ( set/a "_c+=1+0") hinzufügen und während der Ausführungszeit erhöhen, um nacheinander die Informationen zu den von der Konvertierung ausgeschlossenen Dateien zu erstellen/definieren:

)else set/a "_c+=1+0" && <con: call set "_skp_!_c!=Skipped File: %%~nx# Duration: %%~i Bit Rate: %%~j"

%%~f# == Live_TV_-_Bloomberg.mp4
%%~i  == 00:00:36.42
%%~j  == 315

set "_c+=1+0" && call set "_skp_1=Skipped File: Live_TV_-_Bloomberg.mp4 Duration: 00:00:36.42 Bit Rate: 315"

15.Der set-Befehl kann auch für Variablen- und Wertelisten verwendet werden. Mit einemset user, alle Variablen mit definiertenuser+(strings)wird wie folgt aufgelistet:

>set USER
USERDOMAIN=LAME_SLUG
USERDOMAIN_ROAMINGPROFILE=LAME_SLUG
USERNAME=ecker
USERPROFILE=C:\Users\ecker

16.In der letzten Zeile, in der wir einefor /fSchleife, sie wird verwendet, um jede Variable mit dem Namen zu wiederholen_skip_*, die durch das Speichern der Dateien definiert wurde, die während der Ausführung ignoriert wurden, und diese Schleife nimmt alles, was nach dem Zeichen von kommt=(2./tokens^=2):

for /f tokens^=2^delims^=^= ... set _skp_1 .... echo\%%~i
 _skp_1=Skipped File: Live_TV_-_Bloomberg.mp4 Duration: 00:00:36.42 Bit Rate: 315
       
tokens^=2Skipped File: Live_TV_-_Bloomberg.mp4 Duration: 00:00:36.42 Bit Rate: 315
echo;& (for /f tokens^=2^delims^=^= %%i in ('set _skp_')do echo\%%~i)...

17.Der zweite und letzte Teil des letzten in der Bat-Datei lässt die Schleife auftreten (isoliert) und erst nach der Auflistung aller übersprungenen Dateien wird eine Pause/ein unbegrenztes Timeout eingelegt, während auf das Drücken einer Taste gewartet wird. Auf diese Weise wird das Setlocal geschlossen/abgeschlossen und die Ausführung beendet:

1st part: (for /f .....)
2nd part: %__APPDIR__%timeout.exe -1 & endlocal 

echo; & (for /f tokens^=2^delims^=^= %%i in ('set _skp_')do echo\%%~i) & %__APPDIR__%timeout.exe -1 & endlocal

18.Um eine mögliche Fehlermeldung zu vermeiden (Environment variable _skip_ not defined), in Fällen, in denen keine Datei von ignoriert wurde if, fügen Sie einfach hinzu2^>nulIn'set _skip_*2^>nul', innerhalb der letzten Schleifefor:

(for /f tokens^=2^delims^=^= %%i in ('set _skp_ 2^>nul')do echo\%%~i)do...
  • Obs.4Hier dasecho;dient nur zum Erstellen einer separatistischen Zeile, bevor die übersprungenen Dateien aufgelistet werden.


  • Derselbe Code im konventionellen/didaktischen Layout:
@echo off 

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"

for %%# in (*.mp4) do (

     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 (
         
         if %%~j gtr 3200 (
         
             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" 
             
           ) else (
             
             set /a "_c+=1+0"
             set "_skp_!_c!=Skipped File: %%~nx# Duration: %%~i Bit Rate: %%~j"
                 
           )
      )
    
  )

echo.
for /f "tokens=2 delims==" %%i in ('2^>nul set _skp_')do echo\%%~i

%__APPDIR__%timeout.exe -1 
endlocal

verwandte Informationen