3

I have to create 'preview' on video progress hover. I'm doing with a sprite image and WebVTT file. Using ffmpeg and imagemagick. However generating thumbnails from a mp4 video is really damn slow (20-30 minutes for 2hrs and 20 min long video). The video is Full HD, H246 encoded, 2GB big. The command used

"ffmpeg.exe -i largevideo.mp4 -f image2 -bt 20M -vf fps=1/5 thumbs-%03d.jpg"

Which means thumb for every 5 secs of the video. Is there a way to make it faster? Videos in prod can be even bigger.

OS: Win10, ImageMagick is used later to create the sprite from all the thumbnails created with ffmpeg.

Expressingx
  • 1,480
  • 1
  • 14
  • 39
  • What is `$"` please? Which part uses **ImageMagick** please? What's a *"video progress hover"* please? What OS are you using please? – Mark Setchell Apr 22 '20 at 17:32
  • Did you notice I asked you to clarify 3 things? – Mark Setchell Apr 22 '20 at 17:56
  • Better now? Although I don't see how it would help. – Expressingx Apr 22 '20 at 18:09
  • No. It's still unclear what you are doing. If **ImageMagick** is taking all the time, you should be showing your **ImageMagick** code. If not, you shouldn't tag with **ImageMagick**. – Mark Setchell Apr 22 '20 at 18:19
  • Is is better now without the `imagemagick` tag? I think I've clearly mentioned that `ffmpeg` is the one which is slowing me down. This is the reason im showing the `ffmpeg` command. – Expressingx Apr 22 '20 at 18:25
  • Does it have to be every 5 seconds, or would key frames suffice? – llogan Apr 22 '20 at 18:29
  • No, it will depend on configuration, but I've also tested with 1 and 5 min and still takes 10+ minutes. – Expressingx Apr 22 '20 at 18:35
  • What I meant was do you require your screen shots to be taken once per 5 seconds, or can a somewhat arbitrary interval (with timestamps included) work for you? Note you can notify me of a reply with @llogan (I only saw your reply because the tab was still open). – llogan Apr 22 '20 at 18:39
  • @llogan interval is fine as well, as long as its faster. – Expressingx Apr 22 '20 at 18:41
  • 1
    You could *try* doing 2 halves, or 4 quarters, in parallel. Use `ffprobe` to get the length, then start two `ffmpeg` commands in parallel. The first will run from time=0 to time=total/2 and prepend output filenames with `A`, the second will start at time=t/2 and prepend output filenames with `B`. – Mark Setchell Apr 22 '20 at 18:47

1 Answers1

6

Skip everything except keyframes:

ffmpeg -skip_frame nokey -i input.mp4 -vsync passthrough thumbs-%03d.jpg

Also see:

llogan
  • 121,796
  • 28
  • 232
  • 243
  • Well.. I think generating thumbnails based on keyframes only is more than enough for now. And x100 times faster. Thanks! – Expressingx Apr 22 '20 at 19:03
  • @Expressingx You could also use ffmpeg to make the sprite in the same command, but it's worth asking as a separate question (search first in case already asked and answered). – llogan Apr 22 '20 at 19:06
  • Oh really? That would make things simpler. Because I'm currently using `imagemagick` to resize the thumbnails, calculate grid size, create the sprite etc. And also using another lib, complicating deployment a bit more. I'll search a bit, if not I'll ask. – Expressingx Apr 22 '20 at 19:12
  • 1
    @Expressingx See [scale](https://ffmpeg.org/ffmpeg-filters.html#scale) and [tile](https://ffmpeg.org/ffmpeg-filters.html#tile) (or [xstack](https://ffmpeg.org/ffmpeg-filters.html#xstack)) filters. – llogan Apr 22 '20 at 19:16
  • Nice `-vf "scale=100:60,tile=5x30"` thanks! However, now I don't know each thumbnail tile timestamp so I can generate proper `.vtt` file, but I'll have to figure it out I guess. I cannot tag you for some reason. – Expressingx Apr 22 '20 at 19:38
  • Okay, If someone needs it: `ffprobe -v error -skip_frame nokey -show_entries frame=pkt_pts_time -select_streams v -of csv=p=0 input.mp4` this gives each keyframe timestampe in seconds. E.g. `8499.991500` which results to `02:21:39.9920000` in the format of: `hh:mm:ss` – Expressingx Apr 22 '20 at 20:09
  • @Expressingx Looks like you missed the [Get keyframe intervals](https://stackoverflow.com/a/18088156/) link in my answer. You can use `scale=100:-1` or `scale=-1:60` to automatically calculate the other dimension while preserving aspect ratio. – llogan Apr 23 '20 at 02:10