« Zabbix + ssh tunnel with AutoSSHLocal LAN »

Automating some handy MythTV scripts

2007/08/13

  02:08:26 am, by   , 1433 words  
Categories: MythTV, MythTV

Automating some handy MythTV scripts

I've been looking at having the MythTV 'Videos' area have some useful information gatered from the internet - say for movies and such.

So, I've gathered up a couple of scripts, and done some extra work to customize them for my needs:

  • a script that goes through all the sub-directories of the /Videos/ directory, and create thumbnails of the videos as needed. These look great and really make for a more visual MythTV experience
  • a script that goes through the 'tv' sub-directory, and look up the TV related information, such as plot, running time, etc.
  • a script that goes through the 'movies' sub-directory and looks up the movie information from IMDb, the Internet Movie Database. I haven't used this one yet, so we'll see if it works out-of-the-box for my scenario.

So, first the thumbnails script - most of this script was from a bash shell script that I got at http://MythiC.TV - and converted to Perl:

mythtv bin # cat screenshooter.pl
#!/usr/bin/perl

#use strict;
use warnings;

# to determine hostname
use Sys::Hostname;

# MySQL access
use DBI;
use DBD::mysql;

# for file name operations
use File::Copy;
use File::Basename;

# converted to Perl by Torben Sorensen
# previous header comments from bash version:

# Written by Bob Igo from the MythTV Store at http://MythiC.TV
# with contributions from TJC

# This is alpha code to auto-generate thumbnails for previews in MythVideo.
# It won't currently work on some filenames that have spaces in them.
# It's surely just a matter of escaping or quoting, but I have yet to find
# the right incantation.

# NOTE: the above has been fixed in the Perl version by getting the video filenames directly from the MythTV database

# limitations:
# --
# In an MBE/SBE/FE setup this might get the settings for the wrong machine...
# The script has no AI to know if a grabbed frame is useful to identify the video, only that it was able to grab it.
# Doesn't clean up after itself if videos are deleted, though MythTV may do this on its own.
# Surely more limitations I can't think of because it's my baby :)




use vars qw/ %opt /;

sub init()
{
    use Getopt::Std;
    my $opt_string = 'v:s:chd';
    getopts( "$opt_string", \%opt ) or usage();
    usage() if $opt{h};
}

# help Message about this program and how to use it
sub usage()
{
    print STDERR [lt][lt] "EOF";

USAGE: $0 [-s SECONDS] [-c] [-d] [-m DATABASESERVER]
          [-b DATABASETABLE] [-u MYTHTVDBUSER] [-p MYTHTVDBPASS]

 -s [integer] : number of seconds to skip before capturing (defaults to 270)
 -c: clobber any previous screenshot found for this video
 -d: debug - output additional information while processing

 -m:[string] : MySQL server name (defaults to localhost)
 -b:[string] : MySQL MythTV database (defaults to mythconverg)
 -u:[string] : MythTV MySQL user (defaults to mythtv)
 -p:[string] : MythTV MySQL user's password (defaults to mythtv)

EXAMPLE: $0 -v /myth/video/HDTV/ -c -s 30 -d -m myth -b mythdata -u mythdbuser -p mythdbpass

EOF
    exit;
}


# PROGRAM START

# check commad line params
init();

# set defaults
my $skip_ahead = 270;
my $clobber = 0;
my $debug = 0;

my $mysql_server = "localhost";
my $mysql_database ="mythconverg";
my $mysql_user = "mythtv";
my $mysql_password = "mythtv";

# use passed in parameters if supplied
if ( $opt{s} ) { $skip_ahead = $opt{s}; }
if ( $opt{c} ) { $clobber = 1; }
if ( $opt{d} ) { $debug = 1; }

if ( $opt{m} ) { $mysql_server = $opt{m}; }
if ( $opt{b} ) { $mysql_database = $opt{b}; }
if ( $opt{u} ) { $mysql_user = $opt{u}; }
if ( $opt{p} ) { $mysql_password = $opt{p}; }


# get this box's hostname
my $host_name = hostname();
if ( $debug )
{ print "Host: '$host_name'\n"; }

# connect to database
#my $db = mysql-[gt]connect($mysql_server,$mysql_database,$mysql_user,$mysql_password)
#   or die(mysqlerr());
my $dbh = DBI-[gt]connect("dbi:mysql:database=$mysql_database:host=$mysql_server",$mysql_user,$mysql_password)
   or die($DBI::errstr);

# if we were passed the '-v'


# retrieve the 'videos' directory from mythtv's database
my $video_capture_home_sql = "select data from settings where value='VideoArtworkDir' and hostname='$host_name'";
my $queryh = $dbh-[gt]prepare($video_capture_home_sql);
$queryh-[gt]execute()
   or die($DBI::errstr);
my @array = $queryh-[gt]fetchrow;
my $video_capture_home = shift @array;

# look for this directory
if ( ! ( -d $video_capture_home ) )
{ die "ERROR: Directory '$video_capture_home' does not exist, nowhere to put the screen shot!\n\n"; }
else
{
    if ( $debug )
    { print "Saving Screen shots to '$video_capture_home'\n"; }
}

# query the mythtv database for all video filenames
my $video_filename_query = "select filename from videometadata";
$queryh = $dbh-[gt]prepare($video_filename_query);
$queryh-[gt]execute()
   or die($DBI::errstr);
my $num_videos = $queryh-[gt]rows;

if ( $debug )
{ print "Found $num_videos video(s) in MythTV database ... processing ... \n\n"; }

# create an array holding all files to be processed
my @file_array;
my @temp_array;
while ( @temp_array = $queryh-[gt]fetchrow )
{
   my $temp_file = shift @temp_array;
   push( @file_array, $temp_file);
}

my $video_counter = 0;
my $videofile;
foreach $videofile ( @file_array )
{

    # keep track of how many files we're processing
    $video_counter++;

    # flag to avoid clobbering coverfile
    my $avoid_clobber = 0;

    # escape special characters for mysql
    my $quote_videofile = $dbh-[gt]quote( $videofile );

    if ( $debug )
    { print "Video $video_counter - Working on file '$videofile' ...\n"; }

    if ( $clobber == 0 )
    {
        # Since we're not clobbering, first check to see if this video already has a coverfile entry in MySQL
        my $cover_exists_sql = "select coverfile from videometadata where filename=$quote_videofile";
        $queryh = $dbh-[gt]prepare($cover_exists_sql);
        $queryh-[gt]execute()
           or die($DBI::errstr);
        @array = $queryh-[gt]fetchrow;
        my $current_coverfile = shift ( @array );

        # Mythtv stores "No Cover" in the database if there is no pre-existing cover in the database
        if ( ! ( $current_coverfile eq "No Cover") )
        {
            if ( $debug )
            { print " - Found '$current_coverfile' in database\nRESULT: leaving it alone.  To override, add the -c flag to the command.\n\n"; }
            $avoid_clobber = 1;
        }
        else
        {
            if ( $debug )
            { print " - Found '$current_coverfile' as a coverfile for '$videofile' ... generating snapshot ...\n"; }
        }

    }

    if ( ! ( $avoid_clobber ) )
    {

        # The video we're processing may be shorter than SKIPAHEAD seconds.
        # Keep trying to capture until we find a SKIPAHEAD value within the length of the video.
        # Give up if we reach 0 seconds.
        my $temp_skip_ahead = $skip_ahead;

        my $shotfile = "";
        while ( ( !(  $shotfile ) ) and ( $temp_skip_ahead != 0 ) )
        {

            # create the snapshot of the video file
            $shotfile =`/usr/local/bin/mplayer-screenshot.exp "$videofile" $temp_skip_ahead`;
            chomp( $shotfile );

            # error checking on that last command
            if ( $? )
            { print "ERROR: Snaphot call resulted in error #: '$?'\n\n"; }

            # get the name of the outputted snapshot
            $shotfile =~ /'(.*)'/;
            $shotfile = $1;

            $temp_skip_ahead = int( $temp_skip_ahead / 2 );

            if ( ( $debug ) [amp][amp] ( $shotfile ) )
            {
                my $temp_shot = "";
                if ( -z $shotfile )
                { $temp_shot = " is empty."; }
                else
                { $temp_shot = " image captured."; }

                print "ShotFile: '$shotfile' - $temp_shot\n";
            }
        }

        my ( $video_file_base, $video_dir) = fileparse($videofile);
        my $video_capture_filename = "$video_capture_home/$video_file_base.png";
        if ( $shotfile )
        {
            # Now, the video_capture is taken, and the name of the shot is in $SHOTFILE

            # Rename the snapshot file and move it to the place where video capture images live.
            move( $shotfile, $video_capture_filename )
               or die("ERROR: Unable to move file '$shotfile' to '$video_capture_filename'.\n\n");

            # change ownership to mythtv user
            my $user = "mythtv";
            my ($login,$pass,$uid,$gid);
            ($login,$pass,$uid,$gid) = getpwnam($user)
                    or die "ERROR: '$user' not found in passwd file\n\n";
            chown $uid, $gid, $video_capture_filename
                    or die "ERROR: Unable to chown '$video_capture_filename' to user '$user'\n\n";

            # update the mythtv database
            my $quote_video_capture_filename = $dbh-[gt]quote( $video_capture_filename );
            my $myth_update_query = "update videometadata set coverfile=$quote_video_capture_filename where filename=$quote_videofile";
            $queryh = $dbh-[gt]prepare($myth_update_query);
            $queryh-[gt]execute()
               or die($DBI::errstr);

            # output debug info
            if ( $debug )
            { print "RESULT: saved snapshot file to $quote_video_capture_filename.\n\n"; }

        }
        else
        {
            print "ERROR: No image could be captured from '$videofile'. Continuing ...\n\n";
        }
    } # end of no clobber if
} # end of do while video files loop

if ( $debug )
{ print "Done processing files.\n\n"; }
exit;

Then, connect this to cron and have it run every 10 minutes - that way new thumbnails are created regularly.

Create a small script to handle the cron task, as the MythTV user:

$ nano /home/mythtv/mythtv_video_thumbs.sh

#!/bin/bash
/usr/local/bin/screenshooter.pl > /dev/null 2>&1

$ chmod +x mythtv_video_thumbs.sh

Now make a crontab entry - again had to do this as root for some reason:

# crontab -u mythtv -e

and add this code:

*/10 * * * * /home/mythtv/mythtv_video_thumbs.sh

Ok, so thats the video thumbnails being generated automagically - next is the descriptions and other data ...

Feedback awaiting moderation

This post has 42 feedbacks awaiting moderation...


Form is loading...

March 2024
Mon Tue Wed Thu Fri Sat Sun
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
 << <   > >>
LAN / Networks related items ...

Search

  XML Feeds

powered by b2evolution free blog software