Bagaimana cara mengekstrak satu frame video setiap N detik ke gambar?

71

Bagaimana saya dapat mengkonversi file video ke urutan gambar, misalnya satu frame setiap N detik. Bisakah mplayer atau ffmpeg melakukan ini? Saya telah menggunakan MPlayer untuk mengambil tangkapan layar secara manual tetapi saya ingin mengotomatiskan ini untuk video yang panjang.

Liam
sumber
Lihat pertanyaan terkait ini tentang memilih kualitas gambar: stackoverflow.com/questions/10225403/…
Pierz

Jawaban:

70

Ini sangat sederhana dengan ffmpeg, dan dapat menghasilkan satu frame setiap N detik tanpa skrip tambahan. Untuk mengekspor sebagai urutan gambar cukup gunakan myimage_%04d.pngatau mirip dengan output. The %0xdbit dikonversi menjadi nol-empuk bilangan bulat xdigit - contoh yang saya berikan mendapat output

  • myimage_0000.png,
  • myimage_0001.png,
  • myimage_0002.png

    dll ..

Anda dapat menggunakan banyak format gambar diam, png, jpeg, tga, apa pun (lihat ffmpeg -formatsdaftar lengkap).

Ok jadi sekarang kita tahu bagaimana mengekspor film sebagai urutan gambar, tetapi katakan kita tidak ingin mengekspor setiap frame?

Caranya adalah dengan hanya mengubah frame rate dari output ke apa pun yang kita inginkan menggunakan -r nopsi di mana njumlah frame per detik. 1 frame per detik adalah -r 1satu frame setiap empat detik -r 0.25, satu frame setiap sepuluh detik, -r 0.1dan seterusnya.

Jadi untuk menyatukan semuanya, beginilah tampilannya untuk menyimpan satu frame dari input.movsetiap empat detik output_0000.png, output_0001.pngdll.:

ffmpeg -i input.mov -r 0.25 output_%04d.png

Perhatikan bahwa -r 0.25opsi pergi setelah itu -i input.movsebagian, karena itu mengendalikan frame rate dari keluaran . Jika Anda meletakkannya sebelum input, itu akan memperlakukan file input seolah-olah itu memiliki frame rate yang ditentukan.

Ubah% xd menjadi berapa banyak digit yang Anda butuhkan, misalnya jika perintah akan membuat lebih dari 10.000 frame, ubah %04dmenjadi %05d. Ini juga berfungsi untuk file input yang merupakan urutan gambar. Baca lebih lanjut di sini .

Pengguna Windows : Pada baris perintah digunakan%

contoh: ffmpeg -i inputFile.mp4 -r 1 outputFile_%02d.png

Dalam CMD dan Script BAT digunakan %%

contoh: ffmpeg -i inputFile.mp4 -r 1 outputFile %%02d.png

Jadi gandakan %%dalam skrip, dan lajang %di baris perintah interaktif. Melakukan kesalahan di kedua situasi akan menghasilkan kesalahan.

stib
sumber
Apa yang harus saya masukkan -rjika saya ingin mengekspor setiap frame? Jika saya tahu FPS video, saya kira saya masukan itu, tetapi bagaimana jika saya tidak tahu?
Tomáš Zato
4
Jangan menggunakan flag -r sama sekali. Kemudian FFMPEG akan menggunakan frame rate file input.
stib
2
Perhatikan bahwa Anda benar - benar ingin menggunakannya jpegsuntuk ini, kecuali Anda yakin pngitulah yang Anda inginkan. Dalam kasus saya, jpegmasing-masing sekitar 50kb, dan pngsekitar 2MB.
mlissner
5
keuntungan png adalah kompresi lossless, jadi jika Anda menggunakan urutan gambar sebagai perantara dan tidak keberatan dengan ukuran ekstra maka saat itulah Anda mungkin menggunakan png.
stib
Layak untuk ditambahkan bahwa -q:v 1ini adalah opsi yang sangat berguna di sini seperti di superuser.com/questions/318845/…
Nikolay Shmyrev
27
mplayer -vo jpeg -sstep 5 file.avi

akan menyimpan bingkai sebagai file jpeg setiap 5 detik.

Namun, itu tidak akan berhenti di akhir file, itu akan terus menghasilkan salinan dari frame terakhir. Untuk menghindarinya, cari durasi video dalam detik, menggunakan pemutar lain, atau dengan mplayer:

mplayer -vo null -ao null -frames 0 -identify file.avi

dan cari garis seperti "ID_LENGTH = 147.00".

Kurangi 2 dari panjangnya, dan gunakan nilai ini untuk -endposopsi. Misalnya, untuk video 147 detik:

mplayer -vo jpeg -sstep 5 -endpos 145 file.avi
Liam
sumber
ini terdengar seperti bug mplayer. solusi yang bagus.
quack quixote
Bisakah Anda setidaknya menyebutkan pada sistem operasi mana Anda menggunakan perintah ini?
Tomáš Zato
Itu 5 tahun yang lalu, tapi itu mungkin Desktop Ubuntu terbaru pada saat itu, Ubuntu 10.4.
Liam
Bagaimana saya bisa memilih langkah yang lebih pendek dari 1s. Itu hanya menerima bilangan bulat.
fcpenha
Saat ini, mpv --vo=image --sstep=5 movie.mkvberfungsi dengan baik tanpa bug yang disebutkan di atas ( mpv adalah fork of mplayer) menggunakan mpv 0.27.0 di Debian.
Adam Katz
11

Dengan ffmpeg, Anda dapat melakukan hal berikut:

ffmpeg -ss 4 -i input.avi -s 320x240 -frames:v 1 output.jpg

Perintah ini menghasilkan thumbnail JPG berukuran 320x240 pada detik ke-4 dalam video. Masukkan ini dalam skrip yang mengubah waktu dan nama file dan Anda selesai.

Info lebih lanjut: Buat gambar mini setiap X detik video

Nifle
sumber
Ini tampaknya melakukan apa yang saya inginkan, tetapi dengan satu masalah. Ini akan memproses file dari awal pada setiap iterasi, menjadi lambat secara eksponensial.
Liam
@Liam - Apakah ini membantu jika Anda membiarkan waktu offset (atur pada 1) dan menggunakan -ss positionflag untuk mencari lebih jauh ke dalam file? -ss Seek to given time position in seconds. hh:mm:ss[.xxx] syntax is also supported
Nifle
1
@liam: meletakkan -sssebelum -isehingga pencarian terjadi sebelum video input akan diterjemahkan. ini harus mempercepatnya. sumber
quack quixote
2
Ada cara yang lebih baik, lebih cepat untuk melakukannya dengan ffmpeg. Lihat jawaban saya di bawah ini.
stib
solusi stib adalah IMO terbaik.
Griffin
8

Jika Anda mencari semacam lembar kontak dan jika Anda bekerja dengan OS mirip Unix, Anda dapat menggunakan skrip rumit ini, dipanggil ke titik Video Contact Sheet * NIX , vcs pendek .

Di latar belakang juga menggunakan ffmpeg(secara default) atau mplayer, karenanya dapat menangani banyak format video. Ini mengotomatiskan proses pengambilan gambar diam dari film dan menyusunnya menjadi gambar dengan beberapa header dan footer. Anda dapat memilih misalnya berapa banyak tangkapan yang Anda inginkan atau sebagai alternatif perbedaan waktu di antara mereka.

Untuk interval 10 menit, doa seperti itu:

vcs -i 10m input.avi

Periksa daftar lengkap opsi baris perintah untuk beberapa penyesuaian lainnya.

Berikut ini contoh lembar kontak, yang diambil dari beranda :

masukkan deskripsi gambar di sini

mpy
sumber
7

Dengan VLC 1.1.0 ke atas, Anda dapat menggunakan filter video adegan:

vlc C:\video\to\process.mp4 --rate=1 --video-filter=scene --vout=dummy --start-time=10 --stop-time=11 --scene-format=png --scene-ratio=24 --scene-prefix=snap --scene-path=C:\path\for\snapshots\ vlc://quit

Di atas menghemat 1 dari setiap 24 frame (--scene-ratio = 24), mulai dari 00:00:10 dan berakhir pada 00:00:11.

Baru saja diuji dan dikonfirmasi ini berfungsi dengan VLC 2.0.3 pada instalasi Windows 8 yang baru (saya tidak punya plugin video atau perangkat lunak tambahan).

Dokumentasi lengkap: http://wiki.videolan.org/How_to_create_thumbnails

Michael
sumber
2

VirtualDub dapat melakukan ini untuk Anda

File-> Export->Image sequence

masukkan deskripsi gambar di sini

Shevek
sumber
Apakah ini akan menyimpan setiap bingkai sebagai gambar?
Liam
ya, setiap frame.
Shevek
Saya perlu melewatkan sebagian besar frame, mengeluarkan semua frame akan menggunakan terlalu banyak ruang penyimpanan. Saya hanya perlu satu frame setiap beberapa detik.
Liam
1

Anda juga bisa mencoba ini

dari baris perintah VLC ...

vlc "C: \ YOUR \ file \ path \ file.avi" -V image --image-out-prefix = capname --image-out-ratio = 60

file.avi adalah video yang ingin Anda ambil, capname adalah awalan dari gambar yang disimpan, Anda mungkin ingin bermain-main dengan rasio (60 berarti 1 dari 60 gambar diambil) Anda dapat menambahkan lebih banyak perintah, misalnya --image-out-format jpeg akan menyimpan caps Anda sebagai jpeg alih-alih pngs, --snapshot-path memungkinkan Anda memilih tempat untuk menyimpan caps Anda.

Sumber di atas

Nifle
sumber
Saya mendapat pesan ini: Opsi baris perintah tidak dapat dimuat, periksa apakah valid.
Liam
Di Ubuntu, saya mendapatkan pesan ini: opsi yang tidak diketahui atau argumen wajib yang hilang `--image-out-prefix = capname '
Liam
1

Anda dapat melewati bingkai di VirtualDub. Cukup gunakan opsi "Decimate By" yang terletak di Video -> menu Frame Rate. Misalnya jika Anda menetapkan "Decimate By 100" lalu gunakan File -> Export -> Sequence gambar, itu akan menyimpan hanya setiap frame ke-100.

Alex
sumber