Come si converte un'intera directory con ffmpeg?


191

Come si converte un'intera directory / cartella con ffmpeg tramite riga di comando o con uno script batch?

Risposte:


175

La risposta precedente creerà solo 1 file di output chiamato out.mov. Per creare un file di output separato per ogni vecchio film, prova questo.

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

24
Se sei come me e hai molti spazi (e alcuni altri caratteri problematici) nei nomi dei tuoi file, suggerirei di aggiungere doppie virgolette: ffmpeg -i "$ i" "$ name.mov";
Pif,

7
Ricevo l'errorei was unexpected at this time.
Keavon

5
do name=`echo "${i%.*}"`;lavorerà sui nomi dei file con punti (e spazi) al loro interno.
Nepoxx,

8
Caspita, questa risposta è incredibilmente complicata. Vedi una delle risposte a una riga.
Foobaremade,

2
è questo supporto per .batin Windows?
Jazuly,

294

Per Linux e macOS questo può essere fatto in una riga, usando l' espansione dei parametri per cambiare l'estensione del file di output:

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

2
Questo è perfetto, grazie! Ecco il comando completo che ha funzionato alla grande per me: per me in * .avi; ffmpeg -i "$ i" -c: a aac -b: a 128k -c: v libx264 -crf 20 "$ {i% .avi} .mp4"; fatto
Phil Kulak il

1
@Junaid 1) Assicurati di utilizzare un nome diverso per il file di output rispetto all'input o l'output in un'altra directory, perché ffmpegnon è possibile immettere e output sullo stesso file. 2) Non sono sicuro che i comandi Bash funzionino in modo nativo su Windows 10. Forse dovrei aggiungere alla risposta che è indirizzato a sistemi che possono usare nativamente Bash come Linux e macOS. lxs ha fornito una risposta di Windows per questa domanda.
Llogan,

4
Risposta fantastica. Funziona anche con nomi di file con spazi!
Wisbucky

1
Questa dovrebbe essere la risposta migliore. Certo, la spiegazione del perché {$ i%. *} Non è semplice, ma se puoi metterlo da parte e semplicemente "usarlo" puoi modificarlo rapidamente per adattarlo. Ad esempio, ho convertito centinaia di .mp4 (con nomi di file con spazi e caratteri speciali) in un formato più piccolo usando: for i in .mp4; do ffmpeg -i "$ i" -s 512x288 -c: una copia "$ {i%. } .m4v"; fatto
Tony M,

1
Per fare un ulteriore passo in avanti, è possibile utilizzare la sostituzione dei parametri Bash se si desidera sostituire la stringa "x265" con "x264" se si esegue la transcodifica da H.265 a H.264, che è un caso d'uso comune. 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,

70

E su Windows:

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

19
se si esegue questo comando in un file batch (.bat) è necessario raddoppiare i segni% = = %%
hB0

Qualche idea su come eseguire questo comando ma copiarlo in un nuovo file che includa i metadati del file originale?
Barryman9000,

@ Barryman9000 questo era tanto tempo fa, ma penso che ci sia un'opzione per il file di output che potresti passare
lxs

@lxs grazie per il follow-up. Ho finito per fare con PowerShell, cambiando il nome del nuovo file di essere il file originale la data di creazione stackoverflow.com/a/35671099/197472
Barryman9000

Usato per la rimozione di metadati. Ma mi sta dando l'errore Accesso negato. Quindi ho cambiato il nome del file di output con uno spazio extra per renderlo nuovo file. 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

Uno script bash di una riga sarebbe facile da fare - sostituire *.avicon il tipo di file:

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

Il codificatore predefinito per .mov è libx264 (se disponibile), ma questo codificatore ignora -qscale. Rimuoverlo e utilizzare le impostazioni predefinite o utilizzare -crfinvece (impostazione predefinita è -crf 23).
Llogan,

1
Se ci sono spazi nel nome del file, il comando fallirà perché la sotthell con basenamebacktick non è quotata. Questo è esattamente il motivo per cui bash ha invece l'espansione della shell: per i in * .avi; do ffmpeg -i "$ i" -qscale 0 "$ (basename" $ ​​i ".avi)". mov; fatto
Calimo,

grazie @Calimo sono totalmente d'accordo - ho aggiornato la mia risposta
tuorlo

22

Per convertire con le sottodirectory utilizzare ad es

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

Ho usato questo, combinato con questa risposta per convertire VTT in SRT, con grande efficacia. find -name "*.vtt" -exec ffmpeg -i {} {}.srt \;
grooveplex,

Ho questo comando, con una leggera modifica per convertire tutto in mp4 in mp3:find *.mp4 -exec ffmpeg -i {} {}.mp3 \;
swdev,

1
Oppure, se si desidera convertire più tipi di file:find . -name *.ogg -or -name *.wma -exec ffmpeg -i {} {}.mp3 \;
bonh,

Converti tutti i file wma in mp3 e dopo eliminali:find . -name *.wma -exec ffmpeg -i {} {}.mp3 \; -exec rm {} \;
Panagiotis

20

Per Windows:

Qui sto convertendo tutti i file (.mp4) in file (.mp3).
Apri cmd, vai alla cartella desiderata e digita il comando.

Scorciatoia: (facoltativo)
1. Andare alla cartella in cui sono presenti i file (.mp4)
2. Premere Maiusc e fare clic con il pulsante sinistro del mouse e scegliere "Apri finestra PowerShell qui"
o "Apri finestra prompt dei comandi qui"
3. Digitare "cmd" [NOTA : Saltare questo passaggio se apre direttamente cmd anziché PowerShell]
4. Eseguire il comando

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

Se vuoi metterlo in un file batch su Windows 10, devi usare %% i.


18

Per chiunque voglia convertire in batch qualsiasi cosa con ffmpeg ma vorrebbe avere una comoda interfaccia di Windows, ho sviluppato questo front-end:

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

Aggiunge a ffmpeg un'interfaccia di moda per finestre, barre di avanzamento e informazioni sul tempo rimanente, caratteristiche che mi mancavano sempre quando si utilizzava ffmpeg.


Ok, questo è un bel progetto! Ho inseguito la mia coda per un'ora cercando di convincere ffmpeg ad accettare un percorso di file relativo in Windows e questo mi fa sembrare barare. EDIT: l'ho usato per convertire .xwm in .flac
semtex41 il

6

Se hai GNU parallelo, puoi convertire tutti i file .avi sottostanti vid_dirin mp4 in parallelo, usando tutti tranne uno dei tuoi core CPU con

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

Per convertire da / in diversi formati, modificare '*.avi'o .mp4secondo necessità. Il parallelo GNU è elencato nella maggior parte dei repository di distribuzioni Linux in un pacchetto che di solito viene chiamato parallel.


non potresti fare lo stesso aggiungendo !alla fine di una delle battute bash?
Stib

3

So che potrebbe essere ridondante, ma uso questo script per convertire in batch i file.

old_extension=$1
new_extension=$2

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

Sono necessari 2 argomenti per renderlo più flessibile:

  1. l'estensione da cui vuoi convertire
  2. la nuova estensione in cui vuoi convertire

Creo un alias per questo ma puoi anche usarlo manualmente in questo modo:

sh batch_convert.sh mkv mp4

Ciò convertirà tutti i mkvfile in mp4file.

Come puoi vedere leggermente più versatile. Finché è ffmpegpossibile convertirlo, è possibile specificare due estensioni.


Questo è il migliore 👍
Andreas Prang,

3

Ottenere un po 'come il golf del codice qui, ma poiché quasi tutte le risposte finora sono bash (escluso uno solo cmd uno), ecco un comando multipiattaforma di Windows che utilizza PowerShell (perché fantastico):

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

Puoi cambiare * .avi in ​​qualsiasi corrispondenza con il filmato sorgente.


3

Naturalmente, ora PowerShell è arrivato, progettato appositamente per rendere qualcosa di esattamente così estremamente facile.

E, sì, PowerShell è disponibile anche su altri sistemi operativi diversi da Windows, ma è preinstallato su Windows, quindi questo dovrebbe essere utile a tutti.

Innanzitutto, ti consigliamo di elencare tutti i file nella directory corrente, quindi inizieremo con:

ls

Puoi anche usarlo ls -Recursese vuoi convertire ricorsivamente anche tutti i file nelle sottodirectory.

Quindi, filtreremo quelli fino al solo tipo di file che vogliamo convertire, ad esempio "avi".

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

Successivamente, passeremo tali informazioni a FFmpeg tramite a ForEach.

Per l'input di FFmpeg, useremo il FullName- questo è l'intero percorso del file. E per l'output di FFmpeg useremo il Name- ma sostituendo il .avialla fine con .mp3. Quindi, sarà simile a questo:

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

Quindi, mettiamo tutto insieme e questo è il risultato:

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

Che convertirà tutti i file ".avi" in file ".mp3" tramite FFmpeg, basta sostituire le tre cose tra virgolette per decidere quale tipo di conversione desideri e sentirti libero di aggiungere qualsiasi altro argomento a FFmpeg all'interno di ForEach.

Puoi fare un ulteriore passo avanti e aggiungere Remove-Itemalla fine per eliminare automaticamente i vecchi file.

Se ffmpegnon è nel tuo percorso, ed è effettivamente nella directory in cui ti trovi attualmente, scrivi ./ffmpeglì invece che semplicemente ffmpeg.

Spero che questo aiuti chiunque.


1
PowerShell è fantastico, grazie! Nel caso in cui qualcun altro incontri problemi durante l'esecuzione di questo: inserisci questo comando in un .ps1file, non in un .batfile. Dovrai eseguire Set-ExecutionPolicy RemoteSignedcome amministratore se non hai mai eseguito uno script PS prima.
Starpause

Bene, in genere ho solo pensato di eseguirlo direttamente in PowerShell, quindi non ci ho pensato! Un buon consiglio però!
ABPerson

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

flacFile di processo batch in mp3(sicuro per i nomi di file con spazi) utilizzando [1] [2]


2

finestre:

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

%~nd.2.mp3"
)

questo è un bitrate variabile di qualità 2, puoi impostarlo su 0 se vuoi, ma a meno che tu non abbia un sistema di altoparlanti davvero buono è inutile imo


1

Se si desidera che un'interfaccia grafica elabori in batch con ffmpegX, provare Quick Batcher . È gratuito e prenderà le tue ultime impostazioni di ffmpegX per convertire i file che ci cadi dentro.

Si noti che non è possibile trascinare le cartelle su Quick Batcher. Quindi seleziona i file e poi inseriscili in Quick Batcher.


2
Il software "Quick Batcher" è SOLO per MAC OS
Mohammad ElNesr

1

Solo questo ha funzionato per me, per favore nota che devi creare manualmente la cartella "newfiles" dove si trova il file ffmpeg.exe.

Converti . file nel codice audio .wav:

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

cioè se vuoi convertire tutti i file .mp3 in .wav cambiare ("*.*")in ("*.mp3").

L'autore di questo script è:

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

spero che abbia aiutato 🙏.


0

Questo creerà video mp4 da tutti i file jpg dalla directory corrente.

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

0

E per Windows, questo non funziona

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

anche se faccio il doppio di quelli %.

Vorrei anche suggerire:

-acodec ***libmp3lame***

anche:

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

È una risposta o un tentativo di pubblicare una nuova domanda come risposta? In quest'ultimo caso, si prega di creare una domanda completamente nuova, sebbene possibilmente rimandando qui per lo sfondo.
Tripleee

0

Questo è quello che uso per convertire in batch avi in ​​1280x mp4

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"

Funziona bene come file cmd, eseguilo, il ciclo trova tutti i file avi in ​​quella cartella.

chiama MY (cambia per il tuo) ffmpeg, passa il nome di input, le impostazioni sono per riscalare con la nitidezza. I probi non hanno bisogno di CRF e " -b:v 1024k" ...

Il file di output è il file di input meno l'estensione, con mp4 come nuovo ext.


0

Sto usando questo one-liner in Linux per convertire i file (di solito H265) in qualcosa che posso giocare su Kodi senza problemi:

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

Questo converte in un file temporaneo e quindi sostituisce l'originale in modo che i nomi rimangano gli stessi dopo la conversione.


0

Anche se vuoi la stessa conversione nelle sottocartelle. ecco il codice ricorsivo.

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

-1

piccolo script php per farlo:

#!/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
Una risposta dell'ambito molto limitata in quanto un utente deve avere PHP installato sul proprio computer. Le risposte alla riga di comando e al file batch sono molto più semplici e molto meno complesse.
ProfK,

2
@ProfK PHP è una delle lingue più popolari su SO - in secondo luogo, la risposta di Isaac per sh è in qualche modo inaffidabile, in quanto potrebbe rinominare i tuoi file in qualcosa di diverso dall'originale, ad esempio, non preserva le nuove righe nel nome del file. Lo script bat di Lyx è anche peggio, IGNORA COMPLETAMENTE qualsiasi file con nuove righe nel nome. non so perché, nemmeno un errore di sintassi o altro, ma lo fa (testato su win10). il mio script php non ha problemi, grazie a escapeshellarg(), e funziona sia su Windows che su Linux. sono d'accordo che è un caso limite però.
Hanshenrik,

-1

Un'altra soluzione semplice che non è stata ancora suggerita sarebbe quella di utilizzare xargs:

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

Un piccolo inconveniente è la scomoda denominazione dei file di output (ad es input.avi.mp4.). Una possibile soluzione al problema potrebbe essere:

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


shellcheck.net ha alcuni suggerimenti per quanto riguarda i tuoi esempi.
Llogan,

mywiki.wooledge.org/ParsingLs anche se puoi semplicemente sostituirlo lscon printf '%s\n'qui.
tripleee,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.