Bir videonun boyutunu ffmpeg ile nasıl küçültebilirim?


201

ffmpegKaliteyi düşürerek bir videonun boyutunu azaltmak için nasıl kullanabilirim (mümkün olduğunca minimal, doğal olarak, ancak fazla boş alana sahip olmayan bir mobil cihazda çalışmasını istiyorum)?

Henüz bir şey yazmayı unuttum. Video altyazıları kullanabildiği zaman (* .srt veya * .sub) Dönüştürülen video dosyasının parametrelerine uyacak şekilde onları da dönüştürmek istiyorum.


4
Ben kullanmadım ama ffmpegman sayfası -fsçıktı boyutunu sınırlamak için bir seçenek gösterir , ffmpeg -i in.avi -fs 100M out.aviiş gibi bir şey yapar ?
Kevin

1
: Adamın sayfaya yönlendireceğiz olmazman ffmpeg | wc -l --> 5254

3
.avi.. Ana konu değil avisadece bir kaptır. Asıl sorun, hangi kodekleri kullandığınızdır. Birçok (çoğu?) .aviVid, daha iyi olan kodeklerle karşılaştırıldığında daha iyi olan, ancak aynı kalitede daha büyük olan daha eski stil kodekleri (örneğin XviD) kullanır. H.264video sıkıştırma standardını (örn., codec bileşeni x264) ve aacses için sıkıştırmayı kullanarak sıkı bir şekilde kodlayın . Kullandığınız konteyner ve kodekler size ve telefonunuza bağlıdır ... .mp4Konteyner iyi bir şekilde kabul edilir. bu bağlantıya
Peter.O

@Kevin Bu dönüşüm için daha fazla parametre istiyor.
xralf

@hesse Bu ne anlama geliyor?
xralf

Yanıtlar:


277

Bu cevaba bakınız . Kolaylık sağlamak için aşağıda belirtilmiştir:

İhtiyacınız olan bit hızını, saniye cinsinden 1 GB'ı video uzunluğuna bölerek hesaplayın. Bu nedenle, 16:40 (1000 saniye) uzunluğunda bir video için, 1000000 bayt / sn'lik bir bit hızı kullanın:

ffmpeg -i input.mp4 -b 1000000 output.mp4

Göz önünde bulundurulması gereken ek seçenekler, ortalama bit hızını düşüren, ancak daha iyi kaliteyi koruyan Sabit Hız Faktörünü ayarlamaktır. CRF'yi 18 ila 24 arasında değiştiriniz - ne kadar düşükse, bit hızı o kadar yüksektir.

ffmpeg -i input.mp4 -vcodec libx265 -crf 20 output.mp4

Codec'i gerektiği gibi değiştirin - libx265 değilse, biraz daha büyük bir sonuçta ortaya çıkan dosya boyutunun maliyeti karşılığında libx264 kullanılabilir.


338 MB boyutundaki video 130 MB boyutunda küçültüldü. Kalite hızla düştü. Bu işlem için bir açıklama var mı? Orijinal yazar rehberini açıklamaz.
xralf

13
İkinci komut, kullandığım -crf 24255.3 MB'lık bir video çekti ve kaliteyi belirgin şekilde düşürmeden 72.7 MB'a düşürdüm. Olumlu oy ver!
Patrick Roberts

2
Etkileyici bir ~ 2G videoyu 14 MB'a düşürdü, hala iyi görünüyor, bu ilk arama sonucuydu ve tam olarak aradığım şey buydu, teşekkürler!
sinisterstuf

5
Artık libx265daha fazla boyut küçültme için kullanabileceğinizi unutmayın .
ZN13

6
Kullanılmış ffmpeg -i input.avi -vcodec libx264 -crf 24 output.avi. 100 MB'lik bir videoyu 9 MB'ye düşürdü. Video kalitesinde çok az değişiklik. Teşekkür ederim!
alpha_989

32

Belirli bir bit hızı arıyorsanız, -crfseçeneği öneririm . Bu x264kodlama için en yaygın kullanılandır : http://slhck.info/articles/crf

Kısacası: 23'lük bir CRF "DVD" kalitesinde film (~ 700MB-1GB) yapacak ve daha düşük CRF değerleri daha yüksek kalitede (daha büyük dosyalar) olacaktır.


3
Lütfen harici bir web sitesine bağlanmak yerine tam komuttan örnekler verin (ki bir gün bozulabilir :)
Jake Berger

1
@Vicky Chijwani, yukarıdaki örnekte bulunan kodu sağlar. Bu bir yorum için daha uygun, ancak bu sitedeki ilk aktivitemdi. Bağlantı, crf seçeneği hakkında daha fazla açıklamaya sahip ancak kodun çalışması için gerekli değil.
Tom Kelly,

27

Dosya boyutunun bir mobil cihaza daha fazla video uyacak şekilde küçültülmesini istemekten bahsetmiştim; Buradaki tüm cevaplar sıkıştırma kalitesini düşürmek içindir, fakat video karesini küçültmekten kimse bahsetmedi. Çok daha hızlı, deneyimimde yeniden sıkıştırmaya göre 3 ila 5 kat daha hızlı. Ffmpeg dokümanlarını görün ölçekleme daha fazla bilgi için.

ffmpeg -i input.mkv -vf "scale=iw/2:ih/2" half_the_frame_size.mkv
ffmpeg -i input.mkv -vf "scale=iw/3:ih/3" a_third_the_frame_size.mkv
ffmpeg -i input.mkv -vf "scale=iw/4:ih/4" a_fourth_the_frame_size.mkv

20

Bu soruya önerilen diğer cevapların çoğunu test ettim. Test verisi sonuçları aşağıdadır. Bunlar test ettiğim önerilen cevaplar:

(BR) Aşağıdakileri kullanarak bit hızını değiştirin:

ffmpeg -i $infile -b $bitrate $newoutfile 

(CR) Aşağıdakileri kullanarak Sabit Oran Faktörü'nü değiştirin:

ffmpeg -i $infile -vcodec libx264 -crf 23 $outfile

(SZ) Video ekran boyutunu değiştirin (örneğin piksel boyutunun yarısı kadar):

ffmpeg -i $infile -vf "scale=iw/2:ih/2" $outfile

(BL) Kullanarak H.264 profilini "taban çizgisi" olarak değiştirin:

ffmpeg -i $infile -profile:v baseline $outfile

(DF) Aşağıdakileri kullanarak, varsayılan ffmpeg işlemini kullanın:

ffmpeg -i $infile $outfile

VERİ

  • "boyut" - dönüştürülen videonun orijinaline göre yüzde piksel boyutu.
  • "bitrate" - orijinal ve dönüştürülmüş videoların bit hızı.
  • "tanım" - videoların piksel boyutu.
  • "convert" - videoyu saniye cinsinden dönüştürme zamanı.

Önerilen yöntemi kullanarak (BL) için hedef bit hızını hesapladım.

=== Dosya A - Düğüm Açısal-Fnbixa7Ts6M.mkv ===

            original    BR         CR         SZ         BL         DF
            --------    ---        --         --         --         --
size        64152 kb    214%       76%        40%        83%        76%
bitrate     411 kb/s    883        313        165        342        313
definition  1920x1080   1920x1080  1920x1080  960x540    1920x1080  1920x1080
convert     --          648        509        225        427        510

=== B Dosyası - GraphQL'i Açısal Olarak Kullanma _ By - Lee Costello-OGyFxqt5INw.mkv ===

            original    BR         CR         SZ         BL         DF
            --------    ---        --         --         --         --
size        410301 kb   33%        109%       28%        143%       109%
bitrate     2687 kb/s   880        2920       764        3843       2920
definition  3840x2160   3840x2160  3840x2160  1920x1080  3840x2160  3840x2160   
convert     --           2307       3188       1116       2646       3278

SONUÇLAR

  • (SZ) yöntemi kesinlikle en hızlı yöntemdir. 2X - 4X daha hızlıydı. Diğer tüm yöntemlerin dönüştürülmesi, videonun gerçek uzunluğundan daha uzun sürdüğü için bu, yüksek çözünürlüklü videolarda çok fazla bir sorun olabilir! Örneğin, (CR) yöntemi 21 dakikalık videoyu dönüştürmek için 53 dakika sürdü.

  • Videonun tanımı, görüntülenecek olan ekran tanımından daha büyükse, (SZ) yöntemi kesinlikle en iyi yöntemdir. Örneğin, telefonunuz yalnızca 1080p görüntü gösterebiliyorsa, 3840x2160 video göndermek çok israf olur. Boyutunun yarısını 1080p'ye çıkarmak en iyisidir.

  • Önerilen cevapların bazıları aslında bazı videoların boyutunu artırdı. Örneğin, (BR) yöntemi, 1080p numunesinin boyutunu iki katına çıkardı. Ancak 2160p boyutunu üçte bir yaptı. Yüksek çözünürlüklü örnek için, (CR), (BL) ve (DF) yöntemlerinin tümü videonun boyutunu ARTTIRIR.

Doğru (veya en iyi) Cevap

İlk önce çözünürlüğü hedef ekranınız tarafından desteklenen maksimum değere düşürmek daima en iyisidir.

Dosya boyutunu daha da küçültmek istiyorsanız, kişisel tercihlere bağlı olacaktır. Bilgi içeriğini azaltabilir veya sıkıştırmayı artırabilirsiniz.

  • Bu sizi ilgilendiren bir şey değilse, çözünürlüğü daha da azaltabilirsiniz.

  • Videoda hızlı hareket sahneleri bulunmuyorsa, kare hızını azaltmak isteyebilirsiniz.

  • Güçlü bir işlemciniz varsa ve alan tek sorunsa, sıkıştırma oranını artırabilirsiniz.

  • Bit hızı, çoklu faktörlerin bir kombinasyonudur. Bu yüzden sadece ffmpeg'e bit hızını düşürmesini söylemek, istediğiniz sonuçları vermeyebilir.

  • Bilgi içeriğini azaltmanın bir başka yolu da renk derinliğini düşürmektir. Bunun nasıl yapılacağı henüz tartışılmadı.


13

Seçeneksiz çalıştırıldığında ffmpeg zaten bazı optimizasyonlar uyguladığına dikkat edin , bu nedenle ayarları kullanmaya çalışmadan önce veya açıkça bilgileri kaybetmeye karar verdiğinizde, varsayılan bir dönüşümü deneyin:

ffmpeg -i input.mp4 output.mp4

Benim durumumda, hem video hem de sesin bit hızını düşürdü (giriş ve çıkış dosyasını ffprobeüzerlerinde çalıştırarak kontrol edip karşılaştırabilirsiniz ), 700 Mb'lik bir videoyu benzer kalitede 60 Mb'lik birine dönüştürün.


1
Bu, 4 Gb 2 Gb gitti, teşekkürler !!
Sam Hosseini

1
(10Mo dan 1.2MB için ffmpeg oto oldu videomu dönüştürülen VP8 için VP9 )
SODIMEL


3

Eski kameramın oluşturduğu Motion JPEG videolarını (her karenin tamamı bir JPEG görüntüsü olduğu için çok büyük videolar) h264'e dönüştürmek için kendim için oluşturduğum bir tarifim var. İşte diğer video türlerine (kurslar, vb.) Adaptasyon.

Ben ffmpeg kullanmıyorum ama mplayer ve mencoder . İlk önce, sesi mplayer ile karıştırmamız gerekiyor:

mplayer -vo null -ao pcm:fast:file=<audio_pcm.wav> <video>
  • -vo nullVe -ao nullparametreler video ayıklamak değil mplayer'la söyler.

Sonraki adımlarda, mencoder ile 3 geçişli bir sıkıştırma yapacağız. İlk geçişte başlangıç ​​noktası olarak uygun bir Sabit Kalite Modu sıkıştırması ( crf parametresi) seçeceğiz :

mencoder <video> -ovc x264 \ 
         -x264encopts ratetol=100:preset=veryslow:crf=<value>:pass=1 \
         -nosound -o video1.h264
  • Videonun son kalitesine paranoyaksanız , -x264encopts'e slow_firstpass parametresini ekleyebilirsiniz . Mencoder kılavuzu, bu seçeneğin “son geçişin kalitesi üzerinde çok az veya hiç etkisi olmazken kodlama hızını önemli ölçüde artıran” bazı parametreleri devre dışı bıraktığını söylüyor. Yani, sadece son adımda kullanın.

  • Crf için birkaç değer denemelisiniz - 25'ten başlamayı deneyin ve elde edilen videodaki yapıtları not edinceye kadar arttırmaya devam edin (daha yüksek değerler daha fazla sıkıştırılır). Sonraki kodlama geçişlerinin crf için seçtiğiniz kaliteyi artıracağını unutmayın .

  • Alternatifleri veryslow önceden olan yavaş , yavaş , orta tam bir listesi için mencoder kılavuzuna bakınız vb.

  • ratetol bit hızı varyasyonunu kontrol eder - Burada doğru olanı yaptığımdan emin değilim, ancak her sahne için doğru bit hızını seçmesi için mencoder'a toplam özgürlüğü sağlamak için maksimum değere ayarladım.

İlk geçişten sonra, son satırın sonraki adımlarda kullanacağınız ortalama bit hızını verdiğini unutmayın:

(...)
x264 [info]: kb/s:526.43

Değiştirme crf ilk geçişte önerilen parametre, bit hızı , daha sonraki geçişlerde gerekmektedir:

mencoder <video> -ovc x264 \
       -x264encopts slow_firstpass:ratetol=100:preset=veryslow:bitrate=526:pass=3 \
       -nosound -o video2.h264

Bu ikinci geçiş kodlaması , sıkıştırmayı optimize etmek için ilk geçişte ( divx2pass.logve divx2pass.log.mbtree) oluşturulan istatistikleri okuyacaktır .

  • Aynı video girişini kullanacağınızı unutmayın, ilk geçiş tarafından oluşturulan değil - ilk geçiş 'çıkış videosu yalnızca başlangıç ​​kalitesini kontrol etmek için kullanışlıdır.

  • Ayrıca pass=3( değil pass=2 ) yeni bir istatistik dosyası oluşturacağından, son adımı istediğiniz kadar tekrarlayabileceğinizi unutmayın. Genellikle pass=3iki kere yaparım , daima sonuç bit oranına dikkat ederim .

Bu arada, kullandığınız çok ses sıkıştırabilir lameveya oggenc:

oggenc -q<n> <audio_pcm.wav>

Sonunda ses ve videoyu değiştireceğiz

mencoder -audiofile <audio>.ogg video2.h264 -oac copy -ovc copy \
         -of lavf -lavfopts format=mp4 -o <video>.mp4
  • -of lavf -lavfopts format=mp4Üretir mp4lavopts muxer'leri kullanarak dosya formatı.

3

40 dakikalık bir HD video sunumunu 505 MB'tan 183 MB'a sıkıştırdım
.
Orijinal video HD idi ve çıktı neredeyse sıfır fark edildi.
Bu bir video dosyası "Saklamak isterdim ama HD overkill."
İşte nedenlerle kullandığım komut:

ffmpeg -n -loglevel error -i inputfile.mp4 -vcodec libx264 -crf 28 -preset faster -tune film outputfilename.mp4

  • -n: çıktı dosyalarının üzerine yazmaktan kaçının (sınama için daha güvenli, sonra toplu iş)
  • -loglevel error : hataları göster ve ilerleme satırlarını ve ilerleme satırlarını gizle
  • -i inputfile.mp4 : giriş dosyası adı
  • -vcodec libx264: yukarıdaki en üstteki cevaptan kaydırarak
  • -crf 28: Küçük fark fark ile tek-geçişli bir sıkıştırma ( , "0 = kayıpsız, 23 = Varsayılan, 51 = en kötü sübjektif aklı başında aralığı 17- olan 28 " ) ref dokümanlar
  • -preset faster: 'orta' ref belgelerin varsayılan kodlama süresinden 2 kat daha hızlı görünüyor
  • -tune film: girişin bir HQ videosu olduğunu belirtin (diğer seçenekler 'karikatür', 'hareketsiz görüntü' ..) ref docs
  • outputfilename.mp4 : çıktı dosyası adı

Video dosyalarının bir dizini için:

for i in *.{avi,flv,m4v,mov,wmv,mp4,MP4,TS,mkv}; do ffmpeg -n -loglevel error -i "$i" -vcodec libx264 -crf 28 -preset faster -tune film "cc${i}"; done

Sorunlar:

  • komutta tüm uzantılara sahip olmadan "tüm video dosyalarını" toplamanın daha temiz bir yolu
  • dosya adını "cc" ön eki olmadan çıkarmanın daha temiz bir yolu, VE silmeden önce videoyu doğrulayabilmek
  • .webmdosyalar komutla çalışmıyor. Değiştirmek zorunda kaldı "cc${i}""${i%.*}.mp4"

El freni kullanıcı arayüzü ile açık kaynaklı bir alternatiftir


İşe yarıyor. ama çok zaman alıyor. Daha az yürütme süresi için herhangi bir gelişme var mı
Nirali


1

Videonun boyutunu küçültmek ve otomatik olarak farklı crf değerlerini denemek için bir bash betiği yazdım.

Temelde olacak

  • bir dizi crf değeri seçin
  • betiği çalıştır
  • oluşturulan videoların boyutunu kontrol edin ve istediğinizi seçin

Bu, elde etmek istediğiniz bir boyut sınırına sahipseniz ve bunu yapmanıza izin verecek crf değerinin ne olduğunu bilmiyorsanız gerçekten kullanışlıdır.

Umarım bu birine yardımcı olur. Meslektaşlarımla paylaştım ve herkes faydalı buldu.

#!/bin/bash

# bigger values of crf will lead to a bigger compression (smaller video size)
#for i in 1 2 3 4 5
for i in {25..28}
do
# you can remove the option -y if you want to be asked if to overwrite a file with the same name (leave the -y only if you understand what you are doing, otherwise you might rewrite an important file)
   ffmpeg -y -i NAMEOFTHEVIDEOTOCOMPRESS.mp4 -c:v libx264 -crf $i -preset veryfast -profile:v baseline -level 3.0 -strict -2 out_$i.mp4
   printf "\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>Done compression at crf=$i \n\n"
done
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.