Bagaimana Anda mengonversi seluruh direktori dengan ffmpeg?

191

Bagaimana Anda mengonversi seluruh direktori / folder dengan ffmpeg melalui baris perintah atau dengan skrip batch?

Eugene
sumber

Jawaban:

175

Jawaban sebelumnya hanya akan membuat 1 file output bernama out.mov. Untuk membuat file output terpisah untuk setiap film lama, coba ini.

for i in *.avi;
  do name=`echo "$i" | cut -d'.' -f1`
  echo "$name"
  ffmpeg -i "$i" "${name}.mov"
done
Ishak
sumber
24
Jika Anda seperti saya dan memiliki banyak ruang (dan beberapa karakter bermasalah lainnya) dalam nama file Anda, saya sarankan menambahkan tanda kutip ganda: ffmpeg -i "$ i" "$ name.mov";
Pif
7
Saya mendapatkan kesalahani was unexpected at this time.
Keavon
5
do name=`echo "${i%.*}"`;akan bekerja pada nama file dengan titik (dan spasi) di dalamnya.
Nepoxx
8
Wow, jawaban ini sangat rumit. Lihat salah satu jawaban satu baris.
foobarbecue
2
Apakah dukungan ini ada .batdi windows?
Jazuly
294

Untuk Linux dan macOS ini dapat dilakukan dalam satu baris, menggunakan ekspansi parameter untuk mengubah ekstensi nama file dari file output:

for i in *.avi; do ffmpeg -i "$i" "${i%.*}.mp4"; done
llogan
sumber
2
Ini sempurna, terima kasih! Inilah perintah lengkap yang akhirnya bekerja bagus untuk saya: untuk saya di * .avi; do ffmpeg -i "$ i" -c: aac -b: a 128k -c: v libx264 -crf 20 "$ {i% .avi} .mp4"; selesai
Phil Kulak
1
@ Junaid 1) Pastikan untuk menggunakan nama yang berbeda untuk file output daripada input, atau output ke direktori lain, karena ffmpegtidak dapat menginput dan output ke file yang sama. 2) Saya tidak yakin apakah perintah Bash bekerja pada Windows 10 secara asli. Mungkin saya harus menambahkan jawaban yang ditargetkan ke sistem yang dapat menggunakan Bash seperti Linux dan macOS. lxs memberikan jawaban Windows untuk pertanyaan ini.
Logan
4
Jawaban yang luar biasa. Bekerja dengan nama file dengan spasi juga!
wisbucky
1
Ini harus menjadi jawaban teratas. Memang, penjelasan mengapa {$ i%. *} Tidak sederhana, tetapi jika Anda dapat mengesampingkannya dan hanya "menggunakannya" Anda dapat dengan cepat memodifikasi sesuai. Misalnya, saya mengonversi ratusan .mp4's (dengan nama file memiliki spasi dan karakter khusus) ke format yang lebih kecil menggunakan: for i in .mp4; do ffmpeg -i "$ i" -s 512x288 -c: salinan "$ {i%. } .m4v"; selesai
Tony M
1
Untuk mengambil satu langkah lebih jauh, Anda bisa menggunakan substitusi parameter Bash jika Anda ingin mengganti string "x265" dengan "x264" jika Anda mentranskode dari H.265 ke H.264 yang merupakan kasus penggunaan umum. 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

Dan di Windows:

FOR /F "tokens=*" %G IN ('dir /b *.flac') DO ffmpeg -i "%G" -acodec mp3 "%~nG.mp3"
lxs
sumber
19
jika Anda menjalankan perintah ini dalam file batch (.bat), Anda perlu menggandakan% tanda => %%
hB0
Adakah yang tahu cara menjalankan perintah ini tetapi menyalin ke file baru yang menyertakan metadata file asli?
Barryman9000
@ Barryman9000 ini sudah lama sekali tapi saya pikir ada opsi file output yang bisa Anda lewati
lxs
@ lxs terima kasih atas tindak lanjutnya. Saya akhirnya melakukannya dengan Powershell dengan mengubah nama file baru menjadi tanggal file asli dibuat stackoverflow.com/a/35671099/197472
Barryman9000
Digunakan untuk menghapus metadata. Tetapi itu memberi saya Access ditolak kesalahan. Jadi saya mengubah nama file output dengan ruang ekstra untuk menjadikannya file baru. 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

Script bash satu baris akan mudah dilakukan - ganti *.avidengan tipe file Anda:

for i in *.avi; do ffmpeg -i "$i" -qscale 0 "$(basename "$i" .avi)".mov  ; done
kuning telur
sumber
Encoder default untuk .mov adalah libx264 (jika tersedia), tetapi encoder ini mengabaikannya -qscale. Hapus dan gunakan pengaturan default, atau gunakan -crfsebagai gantinya (standarnya adalah -crf 23).
llogan
1
Jika ada spasi dalam nama file, perintah akan gagal karena subkunci backticked basenametidak dikutip. Inilah sebabnya mengapa bash memiliki ekspansi shell: untuk i in * .avi; do ffmpeg -i "$ i" -qscale 0 "$ (basename" $ ​​i ".avi)". mov; selesai
Calimo
terima kasih @ Calimo sepenuhnya setuju - saya telah memperbarui jawaban saya
kuning
22

Untuk mengkonversi dengan subdirektori, gunakan misalnya

find . -exec ffmpeg -i {} {}.mp3 \;
pengguna2707001
sumber
Saya menggunakan ini, dikombinasikan dengan jawaban ini untuk mengubah VTT ke SRT, sangat efektif. find -name "*.vtt" -exec ffmpeg -i {} {}.srt \;
grooveplex
Saya perintah ini, dengan sedikit modif untuk mengkonversi semua mp4 ke mp3:find *.mp4 -exec ffmpeg -i {} {}.mp3 \;
swdev
1
Atau, jika Anda ingin mengonversi beberapa jenis file:find . -name *.ogg -or -name *.wma -exec ffmpeg -i {} {}.mp3 \;
bonh
Konversikan semua file wma ke mp3 dan setelah menghapusnya:find . -name *.wma -exec ffmpeg -i {} {}.mp3 \; -exec rm {} \;
Panagiotis
20

Untuk Windows:

Di sini saya Konversi semua file (.mp4) menjadi file (.mp3).
Cukup buka cmd, buka folder yang diinginkan dan ketik perintah.

Pintasan: (opsional)
1. Buka folder tempat file (.mp4) Anda ada
2. Tekan Shift dan klik kiri dan Pilih "Buka PowerShell Window Here"
atau "Open Command Prompt Window Here"
3. Ketik "cmd" [CATATAN : Lewati langkah ini jika langsung membuka cmd alih-alih PowerShell]
4. Jalankan perintah

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

Jika Anda ingin memasukkan ini ke file batch pada Windows 10, Anda harus menggunakan %% i.

shubhamr238
sumber
18

Bagi siapa saja yang ingin melakukan batch konversi apa pun dengan ffmpeg tetapi ingin memiliki antarmuka Windows yang nyaman, saya mengembangkan front-end ini:

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

Ini menambah ffmpeg antarmuka mode jendela, bilah kemajuan dan info sisa waktu, fitur yang selalu saya lewatkan saat menggunakan ffmpeg.

Eibel
sumber
Ok ini proyek yang bagus! Saya telah mengejar ekor saya selama satu jam mencoba untuk mendapatkan ffmpeg untuk menerima jalur pengabaian relatif di Windows dan ini membuatnya terasa seperti curang. EDIT: saya menggunakan ini untuk mengkonversi .xwm ke
.flac
6

Jika Anda memiliki GNU parallel, Anda dapat mengonversi semua file .avi di bawah inivid_dir ke mp4 secara paralel, menggunakan semua kecuali salah satu inti CPU Anda dengan

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

Untuk mengonversi dari / ke berbagai format, ubah '*.avi'atau .mp4sesuai kebutuhan. Paralel GNU terdaftar di sebagian besar repositori distribusi Linux dalam sebuah paket yang biasa disebut parallel.

sebbit
sumber
tidak bisakah Anda melakukan hal yang sama dengan menambahkan !ujung bash one-liners?
stib
3

Saya tahu ini mungkin berlebihan tetapi saya menggunakan skrip ini untuk mengonversi file batch.

old_extension=$1
new_extension=$2

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

Dibutuhkan 2 argumen untuk membuatnya lebih fleksibel:

  1. ekstensi yang ingin Anda konversi
  2. ekstensi baru yang ingin Anda konversi

Saya membuat alias untuk itu tetapi Anda juga dapat menggunakannya secara manual seperti ini:

sh batch_convert.sh mkv mp4

Ini akan mengubah semua mkvfile menjadi mp4file.

Seperti yang Anda lihat, itu sedikit lebih fleksibel. Selama ffmpegdapat mengonversinya, Anda dapat menentukan dua ekstensi.

Alexander Luna
sumber
Itu yang terbaik 👍
Andreas Prang
3

Mendapatkan sedikit seperti golf kode di sini, tetapi karena hampir semua jawaban sejauh ini adalah bash (kecuali satu cmd yang kesepian), inilah perintah lintas platform windows yang menggunakan PowerShell (karena mengagumkan):

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

Anda dapat mengubah * .avi menjadi apa pun yang cocok dengan rekaman sumber Anda.

stib
sumber
3

Tentu saja, sekarang PowerShell telah hadir, yang dirancang khusus untuk membuat sesuatu yang persis seperti ini menjadi sangat mudah.

Dan, ya, PowerShell juga tersedia pada sistem operasi lain selain Windows, tetapi sudah diinstal sebelumnya pada Windows, jadi ini harus bermanfaat bagi semua orang.

Pertama, Anda ingin membuat daftar semua file dalam direktori saat ini, jadi, kami akan mulai dengan:

ls

Anda juga dapat menggunakan ls -Recursejika Anda ingin mengonversi semua file dalam subdirektori secara rekursif juga.

Kemudian, kami akan memfilternya hanya ke jenis file yang ingin kami konversi - mis. "Avi".

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

Setelah itu, kami akan meneruskan informasi itu ke FFmpeg melalui a ForEach.

Untuk input FFmpeg, kita akan menggunakan FullName- itulah keseluruhan path ke file. Dan untuk output FFmpeg ini kita akan menggunakan Name- tapi menggantikan yang .avipada akhir dengan .mp3. Jadi, akan terlihat seperti ini:

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

Jadi, mari kita kumpulkan semuanya dan inilah hasilnya:

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

Itu akan mengkonversi semua file ".avi" menjadi file ".mp3" melalui FFmpeg, cukup ganti tiga hal dalam tanda kutip untuk memutuskan jenis konversi yang Anda inginkan, dan jangan ragu untuk menambahkan argumen lain apa pun ke FFmpeg di dalam file ForEach.

Anda dapat mengambil langkah ini lebih jauh dan menambahkan Remove-Itemsampai akhir untuk secara otomatis menghapus file lama.

Jika ffmpegtidak ada di jalur Anda, dan itu sebenarnya di direktori Anda saat ini, menulis di ./ffmpegsana, bukan hanya ffmpeg.

Semoga ini bisa membantu siapa saja.

ABPerson
sumber
1
PowerShell luar biasa, terima kasih! Jika ada orang lain yang mengalami kesulitan menjalankan ini: letakkan perintah ini dalam .ps1file, bukan .batfile. Anda harus menjalankan Set-ExecutionPolicy RemoteSignedsebagai administrator jika Anda belum pernah menjalankan skrip PS sebelumnya.
starpause
Yah, umumnya saya hanya berpikir untuk menjalankannya langsung di PowerShell, jadi saya tidak benar-benar memikirkan itu! Tip yang bagus!
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 proses batch menjadi mp3(aman untuk nama file dengan spasi) menggunakan [1] [2]

César D. Velandia
sumber
2

windows:

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

%~nd.2.mp3"
)

ini adalah bitrate variabel kualitas 2, Anda dapat mengaturnya ke 0 jika Anda mau tetapi kecuali Anda memiliki sistem pengeras suara yang benar-benar bagus, itu tidak berharga.

pengguna151496
sumber
1

Jika Anda ingin antarmuka grafis untuk proses batch dengan ffmpegX, coba Batcher Cepat . Ini gratis dan akan mengambil pengaturan ffmpegX terakhir Anda untuk mengonversi file yang Anda masukkan.

Perhatikan bahwa Anda tidak dapat menyeret folder ke Batcher Cepat. Jadi pilih file dan kemudian letakkan di Quick Batcher.

Nirav Mehta
sumber
2
Perangkat lunak "Quick Batcher" HANYA untuk MAC OS
Mohammad ElNesr
1

Hanya yang ini Berfungsi untuk saya, mohon perhatikan bahwa Anda harus membuat folder "file baru" secara manual di mana file ffmpeg.exe berada.

Konversi . file ke .wav kode audio:

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

yaitu jika Anda ingin mengonversi semua file .mp3 ke .wav, ubah ("*.*")menjadi ("*.mp3").

Penulis skrip ini adalah:

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

harap ini membantu 🙏.

Mehrdad995
sumber
0

Ini akan membuat video mp4 dari semua file jpg dari direktori saat ini.

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

Dan untuk Windows, ini tidak berfungsi

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

bahkan jika saya menggandakannya %.

Saya bahkan akan menyarankan:

-acodec ***libmp3lame***

juga:

FOR /F "tokens=*" %G IN ('dir /b *.flac') DO ffmpeg -i "%G" -acodec libmp3lame "%~nG.mp3"
Halligallator
sumber
Apakah ini jawaban, atau upaya untuk memposting pertanyaan baru sebagai jawaban? Dalam kasus yang terakhir, tolong buat pertanyaan yang sama sekali baru, meskipun mungkin menghubungkan kembali ke sini untuk latar belakang.
tripleee
0

Ini yang saya gunakan untuk mengonversi batch avi ke 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"

Berfungsi dengan baik sebagai file cmd, jalankan, loop menemukan semua file avi di folder itu.

panggilan MY (ubah untuk Anda) ffmpeg, melewati nama input, pengaturan untuk menskalakan dengan penajaman. Saya rasa tidak perlu CRF dan " -b:v 1024k" ...

File output adalah file input minus ekstensi, dengan mp4 sebagai ext baru.

Morphy
sumber
0

Saya menggunakan one-liner ini di linux untuk mengkonversi file (biasanya H265) menjadi sesuatu yang bisa saya mainkan di Kodi tanpa masalah:

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

Ini mengonversi ke file sementara dan kemudian menggantikan yang asli sehingga nama tetap sama setelah konversi.

pengguna1634000
sumber
0

Juga jika Anda ingin konversi yang sama dalam subfolder. di sini adalah kode rekursif.

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

skrip php kecil untuk melakukannya:

#!/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' ) );
}
hanshenrik
sumber
2
Jawaban lingkup yang sangat terbatas karena pengguna harus menginstal PHP pada mesin mereka. Baris perintah dan jawaban file batch jauh lebih mudah, dan jauh lebih kompleks.
ProfK
2
@ProfK PHP adalah salah satu bahasa terpopuler di SO - detik, jawaban Isaac untuk sh agak tidak bisa diandalkan, karena mungkin mengubah nama file Anda menjadi sesuatu yang lain daripada yang asli, misalnya, itu tidak mempertahankan baris baru dalam nama file. skrip kelelawar lyx bahkan lebih buruk, itu SEPENUHNYA file apapun dengan baris baru dalam nama. tidak yakin mengapa, bahkan tidak kesalahan sintaks atau apa pun, tetapi itu (diuji pada win10). skrip php saya tidak memiliki masalah, terima kasih kepada escapeshellarg(), dan berfungsi baik di windows dan linux. Saya setuju dengan kasus tepi.
hanshenrik
-1

Solusi sederhana lain yang belum disarankan adalah menggunakan xargs:

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

Satu perangkap kecil adalah penamaan file output yang canggung (mis input.avi.mp4 ). Solusi yang mungkin untuk ini mungkin:

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

telenachos
sumber
shellcheck.net memiliki beberapa saran mengenai contoh Anda.
Logan
mywiki.wooledge.org/ParsingLs meskipun Anda cukup menggantinya lsdengan di printf '%s\n'sini.
tripleee