Video thumbnails for MythTV

My MythTV box has lots of TV episodes on it, as well as films. The MythTV people have got films all sorted nicely; there’s a thing which looks up the film on IMDB, grabs the plot and the cover art, and makes your list of films look all pretty. However, you can’t do that for episodes of TV shows, or random bits of video; they don’t have DVD cover art, unsurprisingly. Lots of people have come up with the idea of using a thumbnail taken from the video as artwork, which is fine, but most people using MythTV are using mplayer to do the thumbnailing (and play videos). Mplayer doesn’t work on my MythTV box (it crashes X), so I use VLC. VLC can theoretically create thumbnails, but I can’t get it to work properly, so I’ve written a script which does it with totem-video-thumbnailer.

(myth-thumbnailer.py — download)

#!/usr/bin/python
import MySQLdb, os, re

if not os.path.exists("/usr/bin/totem-video-thumbnailer"):
  raise "This script requires totem-video-thumbnailer"

# read DB connection parameters
fp = open("/etc/mythtv/mysql.txt")
DB = {}
for line in fp:
  if line.find("=") != -1:
    k,v = line.strip().split("=",1)
    DB[k] = v

required_keys = ["DBHostName", "DBUserName", "DBName", "DBPassword"]
for k in required_keys:
  if not DB.has_key(k):
    raise "Missing MySQL connection detail: %s" % k

# connect to database
con = MySQLdb.connect(DB["DBHostName"], DB["DBUserName"], DB["DBPassword"], DB["DBName"])
crs = con.cursor()

# get location where thumbnails are stored
sql = "select data from settings where value = 'VideoArtworkDir';"
crs.execute(sql)
VIDEO_DIR = crs.fetchone()[0]
# get all files without covers
cmd = 'totem-video-thumbnailer -j -s 600 "%s" "%s" >/dev/null 2>&1'
sql = "select intid, filename from videometadata where coverfile = 'No Cover';"
crs.execute(sql)
VIDEOS = []
while 1:
  data = crs.fetchone()
  if not data: break
  intid, filename = data
  parts = filename.split(os.sep)
  output = re.sub("[^a-z0-9_]","_","_".join(parts[-2:]).lower()) + ".jpg"
  full_output = os.path.join(VIDEO_DIR, output)
  if os.path.exists(full_output):
    pass
  else:
    cmd_exec = cmd % (filename, full_output)
    print "Thumbnailing", os.path.split(filename)[1]
    os.system(cmd_exec)
    VIDEOS.append((intid,full_output))

sql = "update videometadata set coverfile = %s where intid = %s limit 1;"
for intid, thumbnail in VIDEOS:
  crs.execute(sql, (thumbnail, intid))
  print "Added %s to database" % thumbnail

10 Responses to “Video thumbnails for MythTV”

  1. Nice solution :)

    Elzapp
  2. What would be cool is if you could get moving thumbnails ala youporn.com (best example I could think of!), I imagine this wouldn’t be much harder to do

    Thom
  3. Thom: that’d require MythTV itself to do some of the work, I think. Hm…I wonder if animated gifs would work?

    sil
  4. .

    Tom
  5. .

    Tom
  6. Just so you know there are some Python bindings in MythTV now which make writing little scripts like this easier. They handle connecting to the myth backend and database getting settings etc. They will be included in the upcoming 0.21 release.

    hads
  7. hads: ooh, that’s rather cool. I like the sound of those!

    sil
  8. Do I have to change passwords aor anything? Yunno, alter the script in any way - or just run it?

    mat
  9. mat: should just work, as far as I am aware.

    sil
  10. Here’s a diff that captures the error output (in my case, I was having a problem where I hadn’t installed certain codecs in totem, so it couldn’t capture the thumbnail) and displays them (and doesn’t update the DB unless there’s no error).

    === modified file ’covers_for_missing.py’
    — covers_for_missing.py       2008-03-18 19:05:17 +0000
    +++ covers_for_missing.py       2008-03-18 19:11:58 +0000
    @@ -1,5 +1,9 @@
     #!/usr/bin/python
    -import MySQLdb, os, re
    +
    +import os
    +import re
    +import commands
    +import MySQLdb
     
     if not os.path.exists(”/usr/bin/totem-video-thumbnailer”):
       raise ”This script requires totem-video-thumbnailer”
    @@ -26,7 +30,7 @@
     crs.execute(sql)
     VIDEO_DIR = crs.fetchone()[0]
     # get all files without covers
    -cmd = ’totem-video-thumbnailer -j -s 600 ”%s” ”%s” >/dev/null 2>&1′
    +cmd = ’totem-video-thumbnailer -j -s 600 ”%s” ”%s”‘
     sql = ”select intid, filename from videometadata where coverfile = ’No Cover’;”
     crs.execute(sql)
     VIDEOS = []
    @@ -42,8 +46,11 @@
       else:
         cmd_exec = cmd % (filename, full_output)
         print ”Thumbnailing”, os.path.split(filename)[1]
    -    os.system(cmd_exec)
    -    VIDEOS.append((intid,full_output))
    +    status, output = commands.getstatusoutput(cmd_exec)
    +    if not status:
    +      VIDEOS.append((intid,full_output))
    +    else:
    +      print status, output, cmd_exec
     
     sql = ”update videometadata set coverfile = %s where intid = %s limit 1;”
     for intid, thumbnail in VIDEOS:

    https://launchpad.net/~mthaddon

Leave a Reply

OpenID is a decentralised authentication system. If you use LiveJournal or Vox you already have an OpenID; just use the URL of your homepage there. See also how to get yourself an OpenID.