简体   繁体   中英

Get a frame count of a MP4 file

I made my own MP4 parser (it recursively parses an atom tree and the content of some atoms).

I already see the duration of a video (in seconds) and I know how to find a start of a frame at a specific time (in seconds). However, I don't know how to find a number of frames (and compute the FPS) without decoding actual frames.

I was using the moov - trak - 0 - mdia - minf - stbl - stsz array, which usually has one value per frame. But now, I found a MP4 video, which has 370 values in "stsz" (370 video samples), but only 184 frames.

Regarding...

"...How to find the number of frames (and thus compute the FPS ) without decoding actual frames?"

"I found a MP4 video, which has 370 values in "stsz" (370 video samples), but only 184 frames."

short version:

FPS = ( stsz_sampleCount / (mdhd_duration / mdhd_timescale) );


details :
Your MP4 seems to have gone through some video trimmer/editor that modified the bytes.

  • The original duration is 6.195 seconds , equates into 370 samples of the stsz atom.
  • The edited duration , based on the edits in the elst atom, is now 2.820 seconds .

I did not check bytes to manually count frames, so I cannot confirm if there is really 370 samples in mdat or if such metadata details were kept unchanged for the sake of future decoders. This means, for example because of how the FPS is calculated using that 370 number, it would be incorrect if the sample count was lower.

FPS calculation for your MP4 file:

  • From mdhd atom get the values of: timescale (=15360) and duration (=95154).
  • Calculate: playTime = ( duration / timescale ) = 6.195 secs ( ie: Math.ceil from 6.194927...).
  • From stsz atom, get the sampleCount (=370).

then:

  • fps = ( sampleCount / playtime ) = 60 FPS ( ie: Math.ceil from 59.725...).
  • frameCount = sampleCount = ( fps * playTime ) = 370 total Frames.


accounting for elst:
You must read the elst (under edts atom) to find out how much of that frame count is "edited" (can be duration trimmed, can be longer frame duration, can be segment time-skipping, etc). The edits affect the overall duration (except if just doing reverse playback).

You can see your elst has only 1 entry (the one segment that will be played) and it says the segment is extracted from time 1.972 seconds and has a duration of 2.820 seconds .

It is the only segment played:
So the actual_playTime duration is 3 seconds ( ie: Math.ceil from 2.8 seconds).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM