Mengekstrak indeks bingkai kunci dari video menggunakan ffmpeg

17

Saya menggunakan ffmpeg untuk mengekstraksi bingkai kunci dari video. Ini perintahnya:

ffmpeg -i test2.mp4 -vf select='eq(pict_type\,I)' -vsync 2 -s 160x90 -f image2 thumbnails-%02d.jpeg

Bagaimana saya bisa mendapatkan indeks dari setiap frame kunci yang diekstrak dalam video? Sebagai contoh, untuk frame-I pertama, indeks akan menjadi 0, untuk yang kedua, akan menjadi 24, dll.

Faten Khalifa
sumber
kemungkinan duplikat dari superuser.com/questions/669716/...
user236012
Lihatlah ke dalam menggunakan ffprobe kemudian memposting proses output untuk mendapatkan indeks?
dstob
@stob dapatkah Anda menjelaskan lebih lanjut tentang apa yang Anda maksud? karena saya baru di ffmpeg.
Faten Khalifa
@LordNeckbeard Nomor bingkai dalam bingkai video, mis. frame pertama dari video akan berada di indeks 0 Saya ingin tahu indeks dari setiap frame kunci dalam frame video.
Faten Khalifa
Anda ingin nomor bingkai dicetak pada thumbnail (pada gambar itu sendiri)?
Logan

Jawaban:

21

Seperti @dstob yang disebutkan, Anda dapat menggunakan ffprobeuntuk mendapatkan frame-I dan informasi terkaitnya. ffprobehadir dengan beberapa build statis pada halaman unduhan dan dapat dibangun dari sumber juga.

Ini dengan asumsi Anda menggunakan Linux / Unix:

Ekstrak bingkai dan jenis bingkai

ffprobe -select_streams v -show_frames \
-show_entries frame=pict_type \
-of csv bbb480.avi \
| grep -n I | cut -d ':' -f 1

The grepperintah filter baris dengan Idi dalamnya, dan menghitung indeks mereka (menggunakan -nopsi). The cutperintah memilih kolom pertama dari output saja (indeks). Perhatikan bahwa indeks ini berbasis 1, bukan berbasis 0.

Ganti nama file output berdasarkan indeks

Anda sebenarnya dapat mengirim indeks ini ke daftar:

ffprobe -select_streams v -show_frames \
-show_entries frame=pict_type \
-of csv bbb480.avi \
| grep -n I | cut -d ':' -f 1 > frame_indices.txt

Kemudian buat daftar semua gambar mini juga:

ls -1 thumbnails*.jpeg > thumbnails.txt

Lalu tempelkan keduanya bersama-sama:

paste thumbnails.txt frame_indices.txt > combined.txt

Daftar sekarang berisi nama thumbnail dan indeks. Lakukan penggantian nama berdasarkan itu:

while read -r thumbnail index; do
  newIndex=$(echo $index - 1 | bc) # subtract 1 from the index
  mv -- "$thumbnail" "thumbnail-$newIndex.jpeg"  # rename file
done < combined.txt

Di atas akan berganti nama thumbnail-01.jpegmenjadi thumbnail-0.jpeg. Perhatikan bahwa tidak ada bantalan nol pada indeks output. Jika Anda ingin menambahkan nol pada, katakanlah, 5 digit, gunakan printf:

newIndex=$(printf '%05d' $(echo $index - 1 | bc))

Di Windows, Anda akan melakukan hal yang persis sama dengan ffprobetetapi mengurai output berbeda. Tidak tahu bagaimana melakukan penggantian nama di sana.

slhck
sumber
Kesalahan ini ditampilkan: 'grep' tidak dikenali sebagai perintah internal atau eksternal, program yang dapat dijalankan atau file batch.
Faten Khalifa
2
Itu karena Anda menggunakan Windows. Seperti yang saya katakan, jawaban ini mengasumsikan Linux atau Unix. Anda tidak lebih spesifik dalam pertanyaan Anda. Anda dapat mencapai hal yang sama di Windows menggunakan lapisan Cygwin atau GNU / Linux serupa untuk Windows.
slhck
Ini sangat membantu, terima kasih. Satu koreksi: Saya pikir indeks pada perintah pertama Anda tidak aktif dengan faktor tiga, karena ada [FRAME]garis dan [/FRAME]garis untuk setiap pict_typebaris.
Jack O'Connor
2
@ JackO'Connor Hanya ada satu baris per bingkai jika Anda menggunakan -of csvopsi untuk ffprobe. Apa yang Anda gambarkan adalah format output default.
slhck
0

Jika Anda ingin menggunakan FFMPEG seperti yang dinyatakan sebelumnya, Anda dapat mendaftar semua atau sebagian listing serta membuat jpg dengan yang berikut ini:

ffmpeg.exe \
  -i "C:\Users\UserName\Desktop\jpegs and list\VideoName.mp4" \
  -t 15 \
  -vf select="eq(pict_type\,PICT_TYPE_I)" \
  -vsync 2 \
  -s 160x90 \
  -f image2 thumbnails-%02d.jpeg \
  -loglevel debug 2>&1| for /f "tokens=4,8,9 delims=. " %d in ('findstr "pict_type:I"') do echo %d %e.%f>>"keyframe_list.txt"

Hapus -t 15tanpa batas waktu atau ubah sesuai. Hapus -s 160x90 -f image2 thumbnail-%02d.jpegatau ubah sesuai dengan penghapusan thumbnail.

Budman1
sumber
Di Windows 7 CMD, ini gagal di \. Mengubah \ ke ^ menyebabkan kegagalan di: I ". Apakah Anda memiliki versi yang berfungsi pada Windows?
ChrisJJ