Bagaimana saya bisa mengurangi ukuran video dengan ffmpeg?

201

Bagaimana saya dapat menggunakan ffmpeguntuk mengurangi ukuran video dengan menurunkan kualitas (seminimal mungkin, secara alami, tetapi saya perlu menjalankannya di perangkat seluler yang tidak memiliki banyak ruang yang tersedia)?

Saya lupa menulis satu hal. Ketika video dapat menggunakan subtitle (* .srt atau * .sub) saya ingin mengonversinya juga agar sesuai dengan parameter file video yang dikonversi.

xralf
sumber
4
Saya belum menggunakannya tetapi ffmpeghalaman manual menunjukkan -fsopsi untuk membatasi ukuran output, apakah sesuatu seperti ffmpeg -i in.avi -fs 100M out.avibekerja?
Kevin
1
Saya tidak akan mengarahkan Anda ke halaman manual:man ffmpeg | wc -l --> 5254
3
Ini .avibukan masalah utama .. avihanya sebuah wadah. Masalah utama adalah codec mana yang Anda gunakan .. Banyak (sebagian besar?) .aviVids menggunakan codec gaya lama (misalnya XviD) yang baik-baik saja, tetapi lebih besar untuk kualitas yang sama jika dibandingkan dengan generasi codec berikutnya .. Anda biasanya bisa mendapatkan pengodean ketat dengan menggunakan H.264standar kompresi video (mis. codec x264) dan aackompresi untuk audio .. Wadah dan codec yang Anda gunakan terserah Anda dan ponsel Anda ... .mp4Wadah diterima dengan baik .. (tetapi dapatkah telepon Anda menanganinya: lihat tautan ini
Peter.O
@Kevin Ini menginginkan lebih banyak parameter untuk konversi.
xralf
@hesse Apa artinya?
xralf

Jawaban:

277

Lihat jawaban ini . Dikutip di bawah ini untuk kenyamanan:

Hitung bitrate yang Anda butuhkan dengan membagi 1 GB dengan panjang video dalam hitungan detik. Jadi, untuk video berdurasi 16:40 (1000 detik), gunakan bitrate 1000000 byte / detik:

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

Opsi tambahan yang mungkin layak dipertimbangkan adalah menetapkan Constant Rate Factor, yang menurunkan bit rate rata-rata, tetapi tetap mempertahankan kualitas yang lebih baik. Variasikan CRF antara sekitar 18 dan 24 - semakin rendah, semakin tinggi bitrate.

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

Variasikan codec sesuai kebutuhan - libx264 mungkin tersedia jika libx265 tidak, dengan biaya ukuran file yang dihasilkan sedikit lebih besar.

Vicky Chijwani
sumber
Video ukuran 338 MB berkurang pada ukuran 130 MB. Kualitasnya cepat menurun. Apakah ada penjelasan untuk proses ini? Penulis asli tidak menjelaskan pedomannya.
xralf
13
Perintah kedua, menggunakan -crf 24mengambil 255,3MB video yang saya miliki dan menguranginya menjadi 72,7MB tanpa menurunkan kualitas secara nyata. Selamat menikmati!
Patrick Roberts
2
Secara mengesankan mengurangi video ~ 2G menjadi 14MB, masih terlihat bagus, ini adalah hasil pencarian pertama dan itulah yang saya cari, terima kasih!
sinisterstuf
5
Mungkin baik untuk dicatat bahwa Anda sekarang dapat menggunakan libx265untuk pengurangan ukuran lebih banyak.
ZN13
6
Digunakan ffmpeg -i input.avi -vcodec libx264 -crf 24 output.avi. Ini mengurangi video 100MB menjadi 9MB. Sangat sedikit perubahan dalam kualitas video. Terima kasih!
alpha_989
32

Kecuali jika Anda mencari bitrate tertentu, saya akan merekomendasikan -crfopsi. Ini adalah yang paling umum digunakan untuk x264penyandian: http://slhck.info/articles/crf

Singkatnya: CRF 23 akan menghasilkan film berkualitas "DVD" (~ 700MB-1GB) dan nilai CRF yang lebih rendah akan berkualitas lebih tinggi (file lebih besar).

Tom Kelly
sumber
3
Tolong beri contoh perintah lengkap alih-alih menautkan ke situs web eksternal (yang dapat merusak suatu hari nanti :)
Jake Berger
1
@Vicky Chijwani memberikan kode pada contoh di atas. Ini lebih cocok untuk komentar tetapi itu adalah aktivitas pertama saya di situs ini. Tautan memiliki penjelasan lebih lanjut tentang opsi CRF tetapi tidak perlu untuk mendapatkan kode untuk bekerja.
Tom Kelly
27

Anda mengatakan ingin mengurangi ukuran file agar sesuai dengan lebih banyak video di perangkat seluler, yang juga merupakan usecase saya. Semua jawaban di sini adalah untuk mengurangi kualitas kompresi tetapi tidak ada yang menyebutkan mengurangi ukuran bingkai video. Ini jauh lebih cepat, dari sekitar 3 sampai 5 kali lebih cepat daripada kompresi ulang dalam pengalaman saya. Lihat dokumen ffmpeg tentang penskalaan untuk info lebih lanjut.

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
georgiecasey
sumber
20

Saya menguji sebagian besar jawaban yang diajukan lainnya untuk pertanyaan ini. Kesimpulan data uji di bawah ini. Ini adalah jawaban yang diajukan yang saya uji:

(BR) Ubah bitrate, menggunakan:

ffmpeg -i $infile -b $bitrate $newoutfile 

(CR) Variasikan Faktor Tingkat Konstan, menggunakan:

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

(SZ) Ubah ukuran layar video (misalnya menjadi setengah ukuran pikselnya), menggunakan:

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

(BL) Ubah profil H.264 menjadi "dasar", menggunakan:

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

(DF) Gunakan pemrosesan ffmpeg default, menggunakan:

ffmpeg -i $infile $outfile

DATA

  • "size" - persen ukuran piksel dari video yang dikonversi terkait dengan aslinya.
  • "bitrate" - bitrate dari video asli dan yang dikonversi.
  • "definition" - ukuran piksel video.
  • "convert" - waktu untuk mengkonversi video dalam hitungan detik.

Saya menghitung bitrate target untuk (BL) menggunakan metode yang diusulkan.

=== File A - Bagaimana Node Membantu Menggerakkan Angular-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

=== File B - Menggunakan GraphQL dengan Angular _ 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

KESIMPULAN

  • Metode (SZ) jelas merupakan metode tercepat. Itu 2X hingga 4X lebih cepat. Ini bisa menjadi masalah besar pada video definisi tinggi, karena semua metode lain membutuhkan waktu lebih lama untuk dikonversi daripada panjang video yang sebenarnya! Misalnya, metode (CR) membutuhkan waktu 53 menit untuk mengonversi video 21 menit.

  • Metode (SZ) jelas merupakan metode terbaik jika definisi video lebih besar dari definisi layar yang akan menampilkannya. Misalnya, jika ponsel Anda hanya dapat menampilkan gambar 1080p, mengirimkannya video 3840x2160 hanya sia-sia. Akan lebih baik setengah ukurannya menjadi 1080p.

  • Beberapa jawaban yang diajukan sebenarnya MENINGKATKAN ukuran beberapa video. Misalnya, metode (BR) lebih dari dua kali lipat ukuran sampel 1080p. Namun itu membuat ukuran 2160p sepertiga. Untuk sampel definisi tinggi, metode (CR), (BL) dan (DF) semuanya MENINGKATKAN ukuran video.

Jawaban yang benar (atau terbaik)

Itu selalu yang terbaik untuk pertama-tama menurunkan resolusi ke maksimum yang didukung oleh tampilan target Anda.

Jika Anda ingin mengurangi ukuran file lebih lanjut, itu akan tergantung pada pilihan pribadi. Anda dapat mengurangi konten informasi atau meningkatkan kompresi.

  • Anda dapat menurunkan resolusi lebih banyak jika itu bukan sesuatu yang mengkhawatirkan Anda.

  • Jika video tidak menyertakan adegan tindakan cepat, Anda mungkin ingin menurunkan kecepatan bingkai.

  • Jika Anda memiliki prosesor yang kuat dan ruang adalah satu-satunya masalah, Anda dapat meningkatkan tingkat kompresi.

  • Bit rate adalah kombinasi dari beberapa faktor. Jadi hanya memberitahu ffmpeg untuk menurunkan bit rate mungkin tidak memberi Anda hasil yang Anda inginkan.

  • Cara lain untuk konten informasi yang lebih rendah adalah dengan menurunkan kedalaman warna. Cara melakukan ini belum dibahas.

John Pankowicz
sumber
13

Perhatikan bahwa tampaknya ffmpeg sudah melakukan beberapa optimasi ketika dijalankan tanpa opsi, jadi sebelum mencoba menggunakan pengaturan yang Anda tidak mengerti atau memutuskan untuk kehilangan informasi secara eksplisit, cobalah konversi default:

ffmpeg -i input.mp4 output.mp4

Dalam kasus saya ini mengurangi bitrate dari video dan audio (Anda dapat memeriksa dan membandingkan file input dan output dengan menjalankannya ffprobe), mengubah video 700 Mb menjadi 60 Mb yang kualitasnya hampir serupa.

Skippy le Grand Gourou
sumber
1
Pergi dari 4Gb ke 2Gb dengan ini, terima kasih !!
Sam Hosseini
1
(dari 10Mo ke 1.2Mb, ffmpeg otomatis mengkonversi video saya yang berada di VP8 ke VP9 )
sodimel
Ini meningkatkan ukuran video saya dari 10,8MB menjadi 14MB
pjtnt11
3

Saya punya resep yang awalnya saya buat untuk diri sendiri untuk mengonversi video Motion JPEG yang dihasilkan kamera lama saya (itu adalah video yang sangat besar, karena setiap frame adalah gambar JPEG keseluruhan) menjadi h264. Berikut ini adalah adaptasi untuk jenis video lainnya (kursus, dll).

Saya tidak menggunakan ffmpeg , tetapi mplayer dan mencoder . Pertama, Kita harus demux audio dengan mplayer:

mplayer -vo null -ao pcm:fast:file=<audio_pcm.wav> <video>
  • The -vo nulldan -ao nullparameter memberitahu mplayer untuk tidak mengambil video.

Pada langkah selanjutnya, kita akan melakukan kompresi 3-pass dengan mencoder. Pada pass pertama kita akan memilih kompresi Mode Kualitas Konstan yang sesuai ( parameter crf ) sebagai titik awal:

mencoder <video> -ovc x264 \ 
         -x264encopts ratetol=100:preset=veryslow:crf=<value>:pass=1 \
         -nosound -o video1.h264
  • Anda dapat menambahkan parameter slow_firstpass ke -x264encopts jika Anda paranoid dengan kualitas akhir video. Manual Mencoder mengatakan bahwa opsi ini menonaktifkan beberapa parameter yang "secara signifikan meningkatkan kecepatan encoding sementara berdampak kecil atau tidak sama sekali pada kualitas umpan akhir". Jadi, gunakan hanya pada langkah terakhir.

  • Anda harus mencoba beberapa nilai untuk crf - coba mulai dari 25 dan terus meningkat hingga Anda mencatat artefak pada video yang dihasilkan (nilai yang lebih tinggi menekan lebih banyak). Ingat pass encoding berikutnya akan meningkatkan kualitas yang Anda pilih untuk crf .

  • Alternatif untuk veryslow ditetapkan adalah lambat , lambat , menengah dll Lihat panduan mencoder untuk daftar lengkap.

  • ratetol mengontrol variasi bitrate - Saya tidak yakin apakah saya melakukan hal yang benar di sini, tapi saya mengaturnya ke nilai maksimum untuk membiarkan kebebasan total untuk mencoder untuk memilih bitrate yang tepat untuk setiap adegan.

Setelah lulus pertama, Anda akan perhatikan bahwa baris terakhir memberi Anda bitrate rata-rata yang akan Anda gunakan pada langkah berikutnya:

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

Ubah parameter crf , direkomendasikan pada pass pertama, untuk bitrate , diperlukan pada pass berikutnya:

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

Pengkodean pass kedua ini akan membaca statistik yang dihasilkan pada pass pertama ( divx2pass.logdan divx2pass.log.mbtree) untuk mengoptimalkan kompresi.

  • Catatan Anda akan menggunakan input video yang sama, bukan yang dihasilkan oleh video keluaran pertama - pertama lulus hanya berguna untuk memeriksa kualitas awal.

  • Perhatikan juga bahwa pass=3( tidak pass=2 ) akan menghasilkan file statistik baru, sehingga Anda dapat mengulangi langkah terakhir sebanyak yang Anda inginkan. Saya biasanya melakukan pass=3dua kali, selalu memperhatikan hasil bitrate.

Sementara itu, Anda dapat mengompresi audio juga, menggunakan lameatau oggenc:

oggenc -q<n> <audio_pcm.wav>

Akhirnya, kami akan mem-remux audio dan video

mencoder -audiofile <audio>.ogg video2.h264 -oac copy -ovc copy \
         -of lavf -lavfopts format=mp4 -o <video>.mp4
  • The -of lavf -lavfopts format=mp4menghasilkan mp4format file menggunakan lavopts muxers.
Juliano B. Nequirito
sumber
3

Saya mengompresi presentasi video HD 40 menit dari 505MB menjadi 183MB
Itu seperti pergi dari 100MB → 36MB.
Video asli adalah HD dan output hampir nol perbedaan nyata.
Ini adalah file video "Saya ingin tetap di sini, tetapi HD berlebihan."
Inilah perintah yang saya gunakan dengan alasan:

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

  • -n: hindari menimpa file keluaran (lebih aman untuk pengujian kemudian batching)
  • -loglevel error : tampilkan kesalahan dan sembunyikan baris dan baris progres
  • -i inputfile.mp4 : masukkan nama file
  • -vcodec libx264: digesek dari jawaban teratas di atas
  • -crf 28: Single-pass kompresi dengan perbedaan yang nyata minor ( "0 = lossless, 23 = default, 51 = terburuk; subyektif berbagai waras adalah 17- 28 " ) docs ref
  • -preset faster: terlihat 2x lebih cepat dari waktu pengkodean default dokumen 'sedang'
  • -tune film: tentukan input adalah video HQ (opsi lain termasuk 'kartun', 'gambar diam' ..) ref docs
  • outputfilename.mp4 : nama file keluaran

Untuk direktori file video:

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

Masalah:

  • cara yang lebih bersih untuk mengumpulkan "semua file video" tanpa memiliki semua ekstensi dalam perintah
  • cara yang lebih bersih untuk menampilkan nama file tanpa awalan "cc", DAN mampu mengonfirmasi video sebelum menghapus
  • .webmfile tidak berfungsi dengan perintah. Harus bertukar "cc${i}""${i%.*}.mp4"

Handbrake adalah alternatif sumber terbuka dengan UI

Jake Berger
sumber
Berhasil. tetapi butuh terlalu banyak waktu. Apakah ada peningkatan untuk waktu eksekusi yang lebih singkat
Nirali
1

Saya menulis skrip bash untuk mengurangi ukuran video dan mencoba nilai crf yang berbeda secara otomatis.

Pada dasarnya kamu akan

  • pilih rentang nilai crf
  • jalankan skrip
  • periksa ukuran video yang dihasilkan dan pilih yang Anda inginkan

Ini sangat berguna ketika Anda memiliki batas ukuran yang ingin Anda capai dan Anda tidak tahu apa nilai crf yang akan memungkinkan Anda untuk melakukannya.

Saya harap ini akan membantu seseorang. Saya berbagi dengan kolega saya dan semua orang merasa terbantu.

#!/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
kalmanIsAGameChanger
sumber