Tìm nạp số lượng khung hình với ffmpeg


Câu trả lời:


158

Lưu ý: Sự hiện diện của danh sách chỉnh sửa trong MP4 / M4V / M4A / MOV có thể ảnh hưởng đến số khung hình của bạn. Xem Chỉnh sửa danh sách bên dưới.


ffprobe: Truy vấn vùng chứa

ffprobe -v error -select_streams v:0 -show_entries stream=nb_frames -of default=nokey=1:noprint_wrappers=1 input.mp4
  • Đây là một phương pháp nhanh chóng.
  • Không phải tất cả các định dạng (chẳng hạn như Matroska) sẽ báo cáo số lượng khung hình dẫn đến kết quả đầu ra N/A. Xem các phương pháp khác được liệt kê bên dưới.

ffprobe: Đếm số khung hình

ffprobe -v error -count_frames -select_streams v:0 -show_entries stream=nb_read_frames -of default=nokey=1:noprint_wrappers=1 input.mkv
  • Đây là một phương pháp chậm.
  • Thêm -skip_frame nokeytùy chọn để chỉ đếm khung hình chính.

ffmpeg: Đếm số khung hình

Nếu bạn không có, ffprobebạn có thể sử dụng ffmpegthay thế:

ffmpeg -i input.mkv -map 0:v:0 -c copy -f null -
  • Đây là một phương pháp hơi nhanh.
  • Tham khảo frame=gần cuối đầu ra bảng điều khiển.
  • Thêm -discard nokeytùy chọn đầu vào (trước -i) để chỉ đếm khung hình chính.

Chỉnh sửa danh sách

Bỏ qua danh sách chỉnh sửa MP4 / M4V / M4A / MOV với -ignore_editlist 1tùy chọn đầu vào. Mặc định là không bỏ qua danh sách chỉnh sửa.

Các tùy chọn ffprobe có nghĩa là gì

  • -v error Điều này ẩn đầu ra "thông tin" (thông tin phiên bản, v.v.) giúp phân tích cú pháp dễ dàng hơn.

  • -count_frames Đếm số khung hình trên mỗi luồng và báo cáo trong phần luồng tương ứng.

  • -select_streams v:0 Chỉ chọn luồng video.

  • -show_entries stream=nb_frameshoặc -show_entries stream=nb_read_framesChỉ hiển thị mục nhập cho nb_frameshoặc nb_read_frames.

  • -of default=nokey=1:noprint_wrappers=1Đặt định dạng đầu ra (hay còn gọi là "người viết") thành default, không in khóa của mỗi trường ( nokey=1) và không in đầu trang và chân trang ( noprint_wrappers=1) của phần. Có những lựa chọn thay thế ngắn hơn như -of csv=p=0.

Cũng thấy


thông tin truyền thông

Công mediainfocụ nổi tiếng có thể xuất ra số lượng khung hình:

mediainfo --Output="Video;%FrameCount%" input.avi

MP4Box

Đối với tệp MP4 / M4V / M4A.

MP4Box từ gpac có thể hiển thị số khung hình:

MP4Box -info input.mp4

Tham khảo Media Infodòng trong đầu ra cho luồng video được đề cập:

Media Info: Language "Undetermined (und)" - Type "vide:avc1" - 2525 samples

Trong ví dụ này, luồng video có 2525 khung hình.


cái hộp

Đối với tệp MP4 / M4V / M4A / MOV.

boxdumperlà một công cụ đơn giản từ l-smash. Nó sẽ xuất ra một lượng lớn thông tin. Dưới stszô kích thước mẫu phần tham khảo để sample_countbiết số lượng khung. Trong ví dụ này, đầu vào có 1900 khung hình video:

boxdumper input.mp4
  ...
  [stsz: Sample Size Box]
    position = 342641
    size = 7620
    version = 0
    flags = 0x000000
    sample_size = 0 (variable)
    sample_count = 1900
  • Lưu ý rằng một tệp có thể có nhiều hơn một stsznguyên tử.

5
Hoặc, nếu bạn muốn tốc độ nhanh hơn và nếu nb_frames là đủ tin cậy, đơn giản hóa như:ffprobe -v error -select_streams v:0 -show_entries stream=nb_frames -of default=nokey=1:noprint_wrappers=1 input.mkv
juanitogan

Điều này đưa ra câu trả lời hai lần cho tôi (tức là 2600 \ n 2600). Bất kỳ lý do cụ thể nào sẽ xảy ra?
jbodily

@jbodily Ví dụ của tôi hay của juanitogan? Tôi không thể sao chép nó bằng cách sử dụng. Không có nhiều thứ để làm việc ở đây.
llogan

+1, đặc biệt là vì, không giống như quá nhiều câu trả lời khác về bất kỳ công cụ dòng lệnh nào, công cụ này thực sự giải thích tất cả các tùy chọn dòng lệnh. Cảm ơn bạn.
Ray

1
Lưu ý rằng tùy chọn đầu tiên, truy vấn vùng chứa, thực sự xử lý tệp do count_frame. Xem bình luận của @ juanitogan.
aggieNick 02

23

Trong Unix, điều này hoạt động giống như sự quyến rũ:

ffmpeg -i 00000.avi -vcodec copy -acodec copy -f null /dev/null 2>&1 | grep 'frame=' | cut -f 2 -d ' '

3
Thực sự là một trong những tốt đẹp. Chỉ cần bạn không cần sao chép luồng âm thanh. Bạn có thể sử dụng -an instat.
rekire

1
@PrakharMohanSrivastava Kiểm tra câu trả lời này
Antonio

4
Actualy, điều này dường như nhanh chóng và đáng tin cậy:ffmpeg -i 00000.avi -map 0:v:0 -c copy -f null -y /dev/null 2>&1 | grep -Eo 'frame= *[0-9]+ *' | grep -Eo '[0-9]+' | tail -1
Timothy Zorn

1
@Michael cảm ơn vì nụ cười với ly cà phê buổi sáng của tôi :-)
Lloyd Moore

1
@TimothyZorn Bạn đã làm nên ngày của tôi!
Mladen Danic

13

Thay vào đó hãy tính toán dựa trên thời gian.

Đó là những gì tôi làm và nó hiệu quả với tôi và nhiều người khác.) Trước tiên, hãy tìm thời lượng của video trong đoạn mã dưới đây:

Seems stream 0 codec frame rate differs from container frame rate: 5994.00 
(5994/1) -> 29.97 (30000/1001)
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/Users/stu/Movies/District9.mov':
  Duration: 00:02:32.20, start: 0.000000, bitrate: 9808 kb/s
    Stream #0.0(eng): Video: h264, yuv420p, 1920x1056, 29.97tbr, 2997tbn, 5994tbc
    Stream #0.1(eng): Audio: aac, 44100 Hz, 2 channels, s16
    Stream #0.2(eng): Data: tmcd / 0x64636D74

Bạn sẽ có thể tìm thấy một cách nhất quán và an toàn Duration: hh:mm:ss.nnđể xác định kích thước video clip nguồn. Sau đó, đối với mỗi dòng cập nhật (CR, không có LF), bạn có thể phân tích cú pháp văn bản cho mốc thời gian hiện tại là:

frame=   84 fps= 18 q=10.0 size=       5kB time=1.68 bitrate=  26.1kbits/s    
frame=   90 fps= 17 q=10.0 size=       6kB time=1.92 bitrate=  23.8kbits/s    
frame=   94 fps= 16 q=10.0 size=     232kB time=2.08 bitrate= 913.0kbits/s    

Chỉ cần lưu ý rằng không phải lúc nào cũng mong đợi kết quả hoàn hảo từ những dòng trạng thái này. Chúng có thể bao gồm các thông báo lỗi như sau:

frame=   24 fps= 24 q=-1.0 size=       0kB time=1.42 bitrate=   0.3kbits/s    
frame=   41 fps= 26 q=-1.0 size=       0kB time=2.41 bitrate=   0.2kbits/s    
[h264 @ 0x1013000]Cannot parallelize deblocking type 1, decoding such frames in
sequential order
frame=   49 fps= 24 q=26.0 size=       4kB time=0.28 bitrate= 118.1kbits/s    
frame=   56 fps= 22 q=23.0 size=       4kB time=0.56 bitrate=  62.9kbits/s    

Một khi bạn có thời gian, nó rất đơn giản toán học: time / durration * 100 = % done.


1
Xin lỗi vì tôi ngu ngốc nhưng làm thế nào tôi có thể làm thời gian / thời lượng khi thời lượng ở định dạng hh: mm: ss.nn và thời gian luôn là định dạng xx.yy?
Omar Ali

2
@Omar, Là một nhà phát triển .NET, những gì tôi làm là tạo một TimeSpantừ nó, sau đó sử dụng currentDurationTimeSpan.Ticks / (totalDurationTimeSpan.Ticks / 100). Các TimeSpan cũng cung cấp một chức năng Parse mạnh mẽ, check it out
Shimmy Weitzhandler

giải pháp tuyệt vời, thời gian của tôi là hh: mm: ss: ms vì vậy tôi cho rằng trong 3 năm này FFMPEG đã cải thiện định dạng thời gian đầu ra.
ElektroStudios

1
Lưu ý rằng đầu ra bảng điều khiển có thể là 29,97, nhưng đó là viết tắt của 30000/1001. Tương tự cho 23,98 là 24000/1001 và 59,94 là 60000/1001.
llogan

Lưu ý, điều này không hoạt động đối với các video có tốc độ khung hình thay đổi (hiển nhiên).
Timothy Zorn

8

Không phải tất cả các định dạng đều lưu trữ số lượng khung hình hoặc tổng thời lượng của chúng - và ngay cả khi chúng có, tệp có thể không đầy đủ - vì vậy ffmpeg không phát hiện chính xác một trong số chúng theo mặc định.

Thay vào đó, hãy thử tìm đến cuối tệp và đọc thời gian, sau đó đếm thời gian hiện tại trong khi bạn đi.

Ngoài ra, bạn có thể thử AVFormatContext->nb_index_entrieshoặc thời lượng được phát hiện, sẽ hoạt động trên AVI / MOV tốt, ít nhất là không bị hư hại, hoặc thư viện FFMS2, có thể quá chậm để làm phiền thanh tiến trình.


8

Hãy thử một cái gì đó như:

ffmpeg -i "path to file" -f null /dev/null

Nó ghi số khung vào stderr, vì vậy bạn có thể lấy khung cuối cùng từ đây.


8

Bạn có thể sử dụng ffprobe để lấy số khung bằng các lệnh sau

  1. phương pháp đầu tiên

ffprobe.exe -i video_name -print_format json -loglevel fatal -show_streams -count_frames -select_streams v

yêu cầu in dữ liệu ở jsonđịnh dạng

select_streams vsẽ yêu ffprobecầu chỉ cung cấp cho chúng tôi videodữ liệu luồng và nếu bạn xóa dữ liệu đó, nó cũng sẽ cung cấp cho bạn audiothông tin

và đầu ra sẽ như thế nào

{
    "streams": [
        {
            "index": 0,
            "codec_name": "mpeg4",
            "codec_long_name": "MPEG-4 part 2",
            "profile": "Simple Profile",
            "codec_type": "video",
            "codec_time_base": "1/25",
            "codec_tag_string": "mp4v",
            "codec_tag": "0x7634706d",
            "width": 640,
            "height": 480,
            "coded_width": 640,
            "coded_height": 480,
            "has_b_frames": 1,
            "sample_aspect_ratio": "1:1",
            "display_aspect_ratio": "4:3",
            "pix_fmt": "yuv420p",
            "level": 1,
            "chroma_location": "left",
            "refs": 1,
            "quarter_sample": "0",
            "divx_packed": "0",
            "r_frame_rate": "10/1",
            "avg_frame_rate": "10/1",
            "time_base": "1/3000",
            "start_pts": 0,
            "start_time": "0:00:00.000000",
            "duration_ts": 256500,
            "duration": "0:01:25.500000",
            "bit_rate": "261.816000 Kbit/s",
            "nb_frames": "855",
            "nb_read_frames": "855",
            "disposition": {
                "default": 1,
                "dub": 0,
                "original": 0,
                "comment": 0,
                "lyrics": 0,
                "karaoke": 0,
                "forced": 0,
                "hearing_impaired": 0,
                "visual_impaired": 0,
                "clean_effects": 0,
                "attached_pic": 0
            },
            "tags": {
                "creation_time": "2005-10-17 22:54:33",
                "language": "eng",
                "handler_name": "Apple Video Media Handler",
                "encoder": "3ivx D4 4.5.1"
            }
        }
    ]
}

2. bạn có thể sử dụng

ffprobe -v error -show_format -show_streams video_name

sẽ cung cấp cho bạn dữ liệu truyền trực tuyến, nếu bạn muốn thông tin đã chọn như tốc độ khung hình, hãy sử dụng lệnh sau

ffprobe -v error -select_streams v:0 -show_entries stream=avg_frame_rate -of default=noprint_wrappers=1:nokey=1 video_name

đưa ra một con số dựa trên thông tin video của bạn, vấn đề là khi bạn sử dụng phương pháp này, bạn có thể nhận được kết N/Aquả đầu ra.

để biết thêm thông tin, hãy xem trang này Mẹo FFProbe


4

thử cái này:

ffmpeg -i "path to file" -f null /dev/null 2>&1 | grep 'frame=' | cut -f 2 -d ' '

Không hoạt động với *.ts. Đầu ra là một dòng trống.
Victor Polevoy

3

Vì nhận xét của tôi nhận được một số phiếu tán thành, tôi nghĩ rằng tôi sẽ để nó như một câu trả lời:

ffmpeg -i 00000.avi -map 0:v:0 -c copy -f null -y /dev/null 2>&1 | grep -Eo 'frame= *[0-9]+ *' | grep -Eo '[0-9]+' | tail -1

Điều này sẽ nhanh chóng, vì không có mã hóa nào được thực hiện. ffmpegsẽ chỉ demux tệp và đọc (giải mã) luồng video đầu tiên càng nhanh càng tốt. Lệnh đầu tiên grepsẽ lấy văn bản hiển thị khung. Lệnh thứ hai grepsẽ chỉ lấy số từ đó. Các taillệnh sẽ chỉ hiển thị các dòng cuối cùng (số khung hình cuối cùng).


2

để xây dựng trên câu trả lời của stu. đây là cách tôi tìm thấy tốc độ khung hình cho video từ điện thoại di động của mình. tôi đã chạy lệnh sau trong một lúc. tôi để số khung lên đến khoảng ~ 10.000 trước khi tôi mất kiên nhẫn và nhấn ^ C:

$ ffmpeg -i 2013-07-07\ 12.00.59.mp4 -f null /dev/null 2>&1
...
Press [q] to stop, [?] for help
[null @ 0x7fcc80836000] Encoder did not produce proper pts, making some up.
frame= 7989 fps= 92 q=0.0 Lsize=N/A time=00:04:26.30 bitrate=N/A dup=10 drop=0    
video:749kB audio:49828kB subtitle:0 global headers:0kB muxing overhead -100.000042%
Received signal 2: terminating.
$

sau đó, tôi lấy hai phần thông tin từ dòng đó bắt đầu bằng "frame =", số khung, 7989 và thời gian, 00: 04: 26.30. Trước tiên, bạn cần chuyển đổi thời gian thành giây và sau đó chia số khung hình cho từng giây để có được "khung hình trên giây". "khung hình trên giây" là tốc độ khung hình của bạn.

$ bc -l
0*60*60 + 4*60 + 26.3
266.3

7989/(4*60+26.3)
30.00000000000000000000
$

tốc độ khung hình cho video của tôi là 30 khung hình / giây.


2

Điều chính xác duy nhất mà tôi có thể làm là như sau:

ffprobe -i my_video.mp4 -show_frames 2>&1|grep -c '^\[FRAME'

Để đảm bảo điều này hoạt động với video:

ffprobe -i my_video.mp4 -show_frames 2>&1 | grep -c media_type=video

Tôi đã ủng hộ câu trả lời của bạn, nhưng điều đó sẽ chỉ hoạt động nếu video không chứa âm thanh. Nếu nó chứa, cái này sẽ hoạt động:ffprobe -i my_video.mp4 -show_frames 2>&1 | grep -c media_type=video
Gobe

2

Xin lỗi vì câu trả lời chưa xác định, nhưng có lẽ sẽ cần điều này (vì tôi không tìm thấy giải pháp cho các bản phát hành ffmpeg gần đây.

Với ffmpeg 3.3.4, tôi thấy có thể tìm thấy những điều sau:

ffprobe -i video.mp4 -show_streams -hide_banner | grep "nb_frames"

Cuối cùng, nó sẽ xuất số khung hình. Nó phù hợp với tôi trên các video có âm thanh. Tuy nhiên, nó cho hai dòng "nb_frames", nhưng dòng đầu tiên là số khung hình thực tế trên các video tôi đã thử nghiệm.


Cảm ơn @ acidrums4. Đã xác minh rằng phương pháp này hoạt động với phiên bản mới nhất từ ​​github mà tôi đã tạo hôm nay.
Paul J

1

Tôi sử dụng php_ffmpeg thì tôi có thể lấy mọi lúc và mọi khung hình của một bộ phim. Như dưới

$input_file='/home/strone/workspace/play/CI/abc.rmvb';
$ffmpegObj = new ffmpeg_movie($input_file);
echo $ffmpegObj->getDuration();
    echo $ffmpegObj->getFrameCount();

Và sau đó chi tiết là trên trang.

http://ffmpeg-php.sourceforge.net/doc/api/ffmpeg_movie.php


1
Cmd ->

ffprobe.exe -v error -select_streams v:0 -show_entries stream=r_frame_rate,duration -of default=nw=1 "d:\movies\The.Matrix.1999.1080p.BrRip.x264.YIFY.dut.mp4"

Result ->

r_frame_rate=24000/1001
duration=8177.794625

Calculation ->

Frames=24000/1001*8177.794625=196071

Proof -> 

ffmpeg -i "d:\movies\The.Matrix.1999.1080p.BrRip.x264.YIFY.dut.mp4" -f null /dev/null
ffmpeg version N-92938-g0aaaca25e0-ffmpeg-windows-pacman Copyright (c) 2000-2019 the FFmpeg developers
  built with gcc 8.2.0 (GCC)
  configuration: --pkg-config=pkg-config --pkg-config-flags=--static --extra-version=ffmpeg-windows-pacman --enable-version3 --disable-debug --disable-w32threads --arch=x86_64 --target-os=mingw32 --cross-prefix=/opt/sandbox/cross_compilers/mingw-w64-x86_64/bin/x86_64-w64-mingw32- --enable-libcaca --enable-gray --enable-libtesseract --enable-fontconfig --enable-gmp --enable-gnutls --enable-libass --enable-libbluray --enable-libbs2b --enable-libflite --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopus --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libzimg --enable-libzvbi --enable-libmysofa --enable-libaom --enable-libopenjpeg --enable-libopenh264 --enable-liblensfun --enable-nvenc --enable-nvdec --extra-libs=-lm --extra-libs=-lpthread --extra-cflags=-DLIBTWOLAME_STATIC --extra-cflags=-DMODPLUG_STATIC --extra-cflags=-DCACA_STATIC --enable-amf --enable-libmfx --enable-gpl --enable-avisynth --enable-frei0r --enable-filter=frei0r --enable-librubberband --enable-libvidstab --enable-libx264 --enable-libx265 --enable-libxvid --enable-libxavs --enable-avresample --extra-cflags='-march=core2' --extra-cflags=-O2 --enable-static --disable-shared --prefix=/opt/sandbox/cross_compilers/mingw-w64-x86_64/x86_64-w64-mingw32 --enable-nonfree --enable-decklink --enable-libfdk-aac
  libavutil      56. 25.100 / 56. 25.100
  libavcodec     58. 43.100 / 58. 43.100
  libavformat    58. 25.100 / 58. 25.100
  libavdevice    58.  6.101 / 58.  6.101
  libavfilter     7. 47.100 /  7. 47.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  4.100 /  5.  4.100
  libswresample   3.  4.100 /  3.  4.100
  libpostproc    55.  4.100 / 55.  4.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'd:\movies\The.Matrix.1999.1080p.BrRip.x264.YIFY.dut.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.25.100
  Duration: 02:16:17.91, start: 0.000000, bitrate: 2497 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x800 [SAR 1:1 DAR 12:5], 2397 kb/s, 23.98 fps, 23.98 tbr, 24k tbn, 47.95 tbc (default)
    Metadata:
      handler_name    : VideoHandler
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 93 kb/s (default)
    Metadata:
      handler_name    : GPAC ISO Audio Handler
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> wrapped_avframe (native))
  Stream #0:1 -> #0:1 (aac (native) -> pcm_s16le (native))
Press [q] to stop, [?] for help
Output #0, null, to '/dev/null':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.25.100
    Stream #0:0(und): Video: wrapped_avframe, yuv420p, 1920x800 [SAR 1:1 DAR 12:5], q=2-31, 200 kb/s, 23.98 fps, 23.98 tbn, 23.98 tbc (default)
    Metadata:
      handler_name    : VideoHandler
      encoder         : Lavc58.43.100 wrapped_avframe
    Stream #0:1(und): Audio: pcm_s16le, 44100 Hz, stereo, s16, 1411 kb/s (default)
    Metadata:
      handler_name    : GPAC ISO Audio Handler
      encoder         : Lavc58.43.100 pcm_s16le
frame=196071 fps=331 q=-0.0 Lsize=N/A time=02:16:17.90 bitrate=N/A speed=13.8x
video:102631kB audio:1408772kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown

Tốc độ khung hình thường được tính từ hai tham số. r_frame_rate = 24000/1001 (= 23,97602397602397 ...) Được ffmpeg làm tròn thành: 23,98 Thời lượng = giờ * 3600 + phút * 60 + giây.remainder = 8177,91 Trong khi thông số thời lượng = 8177,794625 Nhưng Khung = 24000/1001 * 8177,794625 = 196071 cho biết số khung hình chính xác. (Không đua đâu).
Gerard Wensink

0

linux

ffmpeg -i "/home/iorigins/Завантаження/123.mov" -f null /dev/null

hồng ngọc

result = `ffmpeg -i #{path} -f null - 2>&1`
r = result.match("frame=([0-9]+)")
p r[1]
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.