Làm cách nào để có được số lượng khung hình trong video trên dòng lệnh linux?


30

Tôi có một tệp video và tôi muốn lấy số lượng khung hình video trong đó. Tôi có thể sử dụng ffmpegđể có được độ dài của video và FPS. Tuy nhiên tôi không thể thấy bất cứ điều gì rõ ràng cho tổng số khung.

Về lý thuyết, người ta có thể nhân độ dài (tính bằng giây) với FPS để có được số lượng khung hình, nhưng trong trường hợp này, độ dài (34,43 giây) và tốc độ khung hình (29,97 khung hình / giây) cho số nguyên không phải là số nguyên nghĩ rằng tôi đang làm gì đó sai.

Tôi cần có khả năng thực hiện điều này trên dòng lệnh theo cách hoàn toàn tự động và phi đồ họa. Tôi cũng cần điều này khá chính xác và không phải là ước tính (nếu điều đó thậm chí có thể xảy ra với các tệp video)

Tôi đã thử sử dụng tcprobetrên một số tập tin. Đối với một số tệp AVI, nó hoạt động, nhưng đối với một số tệp VOB, đầu ra tcprobe không có số lượng khung. Tôi nhận được kết quả này:

[tcprobe] MPEG program stream (PS)
[tcprobe] summary for myfile.vob, (*) = not default, 0 = not detected
import frame size: -g 720x480 [720x576] (*)
     aspect ratio: 4:3 (*)
       frame rate: -f 29.970 [25.000] frc=4 (*)
                   PTS=2199.3972, frame_time=33ms bitrate=7000 kbps
      audio track: -a 0 [0] -e 48000,16,5 [48000,16,2] -n 0x2000 [0x2000] (*)
                   PTS=2199.2763, bitrate=192 kbps
                   -D 3 --av_fine_ms 20 (frames & ms) [0] [0]

phương trình của bạn sẽ cho bạn một ước tính sân bóng tốt; chỉ cần làm tròn kết quả pt nổi lên. nếu bạn cần số khung hình chính xác, bạn sẽ cần kiểm tra tệp trực tiếp - ước tính của bạn có thể bị tắt bởi một hoặc hai theo một trong hai hướng do các chi tiết của bộ giải mã video.
quack quixote

đây là những VOB tất cả trong một tập tin hay VOB chia thành nhiều tập tin kiểu DVD?
quack quixote

Câu trả lời:


17

Điều này thật kinh khủng, và ngu ngốc, và chậm chạp, nhưng dường như có tác dụng:

ffmpeg -i foo.avi -vcodec copy -f rawvideo -y /dev/null 2>&1 | tr ^M '\n' | awk '/^frame=/ {print $2}'|tail -n 1

Nó cũng sẽ hoạt động ngay trên các tệp bị cắt và các luồng thô (đó là lý do tại sao bạn không nhận được gì cho các tệp .vob)


Đó là khá tốt. Theo kinh nghiệm của tôi, nó không mất nhiều thời gian. Một tệp 40 phút mất khoảng <3 giây để chạy. Hãy nhớ rằng "^ M" không phải là 2 ký tự ^ và M, bạn phải nhấn Control-V, sau đó nhập. Thay vì lệnh của bạn, tôi đã sử dụng: ffmpeg -i somefile.avi -vcodec copy -f rawvideo -y / dev / null 2> & 1 | tr "^ M" '\ n' | grep '^ frame =' | perl -pe 's / ^ frame = \ s * ([0-9] +) \ s. * $ / \ 1 /' | tail -n 1 Lệnh của bạn thất bại nếu không có khoảng trắng sau "frames ="
Rory

1
Trong Ubuntu 12.04, phiên bản ffmpeg git-2013-04-15-a4f03f0, bạn có thể bỏ qua cả | tr ^M '\n'|tail -n 1. Ngoài ra, không có không gian sau khi frames=không thất bại. (Có lẽ điều gì đó đã thay đổi trong bốn năm qua.)
Camille Goudeseune

đối với tôi, sự trở lại này mỗi lần giá trị khác nhau
CAMOBAP

1
Giải pháp Mediainfo hoạt động với VOB .. Tôi muốn giới thiệu thay thế. root @ lanparty: / mnt / movies # mediainfo --fullscan Bugs_Bunny.vob | grep -i đếm khung \ đếm Frame: 175.715 Khung count: 183.218
kevinf

32

ffprobe có thể được sử dụng để lấy thông tin về tệp phương tiện:

ffprobe -select_streams v -show_streams input.avi

Bạn sẽ nhận được thông tin chi tiết về luồng:

nb_frames=159697

Tìm kiếm nb_framesvới grep:

ffprobe -select_streams v -show_streams input.avi 2>/dev/null | grep nb_frames | sed -e 's/nb_frames=//'

Nó hoạt động cho avi, mp4 và vv Đối với một số bộ chứa, nó không hiển thị giá trị hợp lệ, ví dụ như mpeg.

Trong trường hợp đó, điều này hoạt động ffprobe -show_packets a.mpg 2>/dev/null | grep video | wc -l


Ý tưởng tốt. Tôi đã sửa đổi lệnh một chút để nó chỉ chọn luồng video và lọc đầu ra. Điều đó cung cấp cho bạn chỉ số lượng khung hình.
slhck

1
Xin chúc mừng cho giải pháp thứ 2 của bạn hoạt động với MPEG-2!
malat

1
Nó không hoạt động với container MKV.
Cenk Alti


Có vẻ như cách tiếp cận đầu tiên thất bại trên các tệp được mã hóa VBR. Cách tiếp cận thứ hai đáng tin cậy hơn.
Elder Geek

16

Tôi đã đăng cái này lên một câu hỏi khác . Sử dụng tcprobecông cụ (từ transcodegói), số lượng khung được bao gồm trong thông tin. Sử dụng công -itắc để nhận kết xuất thông tin từ tệp:

$ tcprobe -i foo.avi
[tcprobe] RIFF data, AVI video
[avilib] V: 29.970 fps, codec=XVID, frames=38630, width=512, height=384
[avilib] A: 48000 Hz, format=0x55, bits=16, channels=2, bitrate=128 kbps,
[avilib]    53707 chunks, 21768720 bytes, VBR
[tcprobe] summary for foo.avi, (*) = not default, 0 = not detected
import frame size: -g 512x384 [720x576] (*)
       frame rate: -f 29.970 [25.000] frc=4 (*)
      audio track: -a 0 [0] -e 48000,16,2 [48000,16,2] -n 0x55 [0x2000] (*)
                   bitrate=128 kbps
           length: 38630 frames, frame_time=33 msec, duration=0:21:28.954

Lưu ý số lượng khung được đưa ra trên hai dòng ở đây (dòng đầu ra thứ 2 và dòng đầu ra cuối cùng).


Đó có vẻ là một câu trả lời hay và hoạt động đối với một số tệp, nhưng đối với một số tệp VOB tôi có, tôi không có dữ liệu đó trong đầu ra. Tôi đã cập nhật câu hỏi với đầu ra tôi nhận được
Rory

tôi mong đợi (nhưng không biết chắc chắn) rằng tcprobe đang kiểm tra các tiêu đề tệp cho thông tin này. nếu nó không được bao gồm trong tiêu đề, tcprobe có thể không thử tính toán cho nó. câu hỏi hay; ước gì tôi có một câu trả lời tốt cho bạn
quack quixote

Điều này dường như không hoạt động trên các tệp được mã hóa VBR Tôi không nhận được đầu ra đếm khung hình. Tôi nhận được độ phân giải, tỷ lệ khung hình và tốc độ khung hình.
Elder Geek

7

Tôi đã thấy rằng mediainfo --fullscan inputfile | grep "Frame count"hoạt động độc đáo cho hầu hết các tập tin.

Các hệ thống dựa trên Debian có thể cài đặt nó với apt-get install mediainfo

Nếu bạn nhận được 2 dòng chứ không phải một đầu ra, dòng đầu tiên là bản nhạc video và dòng thứ hai là bản âm thanh. Dường như điều này xảy ra trên các tệp có âm thanh Biến tốc độ bit.

Đã thử nghiệm trên các mẫu .mkv, .m4v, .mp4, flv, vob và .avi kể từ ngày chỉnh sửa.

Nguồn: Làm cách nào để truy xuất thông tin tệp video từ dòng lệnh trong Linux? và thử nghiệm theo hương vị Ubuntu.

Bạn có thể tìm thấy mediainfo có sẵn cho hệ điều hành của bạn ở đây.


4

ffprobe -select_streams v -show_frames -count_frames INPUT_FILE | grep pkt_duration_time =

Thêm thời lượng. Có thể là fancier với sed / awk và những gì không.

Từ thử nghiệm của chúng tôi, tôi có thể nói rằng cho đến nay nó đã được chứng minh là đáng tin cậy nhất. Bạn nhận được một framecount chính xác và thời gian chính xác. Ngay cả với tốc độ khung hình thay đổi mà tất cả các công cụ khác như mediainfo dường như đi vào gaga.


3

Tôi đã thấy rằng số lượng khung hình thực sự gấp đôi thời lượng khung hình / giây (không hiểu tại sao, tôi rất vui được biết).

Trong một kịch bản của tôi, tôi có:

# Get duration and fps
duration=$($FFMPEG -i $input 2>&1 | sed -n "s/.* Duration: \([^,]*\), start: .*/\1/p")
fps=$($FFMPEG -i $input 2>&1 | sed -n "s/.*, \(.*\) tb.*/\1/p")

hours=$(echo $duration | cut -d":" -f1)
minutes=$(echo $duration | cut -d":" -f2)
seconds=$(echo $duration | cut -d":" -f3)
# For some reason, we have to multiply by two (no idea why...)
# Get the integer part with cut
frames=$(echo "($hours*3600+$minutes*60+$seconds)*$fps*2" | bc | cut -d"." -f1)

Và vâng, vì một số lý do tôi phải lấy phần nguyên của nó. Điều này không có ý nghĩa gì, nhưng kịch bản này luôn được quản lý để chuyển đổi video của tôi đúng cách cho đến nay.


Bởi vì FPS là viết tắt của Frames Per Second (hoặc game bắn súng góc nhìn người thứ nhất: D) ​​và nếu có 30 FPS chỉ cần nhân nó với bao nhiêu giây trong video.
John T

Có John, tôi có thể tìm ra điều đó, nhưng điều đó không giải thích tại sao tôi phải nhân nó lên 2 để có được số lượng khung hình phù hợp ... Trong trường hợp của tôi, sau khi tôi tính toán số lượng khung hình, tôi đã khởi chạy ffmpeg trong nền và phân tích các bản ghi để làm một thanh tiến trình. Nhật ký cho thấy có bao nhiêu khung đã vượt qua trong quá trình chuyển đổi. Khi toàn bộ video được chuyển đổi, khung # là int (giây * fps * 2), do đó là mã của tôi, nhưng tôi muốn biết lý do tại sao ;-)
inkaphink

đó là tò mò; các tcprobeđầu ra trong câu trả lời của tôi cung cấp cho các số khung như chính xác giây * fps (lên được làm tròn). tôi hy vọng bạn đang nhìn thấy một sự châm biếm của ffmpeg. Bạn đã thử phân tích tệp với các công cụ khác để xem liệu chúng có hiển thị cùng số lượng khung không?
quack quixote

Hmmm ... Thú vị. Tôi đã thử trên một video và tôi đã nhận seconds*fps=1001.59tcprobe=1002. Vì vậy, rõ ràng, tcprobenói với tôi rằng tôi không cần phải nhân hai. Tại sao sau đó ffmpeg cho tôi một con số lớn gấp đôi trong nhật ký khi nó chuyển đổi?
ℝaphink

2
Là cảnh quay xen kẽ? Nếu vậy, có hai trường trên mỗi khung và nó có thể cung cấp cho bạn số lượng trường.
stib

3

Đã thử nghiệm trên Ubuntu.

melt icecap.mp4 -consumer xml
  • melt- tan có nghĩa là một công cụ kiểm tra cho khung MLT, nhưng nó cũng là một trình chỉnh sửa video định hướng dòng lệnh đa nhiệm mạnh mẽ. Nó cũng có thể được sử dụng như một trình phát phương tiện tối giản cho các tệp âm thanh và video.

  • -consumerid [: arg] [name = value] *
    Đặt người tiêu dùng (chìm)

  • xml - Đặt đầu ra của người tiêu dùng (chìm) thành xml được định dạng

  • <property name="length">nnnn</property>- hiển thị số lượng khung, trong đó nnnnđược thay thế bằng số nguyên bằng số khung

Nếu bạn không bị tan chảy, bạn có thể cài đặt nó trên Ubuntu và các hệ thống dựa trên Debian khác với sudo apt-get install melt


1
Điều này rất ngắn, bạn có muốn mở rộng về những gì nó làm, tại sao nó hoạt động, vv?
David

Điều này hoạt động tốt trên các tập tin mp4 h264 không cung cấp khung hình thông qua mediainfo -fullscan filename.
Anh Cả Geek

3

Trực tiếp với mediainfo, không grep, không chờ đợi, không có gì:

mediainfo --Inform='Video;%FrameCount%' $the_file

Để biết thông tin khác xem mediainfo --info-parameters


0

Bạn có thể làm điều này bằng cách thêm và nhân các giá trị bạn nhận được từ ffprobe.

Lưu ý: ffprobe là một phần của libav (avconv) - phiên bản linux của ffmpeg.

#your command -
 ffprobe man.avi

Khi bạn làm điều này, bạn sẽ nhận được số lượng khung hình trên mỗi giây và cả thời lượng của clip.

Chuyển đổi thời lượng của clip thành giây và nhân giá trị đó với số khung hình / giây.

Nhớ làm tròn số đến gần nhất.


Trên Ubuntu 14.04 LTS ffprobekhông có sẵn, nhưng có cái gì đó gọi là avprobetrong libav-tools(mà cũng cung cấp avconv). Nhưng về phía tôi, nó không in bất kỳ số lượng khung hình nào, ít nhất là không cho các định dạng tôi đã thử. Nó chỉ in, những gì avprobe -iin, quá, và đây chỉ là một số bit nhỏ về định dạng, đáng buồn. Ngay cả với -v debugnó chỉ cho tôi biết một số thuộc tính tốt của phần cứng và phần mềm được cài đặt, nhưng không có một chút thông tin thú vị nào về tệp / luồng cần thăm dò. Có lẽ nó ẩn trong một số vô số các lựa chọn có sẵn. Ai biết?
Tino

@Tino ffprobe thực sự có sẵn như là một phần của gói ffmpeg. avconv là một nhánh của ffmpeg và gây ra một số nhầm lẫn. Xem: stackoverflow.com/questions/9477115/ cấp
Elder Geek

@ElderGeek Đối với Ubuntu 14.04 LTS không có ffmpegtrong kho chính thức. Liên kết bạn đã đưa ra chính xác: FFmpeg được trả về trong Ubuntu 15.04 "Verv Vervet". . Tuy nhiên, tình hình bây giờ đã thay đổi khi 16.04 LTS được đưa ra.
Tino

@Tino Đó thực sự là một sự thật. Tuy nhiên tôi sẽ không đánh đồng là không có sẵn trong kho. Bạn sẽ lưu ý rằng nó có sẵn cho Trusty (14.04) tại đây: ffmpeg.org/doad.html
Elder Geek

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]

-2

Phương pháp tốt nhất: (Trực tiếp bằng cách tính toán các tham số đúng, được xác nhận bởi ffmpeg)

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"

Kết quả ->

r_frame_rate=24000/1001
duration=8177.794625

Tính toán ->

Frames=24000/1001*8177.794625=196071 (exactly... ;P)

Bằng chứng ->

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

Đây

frame=196071 fps=331 q=-0.0 Lsize=N/A time=02:16:17.90 bitrate=N/A speed=13.8x

Đầu ra

video:102631kB audio:1408772kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
shareeditdeleteflag

Tôi nhận được r_frame_rate = 25/1 thời gian = N / A
Elder Geek
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.