I am using ffmpeg to extract frames from videos. Using the generic command

ffmpeg -i input.avi out%d.png

I am getting all the frames but I want the names of the frames to indicate their presentation timestamp in the video, i.e. the hour, minute, second and millisecond.

For example if a frame is shown in the movie at time 0 hours 5 minutes 30 seconds and 37 milliseconds, then the output frame should be named: out_00_05_30_37.png.

Any help?


I couldn't figure out any easy way in which I can play with ffmpeg arguments and solve my problem. So I figured another workaround as also suggested by user:dstob.

Let's say I need to store 10 frames per second, then I can iterate the time by 0.1 second and using the -ss argument I can seek the movie to that particular timestamp. Now I will know which frame to extract and the timestamp of that frame too. Following is my code, though it is in MATLAB the overall idea is to iterate over time.

%your movie name
movie = 'movie_name.mp4';

%get the duration of movie in seconds
[to,te] = system(['ffprobe -i ' movie ' -show_format -v quiet | grep duration']);
tmp_ = strsplit(te,'=');
total_time = floor(str2num(tmp_{2}));

%initialize the timer in milliseconds
curr_time = 0;

while curr_time < total_time*1000
    %iterate 10 times in 1 second to get 10 frames
    for i=1:10
            time_ = curr_time + 100*i;                       
            milli_sec = floor(mod(time_,1000));         %milliseconds
            time_ = floor(time_ / 1000);               
            sec = floor(mod(time_,60));                 %seconds;
            time_ = floor(time_ / 60);                 
            min = floor(mod(time_,60));                 %minutes;
            hour = floor(time_ / 60);                   %hour
            frame_name = sprintf('out_%.2d_%.2d_%.2d_%.3d.png',hour,min,sec,milli_sec);

            %Set the ffmpeg command to seek it to the time you want and
            %store the frame
            cmnd = sprintf('ffmpeg -ss %.2d:%.2d:%.2d.%.3d -i %s -frames:v 1 %s',hour,min,sec,milli_sec,movie,frame_name);
    curr_time = curr_time + 1000;         %increment the timer by 1 second

Hope it helps.

  • This might be inaccurate if the frame rate is not estimated correctly (which may happen quite often). What you could do is ffprobe input.mp4 -select_streams v -of compact -show_frames -show_entries frame=best_effort_timestamp_time – and based on these timestamps rename each output file. The rest is just a programming exercise :) – slhck Nov 14 '14 at 5:39
  • What exactly can be inaccurate? The duration of movie using fprobe or using ffmpeg -ss argument? – diggy Nov 14 '14 at 10:15
  • 1
    Well, let's say you don't care what the framerate of the original video is, but you just want to output 10 frames per second of input video by using ffmpeg -ss 0.1 ..., ffmpeg -ss 0.2 etc. In a "real" video, the presentation timestamps of the frames are most probably not at exactly these timestamps, so you may get the same frames output twice. For example, for a 24fps video, the frames are at 0.0, 0.04167, 0.0833, 0.125 etc., so you really want ffmpeg -ss 0.125 in that case. But if you don't care about frame accuracy, then it doesn't matter so much. – slhck Nov 14 '14 at 10:28
  • The frame rates are usually 20+fps and if I am extracting 10 frames per second, then I think the occurrence of redundancy is a bit difficult. Yes, I don't have to worry much about the frame accuracy so this will work fine for me. Thanks for the information :) – diggy Nov 14 '14 at 10:35

If frame-rate is constant then you could just create a script to rename the files. I do not know of a way to do it within ffmpeg.

If you wanted to automate things a bit more you could use ffprobe to generate your frame information and use that time-stamp information to rename the files.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.