Wie konvertiert man ein ganzes Verzeichnis mit ffmpeg?


187

Wie konvertiert man ein ganzes Verzeichnis / Ordner mit ffmpeg über die Kommandozeile oder mit einem Batch-Skript?

Antworten:


172

Bei der vorherigen Antwort wird nur eine Ausgabedatei mit dem Namen out.mov erstellt. Versuchen Sie dies, um für jeden alten Film eine separate Ausgabedatei zu erstellen.

for i in *.avi;
  do name=`echo "$i" | cut -d'.' -f1`
  echo "$name"
  ffmpeg -i "$i" "${name}.mov"
done

24
Wenn Sie wie ich sind und viele Leerzeichen (und einige andere problematische Zeichen) in Ihren Dateinamen haben, würde ich vorschlagen, doppelte Anführungszeichen hinzuzufügen: ffmpeg -i "$ i" "$ name.mov";
Pif

7
Ich bekomme den Fehleri was unexpected at this time.
Keavon

5
do name=`echo "${i%.*}"`;arbeitet mit Dateinamen mit Punkten (und Leerzeichen).
Nepoxx

8
Wow, diese Antwort ist unglaublich überkompliziert. Siehe eine der einzeiligen Antworten.
Foobarbecue

2
ist diese Unterstützung für .batin Windows?
Jazuly

289

Unter Linux und MacOS kann dies in einer Zeile erfolgen, indem die Dateinamenerweiterung der Ausgabedatei mithilfe der Parametererweiterung geändert wird:

for i in *.avi; do ffmpeg -i "$i" "${i%.*}.mp4"; done

1
Das ist perfekt, danke! Hier ist der vollständige Befehl, der für mich großartig funktioniert hat: für i in * .avi; do ffmpeg -i "$ i" -c: aac -b: a 128k -c: v libx264 -crf 20 "$ {i% .avi} .mp4"; fertig
Phil Kulak

1
@Junaid 1) Stellen Sie sicher, dass Sie einen anderen Namen für die Ausgabedatei als die Eingabe oder Ausgabe in ein anderes Verzeichnis verwenden, da ffmpegkeine Eingabe und Ausgabe in dieselbe Datei möglich ist. 2) Ich bin nicht sicher, ob Bash-Befehle unter Windows 10 nativ funktionieren. Vielleicht sollte ich der Antwort hinzufügen, dass sie sich an Systeme richtet, die Bash nativ verwenden können, wie Linux und MacOS. lxs gab eine Windows-Antwort auf diese Frage.
Llogan

3
Tolle Antwort. Funktioniert auch mit Dateinamen mit Leerzeichen!
wisbucky

1
Dies sollte die beste Antwort sein. Zugegeben, die Erklärung, warum {$ i%. *} Nicht einfach ist, aber wenn Sie das beiseite legen und es einfach "verwenden" können, können Sie es schnell anpassen. Zum Beispiel habe ich Hunderte von MP4-Dateien (mit Dateinamen mit Leerzeichen und Sonderzeichen) in ein kleineres Format konvertiert, indem ich Folgendes verwendet habe: for i in MP4; do ffmpeg -i "$ i" -s 512x288 -c: eine Kopie "$ {i%. } .m4v"; fertig
Tony M

1
Um noch einen Schritt weiter zu gehen, können Sie die Bash-Parametersubstitution verwenden, wenn Sie die Zeichenfolge "x265" durch "x264" ersetzen möchten, wenn Sie von H.265 nach H.264 transkodieren. Dies ist ein häufiger Anwendungsfall. for f in *.mkv; do ffmpeg -i "$f" -map 0 -movflags faststart -c:v libx264 -c:a copy -c:s copy "${f/x265/x264}"; done
Travis Runyard

68

Und unter Windows:

FOR /F "tokens=*" %G IN ('dir /b *.flac') DO ffmpeg -i "%G" -acodec mp3 "%~nG.mp3"

19
Wenn Sie diesen Befehl in einer Batch-Datei (.bat) ausführen, müssen Sie die% -Zeichen verdoppeln => %%
hB0

Haben Sie eine Idee, wie Sie diesen Befehl ausführen, aber in eine neue Datei kopieren können, die die Metadaten der Originaldatei enthält?
Barryman9000

@ Barryman9000 das ist lange her, aber ich denke, es gibt eine Ausgabedatei-Option, die Sie übergeben könnten
lxs

@lxs danke für das Follow-up. Am
Barryman9000

Wird zum Entfernen von Metadaten verwendet. Aber es gibt mir Zugriff verweigert Fehler. Also habe ich den Namen der Ausgabedatei mit einem zusätzlichen Leerzeichen geändert, um daraus eine neue Datei zu machen. FOR /F "tokens=*" %G IN ('dir /b *.mp3') DO ffmpeg -i "%G" -map_metadata -1 -c:v copy -c:a copy "%~nG .mp3"
Junaid

28

Ein einzeiliges Bash-Skript wäre einfach zu erstellen - durch *.aviIhren Dateityp ersetzen :

for i in *.avi; do ffmpeg -i "$i" -qscale 0 "$(basename "$i" .avi)".mov  ; done

Der Standard-Encoder für .mov ist libx264 (falls verfügbar), dieser Encoder wird jedoch ignoriert -qscale. Entfernen Sie es und verwenden Sie die Standardeinstellungen oder verwenden Sie -crfstattdessen (Standard ist -crf 23).
Llogan

1
Wenn der Dateiname Leerzeichen enthält, basenameschlägt der Befehl fehl, da die Backshick- Unterschale nicht in Anführungszeichen gesetzt wird. Genau aus diesem Grund hat bash stattdessen eine Shell-Erweiterung: für i in * .avi; do ffmpeg -i "$ i" -qscale 0 "$ (Basisname" $ ​​i ".avi)". mov; fertig
Calimo

danke @Calimo stimme voll und ganz zu - ich habe meine Antwort aktualisiert
Eigelb

22

Verwenden Sie zum Konvertieren mit Unterverzeichnissen z

find . -exec ffmpeg -i {} {}.mp3 \;

Ich habe dies in Kombination mit dieser Antwort verwendet , um VTT in SRT umzuwandeln, mit großer Wirkung. find -name "*.vtt" -exec ffmpeg -i {} {}.srt \;
Grooveplex

Ich diesen Befehl, mit leichten Modifikationen, um alle mp4 in mp3 zu konvertieren:find *.mp4 -exec ffmpeg -i {} {}.mp3 \;
swdev

1
Oder wenn Sie mehrere Dateitypen konvertieren möchten:find . -name *.ogg -or -name *.wma -exec ffmpeg -i {} {}.mp3 \;
Bonh

Konvertieren Sie alle WMA-Dateien in MP3 und löschen Sie sie anschließend:find . -name *.wma -exec ffmpeg -i {} {}.mp3 \; -exec rm {} \;
Panagiotis

20

Für Windows:

Hier konvertiere ich alle (.mp4) Dateien in (.mp3) Dateien.
Öffnen Sie einfach cmd, gehen Sie zum gewünschten Ordner und geben Sie den Befehl ein.

Verknüpfung: (optional)
1. Wechseln Sie zu dem Ordner, in dem sich Ihre (.mp4) -Dateien befinden.
2. Drücken Sie die Umschalttaste und klicken Sie mit der linken Maustaste und wählen Sie "PowerShell-Fenster hier
öffnen " oder "Eingabeaufforderungsfenster hier öffnen".
3. Geben Sie "cmd" ein [HINWEIS : Überspringen Sie diesen Schritt, wenn cmd anstelle von PowerShell direkt geöffnet wird.]
4. Führen Sie den Befehl aus

for %i in (*.mp4) do ffmpeg -i "%i" "%~ni.mp3"

Wenn Sie dies unter Windows 10 in eine Batchdatei einfügen möchten, müssen Sie %% i verwenden.


17

Für alle, die etwas mit ffmpeg stapelweise konvertieren möchten, aber eine praktische Windows-Oberfläche wünschen, habe ich dieses Front-End entwickelt:

https://sourceforge.net/projects/ffmpeg-batch

Es fügt ffmpeg eine Fenstermode-Oberfläche, Fortschrittsbalken und verbleibende Informationen hinzu, Funktionen, die ich bei der Verwendung von ffmpeg immer vermisst habe.


Ok das ist ein schönes Projekt! Ich habe eine Stunde lang meinen Schwanz gejagt und versucht, ffmpeg dazu zu bringen, einen relativen Outfile-Pfad in Windows zu akzeptieren, und das macht es wie Betrug. EDIT: Ich habe dies verwendet, um .xwm in .flac zu konvertieren
semtex41

6

Wenn Sie GNU parallel haben, können Sie alle .avi-Dateien unten vid_dirparallel in mp4 konvertieren , wobei Sie alle außer einem Ihrer CPU-Kerne mit verwenden

find vid_dir -type f -name '*.avi' -not -empty -print0 |
    parallel -0 -j -1 ffmpeg -loglevel fatal -i {} {.}.mp4

Um von / in verschiedene Formate zu konvertieren, ändern Sie '*.avi'oder .mp4nach Bedarf. GNU parallel ist in den Repositorys der meisten Linux-Distributionen in einem Paket aufgeführt, das normalerweise aufgerufen wird parallel.


Könnten Sie nicht das Gleiche tun, indem Sie !am Ende eines der Bash-Einzeiler hinzufügen ?
Stib

3

Ich weiß, dass dies möglicherweise redundant ist, aber ich verwende dieses Skript, um Dateien stapelweise zu konvertieren.

old_extension=$1
new_extension=$2

for i in *."$old_extension";
  do ffmpeg -i "$i" "${i%.*}.$new_extension";
done

Es sind zwei Argumente erforderlich, um es flexibler zu machen:

  1. die Erweiterung, von der Sie konvertieren möchten
  2. die neue Erweiterung, in die Sie konvertieren möchten

Ich erstelle einen Alias ​​dafür, aber Sie können ihn auch manuell wie folgt verwenden:

sh batch_convert.sh mkv mp4

Dies würde alle mkvDateien in mp4Dateien konvertieren .

Wie Sie sehen können, ist es etwas vielseitiger. Solange ffmpeges konvertiert werden kann, können Sie zwei beliebige Erweiterungen angeben.


Das ist das Beste 👍
Andreas Prang

3

Hier ein bisschen wie Code Golf, aber da fast alle Antworten bisher Bash sind (abgesehen von einem einsamen cmd), ist hier ein plattformübergreifender Windows - Befehl, der Powershell verwendet (weil fantastisch):

ls *.avi|%{ ffmpeg -i $_ <ffmpeg options here> $_.name.replace($_.extension, ".mp4")}

Sie können * .avi so ändern, dass es zu Ihrem Quellmaterial passt.


2
for i in *.flac;
  do name=`echo "${i%.*}"`;
  echo $name;
  ffmpeg -i "${i}" -ab 320k -map_metadata 0 -id3v2_version 3 "${name}".mp3;
done

Batch-Prozessdateien flacin mp3(sicher für Dateinamen mit Leerzeichen) mit [1] [2]


2

Fenster:

@echo off
for /r %%d in (*.wav) do (
    ffmpeg -i "%%~nd%%~xd" -codec:a libmp3lame -c:v copy -qscale:a 2 "%

%~nd.2.mp3"
)

Dies ist eine variable Bitrate der Qualität 2, Sie können sie auf 0 setzen, wenn Sie möchten, aber wenn Sie kein wirklich gutes Lautsprechersystem haben, ist es imo wertlos


2

Natürlich ist jetzt PowerShell hinzugekommen, das speziell dafür entwickelt wurde, so etwas extrem einfach zu machen.

Und ja, PowerShell ist auch auf anderen Betriebssystemen als nur Windows verfügbar , ist jedoch unter Windows vorinstalliert, sodass dies für alle nützlich sein sollte.

Zunächst möchten Sie alle Dateien im aktuellen Verzeichnis auflisten. Beginnen wir also mit:

ls

Sie können auch verwenden, ls -Recursewenn Sie alle Dateien in Unterverzeichnissen rekursiv konvertieren möchten.

Dann filtern wir diese nur nach dem Dateityp, den wir konvertieren möchten - z. B. "avi".

ls | Where { $_.Extension -eq ".avi" }

Danach geben wir diese Informationen über a an FFmpeg weiter ForEach.

Für die Eingabe von FFmpeg verwenden wir das FullName- das ist der gesamte Pfad zur Datei. Und für die Ausgabe von FFmpeg werden wir das verwenden Name- aber das am Ende durch ersetzen . Es wird also ungefähr so ​​aussehen:.avi.mp3

$_.Name.Replace(".avi", ".mp3")

Lassen Sie uns das alles zusammenfassen und das ist das Ergebnis:

ls | Where { $_.Extension -eq ".avi" } | ForEach { ffmpeg -i $_.FullName $_.Name.Replace(".avi", ".mp3") }

Dadurch werden alle ".avi" -Dateien über FFmpeg in ".mp3" -Dateien konvertiert. Ersetzen Sie einfach die drei Punkte in Anführungszeichen, um zu entscheiden, welche Art von Konvertierung Sie möchten, und fügen Sie FFmpeg innerhalb von Dateien weitere Argumente hinzu ForEach.

Sie können noch einen Schritt weiter gehen und Remove-Itemam Ende hinzufügen , um die alten Dateien automatisch zu löschen.

Wenn ffmpeges sich nicht in Ihrem Pfad befindet und sich tatsächlich in dem Verzeichnis befindet, in dem Sie sich gerade befinden, schreiben Sie ./ffmpegdort statt nur ffmpeg.

Hoffe das hilft jedem.


1
PowerShell ist großartig, danke! Falls jemand anderes Probleme beim Ausführen hat: Fügen Sie diesen Befehl in eine .ps1Datei ein, nicht in eine .batDatei. Sie müssen Set-ExecutionPolicy RemoteSignedals Administrator ausgeführt werden, wenn Sie noch nie zuvor ein PS-Skript ausgeführt haben.
Starpause

Im Allgemeinen habe ich nur darüber nachgedacht, es direkt in PowerShell auszuführen, also habe ich nicht wirklich daran gedacht! Guter Tipp!
ABPerson

1

Wenn Sie möchten, dass eine grafische Oberfläche mit ffmpegX stapelweise verarbeitet wird, versuchen Sie es mit Quick Batcher . Es ist kostenlos und verwendet Ihre letzten ffmpegX-Einstellungen, um Dateien zu konvertieren, die Sie darin ablegen.

Beachten Sie, dass Sie keine Ordner per Drag & Drop auf Quick Batcher ziehen können. Wählen Sie also Dateien aus und stellen Sie sie dann in Quick Batcher.


2
Die "Quick Batcher" -Software ist NUR für MAC OS
Mohammad ElNesr

1

Nur dieser hat für mich funktioniert. Bitte beachten Sie, dass Sie den Ordner "newfiles" manuell erstellen müssen, in dem sich die Datei ffmpeg.exe befindet.

Konvertieren . Dateien zu .wav Audio Code:

for %%a in ("*.*") do ffmpeg.exe -i "%%a" "newfiles\%%~na.wav"
pause

dh wenn Sie alle .mp3-Dateien in .wav konvertieren möchten, ändern Sie ("*.*")in ("*.mp3").

Der Autor dieses Skripts ist:

https://forum.videohelp.com/threads/356314-How-to-batch-convert-multiplex-any-files-with-ffmpeg

hoffe es hat geholfen 🙏.


0

Dadurch wird ein MP3-Video aus allen JPG-Dateien aus dem aktuellen Verzeichnis erstellt.

echo exec("ffmpeg -framerate 1/5 -i photo%d.jpg -r 25 -pix_fmt yuv420p output.mp4");

0

Und für Windows funktioniert dies nicht

FOR /F "tokens=*" %G IN ('dir /b *.flac') DO ffmpeg -i "%G" -acodec mp3 "%~nG.mp3"

selbst wenn ich das verdopple %.

Ich würde sogar vorschlagen:

-acodec ***libmp3lame***

ebenfalls:

FOR /F "tokens=*" %G IN ('dir /b *.flac') DO ffmpeg -i "%G" -acodec libmp3lame "%~nG.mp3"

Ist dies eine Antwort oder ein Versuch, eine neue Frage als Antwort zu veröffentlichen? Im letzteren Fall erstellen Sie stattdessen eine völlig neue Frage, obwohl Sie möglicherweise hier als Hintergrund verlinken.
Tripleee

0

Dies ist, was ich verwende, um AVI stapelweise in 1280x mp4 zu konvertieren

FOR /F "tokens=*" %%G IN ('dir /b *.avi') DO "D:\Downloads\ffmpeg.exe" -hide_banner -i "%%G" -threads 8 -acodec mp3 -b:a 128k -ac 2 -strict -2 -c:v libx264 -crf 23 -filter:v "scale=1280:-2,unsharp=5:5:1.0:5:5:0.0" -sws_flags lanczos -b:v 1024k -profile:v main -preset medium -tune film -async 1 -vsync 1 "%%~nG.mp4"

Funktioniert gut als Cmd-Datei, führen Sie es aus, die Schleife findet alle AVI-Dateien in diesem Ordner.

ruft MY (für Sie ändern) ffmpeg auf, übergibt den Eingabenamen, die Einstellungen dienen zum erneuten Skalieren mit Schärfen. Ich probs brauche kein CNI und " -b:v 1024k" ...

Die Ausgabedatei ist die Eingabedatei abzüglich der Erweiterung, wobei mp4 als neue ext.


0

Ich verwende diesen Einzeiler unter Linux, um Dateien (normalerweise H265) in etwas zu konvertieren, das ich ohne Probleme auf Kodi abspielen kann:

for f in *.mkv; do ffmpeg -i "$f" -c:v libx264 -crf 28 -c:a aac -b:a 128k output.mkv; mv -f output.mkv "$f"; done

Dies wird in eine temporäre Datei konvertiert und ersetzt dann das Original, sodass die Namen nach der Konvertierung gleich bleiben.


0

Auch wenn Sie die gleiche Konvertierung in Unterordnern wünschen. Hier ist der rekursive Code.

for /R "folder_path" %%f in (*.mov,*.mxf,*.mkv,*.webm) do (
    ffmpeg.exe -i "%%~f" "%%~f.mp4"
    )

-1

kleines PHP-Skript dafür:

#!/usr/bin/env php
<?php
declare(strict_types = 1);
if ($argc !== 2) {
    fprintf ( STDERR, "usage: %s dir\n", $argv [0] );
    die ( 1 );
}
$dir = rtrim ( $argv [1], DIRECTORY_SEPARATOR );
if (! is_readable ( $dir )) {
    fprintf ( STDERR, "supplied path is not readable! (try running as an administrator?)" );
    die(1);
}
if (! is_dir ( $dir )) {
    fprintf ( STDERR, "supplied path is not a directory!" );
    die(1);
}
$files = glob ( $dir . DIRECTORY_SEPARATOR . '*.avi' );
foreach ( $files as $file ) {
    system ( "ffmpeg -i " . escapeshellarg ( $file ) . ' ' . escapeshellarg ( $file . '.mp4' ) );
}

2
Eine sehr eingeschränkte Antwort, da ein Benutzer PHP auf seinem Computer installiert haben muss. Die Antworten auf Befehlszeilen- und Batchdateien sind viel einfacher und weniger komplex.
ProfK

2
@ProfK PHP ist eine der beliebtesten Sprachen in SO - zweitens ist Isaacs Antwort für sh etwas unzuverlässig, da es Ihre Dateien möglicherweise in etwas anderes als das Original umbenennt, z. B. keine Zeilenumbrüche im Dateinamen beibehält. Das Fledermaus-Skript von lyx ist noch schlimmer, es ignoriert VOLLSTÄNDIG jede Datei mit Zeilenumbrüchen im Namen. Ich weiß nicht warum, nicht einmal ein Syntaxfehler oder so, aber es tut es (getestet auf win10). Mein PHP-Skript hat dank keine Probleme escapeshellarg()und funktioniert sowohl unter Windows als auch unter Linux. Ich bin damit einverstanden, dass es ein Randfall ist.
Hanshenrik

-1

Eine andere einfache Lösung, die noch nicht vorgeschlagen wurde, wäre xargs:

ls *.avi | xargs -i -n1 ffmpeg -i {} "{}.mp4"

Eine kleine Gefahr ist die umständliche Benennung von Ausgabedateien (z input.avi.mp4. B. ). Eine mögliche Problemumgehung hierfür könnte sein:

ls *.avi | xargs -i -n1 bash -c "i={}; ffmpeg -i {} "\${i%.*}.mp4"""


shellcheck.net hat einige Vorschläge zu Ihren Beispielen.
Llogan

mywiki.wooledge.org/ParsingLs obwohl Sie können einfach ersetzen lsmit printf '%s\n'hier.
Tripleee
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.