Saturday, October 3rd 2009

ffmpeg

Extracting thumbnails from videos

I was asked to make it easier to navigate a set of videos on a WDTV media player and, after looking around for alternatives, eventually came up with the following Python snippet, which is designed to be dropped into an Automator workflow.

It takes a list of files on standard input and then invokes ffmpeg to extract a thumbnail 30s into the video. sips is then used to resample that image to a smaller size, preserving the aspect ratio:

import sys, os, re

# Handle only these file extensions
pattern = re.compile("^(.+)\.(divx|mov|avi|3gp|wmv|mp4|mkv)$", re.IGNORECASE)

for f in sys.stdin:
  f = f.strip()
  matches = pattern.match(f)
  if matches:
    base = matches.group(1)
    thumb = "%s.jpg" % base
    if os.path.exists(thumb) and os.path.getsize(thumb):
      continue # skip existing non-null files
    os.system("/usr/local/bin/ffmpeg -i '%s' -deinterlace -an -ss 30 -t 00:00:01 -r 1 -y -vcodec mjpeg -f mjpeg '%s' 2>&1" % (f, thumb))
    if os.path.exists(thumb):
      # tweaked rendering to attempt a vertical thumbnail with a center crop
      os.system("/usr/bin/sips '%s' --resampleHeight 160 --cropToHeightWidth 160 120 --out '%s'" % (thumb, thumb))

There’s also a Windows one-liner I was sent that may help:

for %i in (*.avi) do ffmpeg -i "%i" -f mjpeg -t 0.001 -ss 30 -y "%~ni.jpg"