Bagaimana cara saya menggunakan ffmpeg untuk mendapatkan resolusi video?

7

Saya mencoba untuk mendapatkan resolusi video dengan perintah berikut:

ffmpeg -i filename.mp4

Saya mendapatkan output yang panjang, tetapi saya hanya perlu lebar dan tinggi untuk skrip bash saya. Bagaimana saya harus menyaring parameter tersebut? Mungkin ada cara yang lebih baik untuk melakukan ini.

Vladimir Stazhilov
sumber

Jawaban:

19

Menggunakan ffprobe

$ ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=s=x:p=0 input.mp4
  1280x720

Contoh pilihan pemformatan output lainnya

Lihat -of dokumentasi opsi untuk lebih banyak pilihan dan opsi. Lihat juga Tips FFprobe untuk contoh lain termasuk durasi dan frame rate.

Default

Dengan tidak [STREAM] pembungkus:

$ ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of default=nw=1 input.mp4
  width=1280
  height=720

Tanpa kunci:

$ ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of default=nw=1:nk=1 input.mp4
  1280
  720

CSV

$ ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=p=0 input.mp4
  1280,720

JSON

$ ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of json input.mp4
{
    "programs": [

    ],
    "streams": [
        {
            "width": 1280,
            "height": 720
        }
    ]
}

XML

$ ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of xml input.mp4
<?xml version="1.0" encoding="UTF-8"?>
<ffprobe>
    <programs>
    </programs>

    <streams>
        <stream width="1280" height="720"/>
    </streams>
</ffprobe>
llogan
sumber
Menggunakan eval berisiko dan tidak benar-benar diperlukan untuk ini. stackoverflow.com/questions/17529220/…
Nathaniel M. Beaver
@bariumbitmap Terima kasih. eval dalam jawabannya telah dihilangkan untuk solusi super sederhana yang entah bagaimana saya lewatkan meskipun menatap dokumentasi selama bertahun-tahun.
llogan
Saya mendapat dua hasil dengan perintah itu { "programs": [ { "streams": [ { "width": 640, "height": 360 } ] } ], "streams": [ { "width": 640, "height": 360 } ] }
Salem F
1
@SalemF Tambah | sort -nur | head -n 1. Ini mengembalikan resolusi dengan lebar terbesar. Yang sedang berkata, dalam semua kasus yang pernah saya lihat, hanya ada satu resolusi, tetapi itu dapat diduplikasi.
Cyker
2

Output dari ffprobe terlihat seperti ini:

streams_stream_0_width=1280
streams_stream_0_height=720

Secara teknis, Anda bisa menggunakannya eval untuk menetapkan ini bash variabel, tapi ini tidak perlu dan bisa tidak aman; lihat di sini untuk lebih lanjut:

https://stackoverflow.com/questions/17529220/why-should-eval-be-avoided-in-bash-and-what-should-i-use-instead

Sebagai gantinya, karena Anda menggunakan bash, manfaatkan array bawaan dan manipulasi string:

filepath="filename.mp4"
width_prefix='streams_stream_0_width='
height_prefix='streams_stream_0_height='
declare -a dimensions
while read -r line
do
    dimensions+=( "${line}" )
done < <( ffprobe -v error -of flat=s=_ -select_streams v:0 -show_entries stream=width,height "${filepath}" )
width_with_prefix=${dimensions[0]}
height_with_prefix=${dimensions[1]}
width=${width_with_prefix#${width_prefix}}
height=${height_with_prefix#${height_prefix}}
printf "%s\t%sx%s\n" "${filepath}" "${width}" "${height}"
Nathaniel M. Beaver
sumber
2

Perintah berikut ini sepenuhnya bergantung pada ffmpeg (dan grep dan cut ) untuk mendapatkan tinggi atau lebar sesuai kebutuhan:

Tinggi:

$ ffmpeg -i video.mp4 2>&1 | grep Video: | grep -Po '\d{3,5}x\d{3,5}' | cut -d'x' -f1

1280

Lebar:

$ ffmpeg -i video.mp4 2>&1 | grep Video: | grep -Po '\d{3,5}x\d{3,5}' | cut -d'x' -f2

720

Perbedaan antara keduanya hanyalah -f parameter ke cut.

Jika Anda lebih suka string resolusi penuh, Anda tidak perlu cut:

$ ffmpeg -i video.mp4 2>&1 | grep Video: | grep -Po '\d{3,5}x\d{3,5}'

1280x720

Inilah yang kami lakukan dengan perintah-perintah ini:

  1. Lari ffmpeg -i untuk mendapatkan info file.
  2. Mengekstrak baris yang baru saja berisi Video: informasi.
  3. Mengekstraksi hanya string yang terlihat seperti digitsxdigits yaitu antara 3 dan 5 karakter.
  4. Untuk dua yang pertama, memotong teks sebelum atau sesudah x.
aalaap
sumber
1
Output dari ffmpeg hanya dimaksudkan untuk mata manusia, dan tidak dimaksudkan untuk diuraikan oleh skrip atau alat lain. Outputnya tidak terstandarisasi sehingga tidak dijamin memiliki format yang sama untuk semua file, jadi ini adalah case use yang rapuh. Gunakan ffprobe sebagai gantinya. Banyak contoh di sini di utas ini.
llogan
@ LordNeckbeard saya setuju, tapi ini adalah opsi bagi mereka yang tidak mau ffprobe untuk alasan apa pun.
aalaap
1

Saya akhirnya menemukan jawabannya:

Saya menggunakan ini paket yang disebut Info media

Dan kemudian saya memerintahkan:

mediainfo mediainfo --Inform="Video;%Width%" midhand.mp4

Untuk melihat daftar params:

mediainfo --Info-Parameters

Alat terbaik untuk mengekstrak metadata video!

Vladimir Stazhilov
sumber
1

Menggunakan grep untuk memilih hanya garis-garis yang Anda cari. Redirect output dari STDERR ke STDOUT, karena ffmpeg akan menampilkan semua info di sana.

ffmpeg -i filename.mp4 2>&1 | grep <keyword>

Sunting: Contoh kerja lengkap menggunakan perl:

$ ffmpeg -i MVI_7372.AVI 2>&1 | grep Video | perl -wle 'while(<>){ $_ =~ /.*?(\d+x\d+).*/; print $1 }'
640x480
Andreas F
sumber
Anda juga perlu menggunakan STDERR. Saya memperbaiki bagian itu.
slhck
0

Saya tahu pertanyaannya adalah tentang bash tetapi, kalau-kalau seseorang berakhir di sini mencari solusi untuk batch Windows, seperti saya sendiri sebelum saya menemukannya.

for /f "delims=" %%a in ('ffprobe -hide_banner -show_streams filename.mp4 2^>nul ^| findstr "^width= ^height="') do set "myvideo_%%a"

Tidak ada pesan konsol, dan Anda diakhiri dengan variabel lingkungan yang bagus myvideo_width dan myvideo_height. Anda dapat memeriksanya dengan:

C:\>set myvideo_
myvideo_height=720
myvideo_width=1280

Jika resolusi video Anda adalah 1280x720, tentu saja.

cdlvcdlv
sumber