2

I am using ffmpeg to extract frame and save it into jpg files as follow.

ffmpeg -i video.avi -r 1 -f image2 -q 1 %05d.jpg

However, how can I get the timestamps information of each extracted frame. For example, I would like to save the jpg file with filename as hh_mm_ss.jpg?

4
  • Take a look at this question asked on Stack Overflow. The accepted answer provides a work-around using ImageMagick, because FFmpeg is not able to do this by itself.
    – Omega
    Commented May 27, 2013 at 11:24
  • @NickvanTilborg I think that the question is asking for timestamps taken from within the video (PTS, Presentation Time Stamp) - so a frame taken from 1 minute 30 seconds into the video would have a filename like 00_01_30.jpg - rather than the timestamp for the system time at which the file was created.
    – evilsoup
    Commented May 27, 2013 at 11:34
  • Ah right, but then a simple rename script should do the trick. @MinSun, can you please confirm what you want?
    – Omega
    Commented May 27, 2013 at 14:44
  • I have the same question, specifically what I believe he's asking (as I am) is for the timestamp from the video, i.e. a frame taken 20 seconds into the video would have a filename with: image-00_20_00.jpg Commented May 16, 2014 at 4:59

1 Answer 1

1

Well, it seems like ffmpeg can't handle this (nor can other popular solutions like VLC media player). A workaround solution I used is to get the duration of the video from ffmpeg -i video_file.mp4 and divide that by the number of frames.

For reference and example here's a bash script I wrote that batch processes a set of videos, splits them into frames (@ 30 fps) and renames the files so they have both the video timestamp (in milliseconds from start of video) and the frame number originally.

I'm sure the script could be more efficient, but it works well enough for my purposes, so hopefully it finds use (since this question is coming up on google searches):

# Regular expression definitions to get frame number, and to get video duration from ffmpeg -i
FRAME_REGEX="frame-([0-9]*)\.jpeg"
LEN_REGEX="Duration: ([0-9]*):([0-9]*):([0-9]*)\.([0-9]*), start"

# Loops through the files passed in command line arguments, 
# example: videotoframes video-*.mp4
#      or: videotoframes file1.mp4 file2.mp4 file3.mp4
for vf in "$@"; do
    video_info=$(ffmpeg -i $vf 2>&1)                                                                                                                        # Get the video info as a string from ffmpeg -i
    [[ $video_info =~ $LEN_REGEX ]]                                                                                                                         # Extract length using reges; Groups 1=hr; 2=min; 3=sec; 4=sec(decimal fraction)
    LENGTH_MS=$(bc <<< "scale=2; ${BASH_REMATCH[1]} * 3600000 + ${BASH_REMATCH[2]} * 60000 + ${BASH_REMATCH[3]} * 1000 + ${BASH_REMATCH[4]} * 10")          # Calculate length of video in MS from above regex extraction

    mkdir frames-$vf                                                # Make a directory for the frames (same as the video file prefixed with "frames-"
    ffmpeg -i $vf -r 30 -f image2 frames-$vf/frame-%05d.jpeg        # Convert the video file to frames using ffmpeg, -r = 30 fps
    FRAMES=$(ls -1 frames-$vf | wc -l)                              # Get the total number of frames produced by the video (used to extrapolate the timestamp of the frame in a few lines)

    # Loop through the frames, generate a timestamp in milliseconds, and rename the files
    for f in frames-$vf/frame-*; do
        [[ $f =~ $FRAME_REGEX ]]                                                        # Regex to grab the frame number for each file
        timestamp=$(bc <<< "scale=0; $LENGTH_MS/$FRAMES*${BASH_REMATCH[1]}")            # Calculate the timestamp (length_of_video / total_frames_generated * files_frame_number)
        `printf "mv $f frames-$vf/time-%07d-%s" $timestamp $(basename $f)`              # Execute a mv (move) command, uses the `printf ...` (execute command returned by printf) syntax to zero-pad the timestamp in the file name
    done;
done;

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .