Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I'd like to extract one frame per minute from a video, starting from a specified offset. For example, say the offset is 00:01 (mm:ss), then I'd like to extract 00:01, 01:01, 02:01, and so on.

The problem I've run into is that ffmpeg seems to be rounding my offset down to the nearest minute. If I ask for 00:01, I get 00:00, 01:00, 02:00, and so on. If I give it 01:01, I get 01:00, 02:00, 03:00, and so on.

Additional constraints:

  • Subtitles must be rendered. They're in a .ass file in the same directory.
  • Each frame should have some text written in the upper-left corner

Here's how I'm invoking ffmpeg for offset 00:01:

ffmpeg -y -i "HorribleSubs.mkv" -ss 00:00:01 \
 -vf "ass=HorribleSubs.ass,fps=1/60,drawtext=fontfile=...: fontcolor=white: fontsize=32: x=10: y=10: text=HorribleSubs" \
 "screenshots/%03d-HorribleSubs.png"

And here's the output (I ctrl+c'd it when I realized it wasn't working):

ffmpeg version git-2013-06-15-8a79a00 Copyright (c) 2000-2013 the FFmpeg developers
  built on Jun 15 2013 16:36:45 with gcc 4.7 (Ubuntu/Linaro 4.7.3-1ubuntu1)
  configuration: --prefix=/home/sircmpwn/ffmpeg_build --extra-cflags=-I/home/sircmpwn/ffmpeg_build/include --extra-ldflags=-L/home/sircmpwn/ffmpeg_build/lib --bindir=/home/sircmpwn/bin --extra-libs=-ldl --enable-gpl --enable-libass --enable-libfdk-aac --enable-libmp3lame --enable-libopus --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-nonfree --enable-x11grab --enable-libfreetype
  libavutil      52. 35.101 / 52. 35.101
  libavcodec     55. 16.100 / 55. 16.100
  libavformat    55.  8.102 / 55.  8.102
  libavdevice    55.  2.100 / 55.  2.100
  libavfilter     3. 77.101 /  3. 77.101
  libswscale      2.  3.100 /  2.  3.100
  libswresample   0. 17.102 /  0. 17.102
  libpostproc    52.  3.100 / 52.  3.100
Input #0, matroska,webm, from 'HorribleSubs.mkv':
  Metadata:
    creation_time   : 2013-05-26 13:34:41
  Duration: 00:23:42.11, start: 0.000000, bitrate: 1900 kb/s
    Stream #0:0: Video: h264 (High), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 30.30 fps, 30.30 tbr, 1k tbn, 59.94 tbc (default) (forced)
    Stream #0:1: Audio: aac, 44100 Hz, stereo, fltp (default) (forced)
    Stream #0:2: Subtitle: ssa (default) (forced)
Codec 0x18000 is not in the full list.
    Stream #0:3: Attachment: unknown_codec
    Metadata:
      filename        : OpenSans-Semibold.ttf
      mimetype        : application/x-truetype-font
[Parsed_ass_0 @ 0x19b2100] Added subtitle file: 'HorribleSubs.ass' (9 styles, 374 events)
Output #0, image2, to 'screenshots/%03d-HorribleSubs.png':
  Metadata:
    encoder         : Lavf55.8.102
    Stream #0:0: Video: png, rgb24, 1280x720 [SAR 1:1 DAR 16:9], q=2-31, 200 kb/s, 90k tbn, 0.02 tbc (default) (forced)
Stream mapping:
  Stream #0:0 -> #0:0 (h264 -> png)
Press [q] to stop, [?] for help
frame=    7 fps=0.5 q=0.0 Lsize=N/A time=00:07:00.00 bitrate=N/A dup=1 drop=0    
video:4306kB audio:0kB subtitle:0 global headers:0kB muxing overhead -100.000499%
Received signal 2: terminating.
share|improve this question
    
I believe this is possible with the select filter. I am unable to test at this time to provide a complete answer. –  LordNeckbeard Jun 17 '13 at 17:05

2 Answers 2

up vote 1 down vote accepted

FFmpeg can't really cut everywhere when using h.264 video encoding (which is your case: Stream #0:0 -> #0:0 (h264 -> png)).

To make FFmpeg cut everywhere you will need to re-encode the video. try the following:

ffmpeg -y -ss 00:00:01 -i "HorribleSubs.mkv" -c:v mpeg2video -g 1 -vf "ass=HorribleSubs.ass,fps=1/60,drawtext=fontfile=...: fontcolor=white: fontsize=32: x=10: y=10: text=HorribleSubs" "screenshots/%03d-HorribleSubs.png"

share|improve this answer
    
After my own research, I've also found that it'll probably need to be re-encoded. Can you suggest a cheaper encoding than matroska? Re-encoding has added huge amounts of execution time to the script. –  Drew DeVault Jun 21 '13 at 5:35

This might work: put the -ss in front of the -i so ffmpeg seek to that position before actually doing all the filtering and encoding. Or try LordNeckbeard's solution to use select filter, but I got confused about all those options and variables.

You can go to ffmpeg-users mailing list for some more help.

share|improve this answer
    
This is a very skimpy answer, it should almost be a comment. –  David Jun 18 '13 at 22:03
    
Two problems: one: it doesn't work, and two: it unacceptably reduces seeking accuracy. –  Drew DeVault Jun 19 '13 at 0:06
    
@David Yes, that is what I want to do, but adding a comment to a question requires 50 reputations, but I am a new user to Superuser. :( –  Timothy_G Aug 28 '13 at 2:40

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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