Bir dizinin tamamını ffmpeg ile nasıl dönüştürebilirsiniz?


192

Tüm dizini / klasörü ffmpeg ile komut satırı veya toplu komut dosyasıyla nasıl dönüştürürsünüz?

Yanıtlar:


176

Önceki yanıt sadece out.mov adlı 1 çıktı dosyası oluşturur. Her eski film için ayrı bir çıktı dosyası oluşturmak için şunu deneyin.

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

24
Benim gibiyseniz ve dosya adlarınızda çok fazla boşluk (ve birkaç sorunlu karakter) varsa, çift tırnak eklemenizi öneririm: ffmpeg -i "$ i" "$ name.mov";
Pif

7
Hatayı alıyorumi was unexpected at this time.
Keavon

5
do name=`echo "${i%.*}"`;içinde nokta (ve boşluk) bulunan dosya adları üzerinde çalışacaktır.
Nepoxx

8
Vay be, bu cevap inanılmaz derecede karmaşık. Tek satırlık cevaplardan birine bakın.
foobarbecue

2
.batWindows için bu destek nedir?
Temmuz 18 Jazuly

296

For Linux ve MacOS bu kullanarak, tek satırda yapılabilir parametre genişleme çıkış dosyasının dosya adı uzantısını değiştirmek için:

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

3
Bu mükemmel, teşekkürler! İşte benim için harika çalışan tam komut: i. * .Avi için; ffmpeg -i "$ i" -c: aac -b: a 128k -c: v libx264 -crf 20 "$ {i% .avi} .mp4"; tamamlandı
Phil Kulak

1
@Junaid 1) Çıktı dosyası için girişten veya başka bir dizine çıktıdan farklı bir ad kullandığınızdan emin olun, çünkü ffmpegaynı dosyaya giriş ve çıkış yapamazsınız. 2) Bash komutlarının Windows 10'da yerel olarak çalışıp çalışmadığından emin değilim. Belki de Linux ve macOS gibi yerel olarak Bash kullanabilen sistemlere yönelik olduğu cevabını eklemeliyim. lxs bu soru için bir Windows yanıtı sağlamıştır.
llogan

4
Müthiş cevap. Boşluklu dosya adları ile de çalışır!
Wisbucky

1
Bu en iyi cevap olmalı. Kuşkusuz, {$ i%. *} 'İn neden açıklanması basit değildir, ancak bunu bir kenara koyabilir ve sadece "kullanabilirsiniz" olarak uygun şekilde hızlı bir şekilde değiştirebilirsiniz. Örneğin, yüzlerce .mp4 (boşluk ve özel karakterleri olan dosya adları ile) kullanarak daha küçük bir biçime dönüştürdüm: for i in .mp4; ffmpeg -i "$ i" -s 512x288 -c: bir kopya "$ {i%. } .m4v"; bitti
Tony M

1
Bir adım daha ileri gitmek için, yaygın bir kullanım örneği olan H.265'ten H.264'e kod dönüştürüyorsanız, "x265" dizesini "x264" ile değiştirmek isterseniz Bash parametresi ikamesini kullanabilirsiniz. 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

Ve Windows'ta:

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

19
Bu komutu bir toplu iş (.bat) dosyasında çalıştırırsanız,% signs => %%
hB0

Bu komutu çalıştırmak ama orijinal dosyanın meta verilerini içeren yeni bir dosyaya kopyalamak nasıl bir fikrin var mı?
Barryman9000

@ Barryman9000 bu çok uzun zaman önceydi ama geçebileceğiniz bir çıktı dosyası seçeneği olduğunu düşünüyorum
lxs

@lxs takip için teşekkürler. Powershell ile yeni dosyanın adını orijinal dosyanın oluşturulduğu tarih olarak değiştirerek
bitirdim

Meta verileri kaldırmak için kullanılır. Ama bana Access reddedildi hatası veriyor. Böylece çıktı dosyası adını yeni bir dosya yapmak için fazladan bir boşlukla değiştirdim. 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

Tek satırlık bir bash betiği yapmak kolay olurdu - *.avidosya türünüzle değiştirin :

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

.Mov için varsayılan kodlayıcı libx264'tür (varsa), ancak bu kodlayıcı yok sayar -qscale. Kaldırın ve varsayılan ayarları kullanın veya -crfbunun yerine kullanın (varsayılan değer -crf 23).
llogan

1
Dosya adında boşluk varsa, geri bağlanan basenamealt kabuk alıntılanmadığı için komut başarısız olur . Tam da bu yüzden bash'ın kabuk genişlemesi var: i in * .avi; do ffmpeg -i "$ i" -qscale 0 "$ (taban adı" $ i ".avi)". mov; bitti
Calimo

Teşekkürler @Calimo tamamen katılıyorum - cevabımı güncelledim
yolk

23

Alt dizinlerle dönüştürmek için örn.

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

Bunu VTT'yi SRT'ye dönüştürmek için bu cevapla birlikte kullandım . find -name "*.vtt" -exec ffmpeg -i {} {}.srt \;
grooveplex

Ben bu komutu, tüm MP4 mp3 dönüştürmek için hafif modif ile:find *.mp4 -exec ffmpeg -i {} {}.mp3 \;
swdev

1
Veya, birden fazla dosya türünü dönüştürmek istiyorsanız:find . -name *.ogg -or -name *.wma -exec ffmpeg -i {} {}.mp3 \;
bonh

Tüm wma dosyalarını mp3'e dönüştürün ve sildikten sonra:find . -name *.wma -exec ffmpeg -i {} {}.mp3 \; -exec rm {} \;
Panagiotis

21

Pencereler için:

Burada tüm (.mp4) dosyalarını (.mp3) dosyalarına dönüştürüyorum.
Sadece cmd'yi açın, istediğiniz klasöre gidin ve komutu yazın.

Kısayol: (isteğe bağlı)
1. (.mp4) dosyalarınızın bulunduğu klasöre gidin
2. Shift ve Sol tuşlarına basın ve "PowerShell Penceresini Burada
Aç " veya "Komut İstemi Penceresini Burada Aç" ı seçin
3. "cmd" yazın [NOT : PowerShell yerine doğrudan cmd'yi açarsa bu adımı atlayın]
4. Komutu çalıştırın

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

Bunu Windows 10'da bir toplu iş dosyasına koymak istiyorsanız, %% i öğesini kullanmanız gerekir.


18

Ffmpeg ile herhangi bir şeyi toplu olarak dönüştürmek isteyen ancak uygun bir Windows arabirimine sahip olmak isteyen herkes için bu ön ucu geliştirdim:

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

Bir pencere moda arayüzü, ilerleme çubukları ve kalan süre bilgisi, ffmpeg kullanırken her zaman kaçırdığım özellikler ffmpeg'e ekler.


Tamam bu güzel bir proje! Bir saattir kuyruğumu Windows'ta göreceli bir dış yolu kabul etmek için ffmpeg almaya çalışıyorum ve bu hile gibi hissediyorum. EDIT: Bunu .xwm dönüştürmek için kullanılır .flac
semtex41

6

GNU paraleliniz varsa, aşağıdaki vid_dirCPU çekirdeğiniz dışındaki tüm .avi dosyalarını paralel olarak mp4'e dönüştürebilirsiniz.

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

Farklı biçimlere / biçimlere dönüştürmek için '*.avi'veya .mp4gerektiği şekilde değiştirin . GNU paralel, çoğu Linux dağıtımının depolarında genellikle adlandırılan bir pakette listelenir parallel.


!bash one-liner'ların sonuna ekleyerek aynı şeyi yapamaz mıydınız?
stib

3

Bunun gereksiz olabileceğini biliyorum ama dosyaları dönüştürmek için bu komut dosyasını kullanıyorum.

old_extension=$1
new_extension=$2

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

Daha esnek hale getirmek için 2 argüman gerekir:

  1. dönüştürmek istediğiniz uzantı
  2. dönüştürmek istediğiniz yeni uzantı

Bunun için bir takma ad oluşturuyorum ancak manuel olarak da bu şekilde kullanabilirsiniz:

sh batch_convert.sh mkv mp4

Bu, tüm mkvdosyaları dosyalara dönüştürür mp4.

Gördüğünüz gibi biraz daha çok yönlü. ffmpegDönüştürebildiği sürece herhangi iki uzantı belirtebilirsiniz.


Thats the best 👍
Andreas Prang

3

Burada kod golf gibi biraz almak, ama şimdiye kadar neredeyse tüm cevaplar bash (bir yalnız cmd bir engelleme) olduğundan, burada powershell (çünkü harika) kullanan bir windows çapraz platform komutu:

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

* .Avi dosyasını kaynak görüntünüze uygun olanla değiştirebilirsiniz.


3

Tabii ki, PowerShell artık tam olarak böyle bir şeyi son derece kolay hale getirmek için tasarlanmış .

Ve evet, PowerShell sadece Windows dışındaki diğer işletim sistemlerinde de mevcuttur , ancak Windows'a önceden yüklenmiş olarak gelir, bu yüzden bu herkes için yararlı olmalıdır.

İlk olarak, geçerli dizindeki tüm dosyaları listelemek isteyeceksiniz, bu yüzden şunlarla başlayacağız:

ls

ls -RecurseAlt dizinlerdeki tüm dosyaları özyinelemeli olarak dönüştürmek istiyorsanız da kullanabilirsiniz .

Ardından, bunları yalnızca dönüştürmek istediğimiz dosya türüne (ör. "Avi") göre filtreleyeceğiz.

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

Bundan sonra, bu bilgileri bir fFmpeg'e a ForEach.

FFmpeg'in girdisi için, FullName- dosyasının tamamı budur. Ve FFmpeg en çıkışı için biz kullanacağız Name- ama yerine.avi birlikte sonunda .mp3. Yani, şöyle bir şey olacak:

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

Öyleyse, hepsini bir araya getirelim ve sonuç:

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

Bu, tüm ".avi" dosyalarını FFmpeg aracılığıyla ".mp3" dosyalarına dönüştürür, istediğiniz dönüşüm türüne karar vermek için tırnak içindeki üç şeyi değiştirin ve içinde FFmpeg'e başka bağımsız değişkenler eklemekten çekinmeyin ForEach.

Bunu bir adım daha ileri taşıyabilir Remove-Itemve eski dosyaları otomatik olarak silmek için sonuna ekleyebilirsiniz .

Yolunuzda ffmpegdeğilse ve aslında şu anda bulunduğunuz dizinde ise, ./ffmpegsadece yerine yazın ffmpeg.

Umarım bu herkese yardımcı olur.


1
PowerShell harika, teşekkürler! Başkasının bunu çalıştırmakta sorun yaşaması durumunda: bu komutu bir .ps1dosyaya değil , bir dosyaya koyun .bat. Daha Set-ExecutionPolicy RemoteSignedönce hiç PS betiği çalıştırmadıysanız yönetici olarak çalıştırmanız gerekir .
starpause

Genel olarak PowerShell'de doğrudan çalıştırmayı düşündüm, bu yüzden gerçekten düşünmedim! İyi bir ipucu olsa!
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

[1] [2] kullanarak işlem flacdosyalarını mp3(boşluklu dosya adları için güvenli)


2

pencereler:

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

%~nd.2.mp3"
)

Bu, kalite 2 değişken bit hızı, isterseniz 0 olarak ayarlayabilirsiniz, ancak gerçekten iyi bir hoparlör sisteminiz yoksa, değersiz imo


1

Bir grafik arabirimin ffmpegX ile toplu işlem yapmasını istiyorsanız, Hızlı Toplu İşi deneyin . Ücretsizdir ve bıraktığınız dosyaları dönüştürmek için son ffmpegX ayarlarınızı alacaktır.

Klasörleri Quick Batcher'a sürükleyemeyeceğinizi unutmayın. Bu yüzden dosyaları seçin ve ardından Quick Batcher'a koyun.


2
"Quick Batcher" yazılımı SADECE MAC OS için
Mohammad ElNesr

1

Sadece bu benim için çalıştı, pls ffmpeg.exe dosyasının bulunduğu yerde "newfiles" klasörü oluşturmak zorunda olduğuna dikkat edin.

Dönüştür . .wav ses koduna dosyalar:

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

yani .wav değişikliğe tüm .mp3 dosyalarını dönüştürmek istiyorsanız ("*.*")için ("*.mp3").

Bu betiğin yazarı:

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

umarım yardımcı olmuştur 🙏.


0

Bu, geçerli dizindeki tüm jpg dosyalarından mp4 video oluşturur.

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

0

Ve Windows için bu çalışmıyor

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

bunları ikiye katlasam bile %.

Hatta şunu öneririm:

-acodec ***libmp3lame***

Ayrıca:

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

Bu bir cevap mı yoksa yeni bir soruyu cevap olarak gönderme girişimi mi? İkinci durumda, lütfen arka plan için buraya bağlanıyor olsa da, bunun yerine tamamen yeni bir soru oluşturun.
tripleee

0

Bu, avi'yi 1280x mp4'e dönüştürmek için kullandığım şey

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"

Bir cmd dosyası olarak iyi çalışır, çalıştırın, döngü o klasördeki tüm avi dosyalarını bulur.

MY (seninkini değiştir) ffmpeg'i çağırır, giriş adını geçer, ayarlar keskinleştirme ile yeniden ölçeklendirme içindir. Probların CRF'ye ihtiyacı yok ve " -b:v 1024k" ...

Çıktı dosyası, eksi uzantı eksi, mp4 yeni ext olarak.


0

Ben bu tek astar linux dosyaları (genellikle H265) Kodi üzerinde sorunsuz bir şekilde oynayabileceğim bir şeye dönüştürmek için kullanıyorum:

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

Bu geçici bir dosyaya dönüştürür ve daha sonra orijinali değiştirir, böylece dönüşümden sonra adlar aynı kalır.


0

Ayrıca alt klasörlerde aynı dönüşüm istiyorsanız. İşte özyinelemeli kod.

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

-1

küçük php betiği yapmak için:

#!/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
Kullanıcının makinelerinde PHP yüklü olması nedeniyle çok sınırlı bir kapsam cevabı. Komut satırı ve toplu iş dosyası yanıtları çok daha kolay ve daha az karmaşıktır.
ProfK

2
@ProfK PHP SO'daki en popüler dillerden biridir - ikinci olarak, Isaac'in sh için cevabı biraz güvenilmezdir, çünkü dosyalarınızı orijinalinden başka bir adla yeniden adlandırabilir, örneğin, dosya adındaki yeni satırları korumaz. lyx'in yarasa betiği daha da kötüdür, adında yeni satırları olan herhangi bir dosyayı TAMAMEN IGNORES . neden olduğundan emin değil, hatta bir sözdizimi hatası veya herhangi bir şey değil, ama öyle (win10'da test edildi). benim php betiği sayesinde hiçbir sorunları vardır escapeshellarg(), ve hem windows ve linux üzerinde çalışır. katılıyorum olsa da bir durum.
hanshenrik

-1

Henüz önerilmeyen başka bir basit çözüm kullanmak olacaktır xargs:

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

Küçük bir tuzak, çıktı dosyalarının garip adlandırılmasıdır (örn. input.avi.mp4). Bunun olası bir çözümü şunlar olabilir:

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


shellcheck.net'te örneklerinizle ilgili birkaç öneri var.
llogan

mywiki.wooledge.org/ParsingLs sana rağmen basitçe yerini alabilir lsile printf '%s\n'burada.
Üçlü
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.