5
votes

I scan input video to extract certain frames using ffmpeg's select filter. The selection is based on a complex creteria and the number of extracted frames can't be predicted (I'm doing scene detection, but this can be something different - e.g. selecting all the I frames, etc).

What I need is to display the percentage of scanned (decoded) video (e.g. 10% or 90%).


I tried several ways to do this parsing console output as people usually do when dealing with encoding, but it doesn't help with the progress of scanning (e.g. Can ffmpeg show a progress bar? or ffmpeg Progress Bar - Encoding Percentage in PHP)

ffmpeg -progress sceneProgr.txt -i input.wmv -vsync passthrough -an -vf select='gt(scene\,0.2)',showinfo scene%%05d.png

The output this produces is as follows:

<..>    
frame=    0 fps=0.0 q=0.0 size=N/A time=00:00:00.00 bitrate=N/A    
n:0 pts:16550 pts_time:16.55 pos:4205325 fmt:rgb24 sar:0/1 s:640x480 i:P iskey:1 type:I checksum:95895BC9 plane_checksum:[95895BC9]
frame=    1 fps=0.7 q=0.0 size=N/A time=00:00:00.00 bitrate=N/A    
n:1 pts:24591 pts_time:24.591 pos:6685325 fmt:rgb24 sar:0/1 s:640x480 i:P iskey:0 type:P checksum:FF4CC015 plane_checksum:[FF4CC015]
'frame=...' and 'n:...' lines are repeated for each of the extracted frames.

Both frame=... and n:... lines refer to the numbers in the output and therefore can't be used to calculate progress the way people usually do this (as I can't predict how many frames will be found beforehead and besides, they are not uniformly spread across the input video).


If I specify -progress progress.txt parameter, the progress.txt file is as follows:

frame=5
fps=1.2
stream_0_0_q=0.0
total_size=N/A
out_time_ms=43209833
out_time=00:00:43.209833
dup_frames=0
drop_frames=0
progress=continue


frame=6
fps=1.3
stream_0_0_q=0.0
total_size=N/A
out_time_ms=52252200
out_time=00:00:52.252200
dup_frames=0
drop_frames=0
progress=continue

frame=6
fps=1.2
stream_0_0_q=0.0
total_size=N/A
out_time_ms=52252200
out_time=00:00:52.252200
dup_frames=0
drop_frames=0
progress=continue

New portion is written approximately every second and refers to the last extracted frame. Which is somewhat helpful as out_time refers to the last extracted frames' position in the input video, so I can calculate the progress of the scan from it as

progress = out_time_ms/total_input_time 

But this is not ideal as it will be updated only when the new frame which matches the select criteria is extracted. So, If I have a large portion of video with no matching frames, the progress won't change for a lot of time.


Wrapping-up:

I am looking for a way to calculate the progress of video scanning when using select filter.

Any ideas are strongly appreciated.

1
try using stats that report what has NOT been process yet to get at percent complete. each frame has a timestamp. on init , you have var for total duration. those 2 vars always provide measure of progressRobert Rowntree
@RobertRowntree , thanks for taking a look: how do I get this "tats that report what has NOT been process yet" which you refer to?Isantipov
the stdout info on ffmpeg for input media tracks at BEGIN includes 'duration' or the total length in seconds.... can you READ this or get it somehow? Then , use that along with the timestamp on every frame to figure out percent complete .Robert Rowntree
@RobertRowntree , I can get the total length easily, my problem is that I can't get the currently decoded/scanned frame number as ffmpeg outputs the frame stat only if it has passed through the select condition (see the first example output in my question).Isantipov

1 Answers

0
votes

what you get on every frame like data from ffprobe.....

[FRAME]
media_type=video
key_frame=1
pkt_pts=0
pkt_pts_time=0.000000
pkt_dts=0
pkt_dts_time=0.000000
pkt_duration=1
pkt_duration_time=0.040000
pkt_pos=44
width=800
height=542
pix_fmt=yuv420p
sample_aspect_ratio=1:1
pict_type=I
coded_picture_number=0
display_picture_number=0
interlaced_frame=0
top_field_first=0
repeat_pict=0
reference=3
[/FRAME]

what you get at BEGIN

I/stderr  ( 7434): Input #0, image2, from '/storage/sdcard0/Pictures/me374658335.jpg':
I/stderr  ( 7434):   Duration: 00:00:00.04, start: 0.000000, bitrate: N/A
I/stderr  ( 7434):     Stream #0:0: Video: mjpeg, yuvj420p, 1296x972 [SAR 1:1 DAR 4:3], 25 fps, 25 tbr, 25 tbn, 25 tbc
I/stderr  ( 7434): Input #1, mov,mp4,m4a,3gp,3g2,mj2, from '/storage/sdcard0/PictureComment/1347139284144.3gp':
I/stderr  ( 7434):   Metadata:
I/stderr  ( 7434):     major_brand     : 3gp4
I/stderr  ( 7434):     minor_version   : 0
I/stderr  ( 7434):     compatible_brands: isom3gp4
I/stderr  ( 7434):     creation_time   : 2012-09-08 21:21:41
I/stderr  ( 7434):   Duration: 00:00:17.22, start: 0.000000, bitrate: 67 kb/s
I/stderr  ( 7434):     Stream #1:0(eng): Audio: aac (mp4a / 0x6134706D), 44100 Hz, mono, s16, 64 kb/s
I/stderr  ( 7434):     Metadata:
I/stderr  ( 7434):       creation_time   : 2012-09-08 21:21:41
I/stderr  ( 7434):       handler_name    : SoundHandle
I/stderr  ( 7434): [libx264 @ 0x5a070910] using SAR=1/1
I/stderr  ( 7434): [libx264 @ 0x5a070910] using cpu capabilities: ARMv6 NEON
I/stderr  ( 7434): [libx264 @ 0x5a070910] profile High, level 3.2

can you use the frame timestamp along with the Duration to calculate percent complete?