Trích xuất chỉ mục của các khung chính từ video bằng ffmpeg


17

Tôi đang sử dụng ffmpeg để trích xuất các khung chính từ video. Đây là lệnh:

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

Làm cách nào tôi có thể lấy chỉ mục của từng khung hình chính được trích xuất trong video? Ví dụ: đối với khung hình I đầu tiên, chỉ số sẽ là 0, đối với khung hình thứ hai, nó sẽ là 24, v.v.


bản sao có thể có của superuser.com/questions/669716/
Mạnh

Nhìn vào sử dụng ffprobe sau đó đăng quá trình đầu ra để lấy chỉ số?
dstob

@dstob bạn có thể giải thích thêm về ý của bạn không? như tôi mới biết đến ffmpeg.
Faten Khalifa 4/03/2015

@LordNeckbeard Số khung trong khung video, ví dụ: khung đầu tiên của video sẽ ở chỉ số 0 Tôi muốn biết chỉ số của từng khung chính trong các khung video.
Faten Khalifa 4/03/2015

Bạn muốn số khung hình được in trên hình thu nhỏ (trên chính hình ảnh)?
llogan 4/03/2015

Câu trả lời:


21

Giống như @dstob đã đề cập, bạn có thể sử dụng ffprobeđể lấy I-frames và thông tin liên quan của chúng. ffprobeđi kèm với một số bản dựng tĩnh trên trang tải xuống và cũng có thể được xây dựng từ nguồn.

Điều này giả sử bạn đang dùng Linux / Unix:

Trích xuất khung và loại khung

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

Các greplệnh lọc dòng với Itrong họ, và đếm chỉ mục của họ (bằng cách sử dụng -ntùy chọn). Các cutlệnh chọn cột đầu tiên của kết quả duy nhất (chỉ số). Lưu ý rằng chỉ số này là dựa trên 1, không dựa trên 0.

Đổi tên tập tin đầu ra dựa trên chỉ mục

Bạn thực sự có thể dẫn các chỉ số này vào một danh sách:

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

Sau đó, tạo một danh sách tất cả các hình thu nhỏ quá:

ls -1 thumbnails*.jpeg > thumbnails.txt

Sau đó dán hai cái đó lại với nhau:

paste thumbnails.txt frame_indices.txt > combined.txt

Danh sách hiện chứa tên của hình thu nhỏ và chỉ mục. Thực hiện đổi tên dựa trên đó:

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

Ở trên sẽ đổi tên thumbnail-01.jpegthành thumbnail-0.jpeg. Lưu ý rằng không có phần đệm bằng 0 trên chỉ mục đầu ra. Nếu bạn muốn không đệm nó, giả sử, 5 chữ số, sử dụng printf:

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

Trên Windows, bạn sẽ làm tương tự với ffprobenhưng phân tích đầu ra khác nhau. Không có ý tưởng làm thế nào để thực hiện việc đổi tên ở đó mặc dù.


Lỗi này được hiển thị: 'grep' không được nhận dạng dưới dạng lệnh bên trong hoặc bên ngoài, chương trình có thể hoạt động hoặc tệp bó.
Faten Khalifa

2
Đó là bởi vì bạn đang ở trên Windows. Như tôi đã nói, câu trả lời này giả định Linux hoặc Unix. Bạn đã không được cụ thể hơn trong câu hỏi của bạn. Bạn có thể đạt được điều tương tự trên Windows bằng cách sử dụng các lớp Cygwin hoặc các lớp GNU / Linux tương tự cho Windows.
slhck

Đây là một sự giúp đỡ rất lớn, cảm ơn. Một điều chỉnh: Tôi nghĩ rằng các chỉ số trong lệnh đầu tiên của bạn bị tắt bởi hệ số ba, bởi vì có một [FRAME]dòng và một [/FRAME]dòng cho mỗi pict_typedòng.
Jack O'Connor

2
@ JackO'Connor Chỉ có một dòng trên mỗi khung nếu bạn sử dụng -of csvtùy chọn cho ffprobe. Mặc dù vậy, những gì bạn đang mô tả là định dạng đầu ra mặc định.
slhck

0

Nếu bạn muốn sử dụng FFMPEG như đã nêu ban đầu, Bạn có thể liệt kê tất cả hoặc một phần danh sách cũng như tạo jpg bằng cách sau:

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"

Hủy bỏ -t 15không giới hạn thời gian hoặc thay đổi cho phù hợp. Xóa -s 160x90 -f image2 thumbnail-%02d.jpeghoặc thay đổi cho phù hợp để loại bỏ hình thu nhỏ.


Trong Windows 7 CMD, điều này không thành công tại \. Thay đổi \ thành ^ gây ra lỗi tại: I ". Bạn có phiên bản nào hoạt động trên Windows không?
ChrisJJ
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.