From MythTV Official Wiki
Jump to: navigation, search

Important.png Note: The correct title of this article is It appears incorrectly here due to technical restrictions.

List-add.png Todo: Script needs to be updated to use Perl bindings for database credentials. is a perl script to scan your database for MythVideo videos that don't have preview icons or cover images, and generate a preview icon by taking a screenshot out of the video.

See also Discussion page.



# this script will loop through all videos in videometadata,
# capture a screenshot for each, move each screenshot to the
# COVERPATH dir, and update each row in videometadata with
# the appropriate information. Only rows with coverfile=
# 'No Cover' are processed. A percentage of the length
# of each video is used for the capture position to account
# for clips of widely varying lengths.

# This script is mostly based on a bash script posted to the mythtv-users
# mailing list by damonkeiman-at-hotmail-dot-com; viewable at:
# <>.
# I had trouble getting it to work as-is (it kept losing parts of the output
# from the first mysql query), and wound up rewriting it in Perl to get it to
# work.

# Portions written by me are
# Copyright (C) 2007 David Miller <>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# GNU General Public License for more details.
# The full text of the GNU General Public License can be viewed at
# <>.

use DBI;

if (getpwuid($>) ne "mythtv") {
  print STDERR "You must run this script as the mythtv user.\n";
  exit 1;

# set some defaults
my %config = (
  DBHostName => 'localhost',
  DBUserName => 'mythtv',
  DBName     => 'mythconverg',
  DBPassword => '',

# read in the real ones
open MYSQLDATA, "<", "/etc/mythtv/mysql.txt";
while (my $line = <MYSQLDATA>) {
  if ($line =~ /^(DB\S+)=(.*)\s*$/) {
    $config{$1} = $2;

# intialize variables
my $OUTPATH='/tmp';
my $COVERPATH='/home/mythtv/.mythtv/MythVideo';
my $FRAME='00000002.jpg';
my $SKIPOFFSET='35';

my $dsn = "DBI:mysql:host=" . $config{DBHostName} . ":database=" . $config{DBName};
my $dbh = DBI->connect($dsn, $config{DBUserName}, $config{DBPassword});

my $sth = $dbh->prepare("SELECT intid, filename FROM videometadata WHERE coverfile='No Cover'");
while (my ($ID, $FILE) = $sth->fetchrow_array()) {
  print "MYSQLRESULT: id=$ID, file=$FILE\n";

  # if video is mpeg, use ffmpeg12 codec to avoid pixelation
  my @VC = ();
  if ($FILE =~ /.*\.mp[e]*g/) {

  # if video is a .iso or a .img, add dvd:\\1 -dvd-device
  my @dvd = ();
  if ($FILE =~ /\.(iso|img)$/i) {
    @dvd=("dvd://1", "-dvd-device");

  # use mplayer to get length of video in seconds
  my $length=`echo -n q | mplayer -vo null -nosound -identify -ac null -vc null "$FILE" | egrep "^(ID_LENGTH=)" | cut -d '=' -f 2`;

  if (!$length) {
    print "mplayer was unable to get the $FILE length.\n";

  my $SKIP = int(($length * $SKIPOFFSET) / 100);
  print "calculated skip seconds: $SKIP\n";

  # command to get jpeg from video

  # move jpeg from outpath to coverpath
  print "mv $OUTPATH/$FRAME $COVERPATH/intid.$ID.jpg\n";
  if (0 != system("mv", "$OUTPATH/$FRAME", "$COVERPATH/intid.$ID.jpg")) {
    print "Move failed. Will not update videometadata table...\n";
    unlink "$OUTPATH/$FRAME";
  else {
    # SQL to update table with cover image path
    my $usth = $dbh->prepare("UPDATE videometadata SET coverfile='$COVERPATH/intid.$ID.jpg' WHERE intid=$ID LIMIT 1");