ffprobe
ffprobe -v error -select_streams v:0 -count_packets -show_entries stream=nb_read_packets -of csv=p=0 input.mp4
This actually counts packets instead of frames but it is much faster. Result should be the same. If you want to verify by counting frames change -count_packets
to -count_frames
and nb_read_packets
to nb_read_frames
.
What the ffprobe options mean
-v error
This hides "info" output (version info, etc) which makes parsing easier (but makes it harder if you ask for help since it hides important info).
-count_frames
Count the number of packets per stream and report it in the corresponding stream section.
-select_streams v:0
Select only the first video stream.
-show_entries stream=nb_read_packets
Show only the entry for nb_read_frames
.
-of csv=p=0
sets the output formatting. In this case it hides the descriptions and only shows the value. See FFprobe Writers for info on other formats including JSON.
Only counting keyframes
See Checking keyframe interval?
MP4 Edit List
The presence of an edit list in MP4/M4V/M4A/MOV can affect your frame count.
Also see
mediainfo
The well known mediainfo
tool can output the number of frames:
mediainfo --Output="Video;%FrameCount%" input.avi
MP4Box
For MP4/M4V/M4A files.
MP4Box
from gpac can show the number of frames:
MP4Box -info input.mp4
Refer to the Media Info
line in the output for the video stream in question:
Media Info: Language "Undetermined (und)" - Type "vide:avc1" - 2525 samples
In this example the video stream has 2525 frames.
boxdumper
For MP4/M4V/M4A/MOV files.
boxdumper
is a simple tool from l-smash. It will output a large amount of information. Under the stsz
sample size box section refer to sample_count
for the number of frames. In this example the input has 1900 video frames:
boxdumper input.mp4
...
[stsz: Sample Size Box]
position = 342641
size = 7620
version = 0
flags = 0x000000
sample_size = 0 (variable)
sample_count = 1900
- Be aware that a file may have more than one
stsz
atom.
That's the command I was using for a ffmpeg project, the quality should be good enough. If not, try increasing the bitrate (-b
argument):
ffmpeg -i input.flv -ar 22050 -b 2048k output.avi
Best Answer
I've been playing around with this for a few days. That "ffmpegprogress" thing helped, but it was very hard to get to work with my set up, and hard to read the code.
In order to show the progress of ffmpeg you need to do the following:
Here's how I solved each part:
1. I got the following idea from "ffmpegprogress". This is what he did: one PHP file calls another through an http socket. The 2nd one actually runs the "exec" and the first file just hangs up on it. For me his implementation was too complex. He was using "fsockopen". I like CURL. So here's what I did:
Setting CURLOPT_TIMEOUT to 1 means it will wait 1 second for a response. Preferably that would be lower. There is also the CURLOPT_TIMEOUT_MS which takes milliseconds, but it didn't work for me.
After 1 second, CURL hangs up, but the exec command still runs. Part 1 solved.
BTW - A few people were suggesting using the "nohup" command for this. But that didn't seem to work for me.
*ALSO! Having a php file on your server that can execute code directly on the command line is an obvious security risk. You should have a password, or encode the post data in some way.
2. The "exec.php" script above must also tell ffmpeg to output to a file. Here's code for that:
Note the "1> path/to/output.txt 2>&1". I'm no command line expert, but from what I can tell this line says "send normal output to this file, AND send errors to the same place". Check out this url for more info: http://tldp.org/LDP/abs/html/io-redirection.html
3. From the front end call a php script giving it the location of the output.txt file. That php file will then pull out the progress from the text file. Here's how I did that:
Hope this helps someone.