Thanks for the info, but it seems to be a lot more work then I'm doing now. I think it will work for my movies, but TV shows would be a nightmare.
I currently use a modified (Unix) PHP script...
Code: Select all
<?php
/**********************************************************************
Grabber.php
VERSION: 0.1.4
DATE: 20 August 2007
AUTHOR: Joshua Glemza
CONTACT: josh uknow hwarf.com
WEBSITE: http://hwarf.com/
LICENSE
This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 License.
To view a copy of this license, visit
http://creativecommons.org/licenses/by-sa/3.0/us/ or send a letter to
Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
AKNOWLEDGEMENTS:
This script utilizes the TheTVDB.com website. Many thanks to them!
http://www.thetvdb.com/
OVERVIEW:
This script will take the information from a filename and create the
preview image and xml data needed by ATVFiles. From a given path it
will recursively traverse the directory and add xml to all video files.
CURRENT LIMITATIONS
*The file structure must be in this format: SHOWNAME S00E00whatever.ext
Example: Entourage S03E20 - Adios Amigos.avi
*Does not currently work if you need to go through an HTTP proxy server.
*Requires that mplayer be installed if png images are created.
USAGE:
php -q Grabber.php /path/to/folder/root ACTION
An action can be:
NEW: Create png/xml for files that do not have them
ALL: Recreate all jpg/xml data
THINGS TO DO:
*Support more filename formats. ie, how they're posted.
*Give an error if no tv show is found.
*Input validation for multiple tv show names.
*Some png screens are blank.
**********************************************************************/
//////////// Configuration Variables ////////////
$createPng = 'y'; //y for yes, n for no
$pngSeconds = 120; //seconds into video file to create png
//$pngWidth = 400; //Width of the png file
$mirrorUrl = ''; //tvdb.com mirror url, blank for default
////////////////////////////////////////////////
# Takes a show name and returns the seriesid from tvdb
function getSeriesId($show_name, $mirrorUrl)
{
$show_name = urlencode($show_name);
// Get seriesid
$seriesId_xml = file_get_contents("$mirrorUrl/GetSeries.php?seriesname=$show_name");
$seriesXml = new SimpleXMLElement($seriesId_xml);
// Display all the shows found and select the correct one
$counter = 1;
$selection = 1;
$output = '';
foreach($seriesXml->Item as $Item)
{
$output .= $counter . ". " . $Item->SeriesName . "\n";
$counter++;
}
if($counter > 2)
{
print "####################################\n";
print "Multiple TV Shows found:\n";
print $output;
print "####################################\n\n";
print "Please choose the correct show: ";
$selection = fread(STDIN, 80);
print "\n\n";
}
$seriesid = $seriesXml->Item[$selection-1]->id;
return $seriesid;
}
# Takes a seriesid, season number, episode number and return xml data
function getEpisodeInfo ($seriesid, $season, $episode, $mirrorUrl)
{
// Get episodeid
$episodeId_xml = file_get_contents("$mirrorUrl/GetEpisodes.php?seriesid=$seriesid&season=$season&episode=$episode");
$episodeXml = new SimpleXMLElement($episodeId_xml);
$episodeid = $episodeXml->Item[1]->id;
// Get episode info
$episodeInfo_xml = file_get_contents("$mirrorUrl/EpisodeUpdates.php?lasttime=0&idlist=$episodeid");
$episodeInfoXml = new SimpleXMLElement($episodeInfo_xml);
return $episodeInfoXml;
}
# Takes episodeInfo and returns ATVFiles formatted XML
function createXmlData($episodeInfo, $show_name)
{
$atv_xml = "<media type=\"TV Show\">\n";
$atv_xml .= " <title>S" . $episodeInfo->Item[1]->SeasonNumber . ".E" . $episodeInfo->Item[1]->EpisodeNumber . ". " . $episodeInfo->Item[1]->EpisodeName . "</title>\n";
$atv_xml .= " <artist>" . $show_name . "</artist>\n";
$atv_xml .= " <summary>" . $episodeInfo->Item[1]->EpisodeName . "</summary>\n";
$atv_xml .= " <description>\n";
$atv_xml .= " " . $episodeInfo->Item[1]->Overview . "\n";
$atv_xml .= " </description>\n";
$atv_xml .= " <episode>" . $episodeInfo->Item[1]->EpisodeNumber . "</episode>\n";
$atv_xml .= " <season>" . $episodeInfo->Item[1]->SeasonNumber . "</season>\n";
$atv_xml .= " <published>" . $episodeInfo->Item[1]->FirstAired . "</published>\n";
$atv_xml .= " <rating>TV-PG</rating>\n";
$atv_xml .= "</media>";
return $atv_xml;
}
# This function takes a directory and returns all of the files within
# the directory that match a given extension.
# Taken from: http://www.hawkee.com/snippet/1281/
function directoryToArray($directory, $extension="", $full_path = true)
{
$array_items = array();
if ($handle = opendir($directory))
{
while (false !== ($file = readdir($handle)))
{
if ($file != "." && $file != "..")
{
if (is_dir($directory. "/" . $file))
$array_items = array_merge($array_items, directoryToArray($directory. "/" . $file, $extension, $full_path));
else
{
if(!$extension || (ereg("." . $extension, $file)))
{
if($full_path)
$array_items[] = $directory . "/" . $file;
else
$array_items[] = $file;
}
}
}
}
}
closedir($handle);
return $array_items;
}
// Was the path and action given on the command line?
if ($argv[1] == '' || $argv[2] == '')
die("Grabber.php\nError: Incorrect usage.\nExample: php -q tvdb_grabber.php /path/to/root/folder NEW|ALL\n\n");
// Get a list of all video files from the given path based on extension
$root_path = $argv[1];
$vid_extensions = array ("mpg", "avi", "vob", "mp4", "mkv", "mpg", "m4v", "mov");
$video_files = array();
foreach ($vid_extensions as $ext)
$video_files = array_merge($video_files, directoryToArray($root_path, $ext, true));
sort($video_files);
// Loop through the returned video files based on desired action
$action = $argv[2];
switch($action)
{
// Create a jpg/xml pair for the given path only if they don't exist
case "NEW":
case "ALL":
$show_name = '';
//Loop through all of the video files found
foreach ($video_files as $path)
{
// Strip the file extension from the video path
$current_path = preg_replace("/\.[0-9A-Za-z][0-9A-Za-z][0-9A-Za-z]$/", "", $path);
// Remember the orginal path and the stripped extension path
$original_path = $path;
$path = $current_path;
// Does the xml/png file exist for this video
if (file_exists($current_path . ".xml") && file_exists($current_path . ".png") && $action != "ALL");
// The file doesn't exists. Create it.
else
{
// Parse the video information
preg_match("/[Ss][0-9][0-9][Ee][0-9][0-9]/", $current_path, $matches);
if ($matches[0] != '')
$season_episode = trim($matches[0]);
else
print "Could not be parsed: $current_path\n";
// Is the season and episode info there?
if ($season_episode != '')
{
$current_path = preg_replace("/[Ss][0-9][0-9][Ee][0-9][0-9].*$/", "", $current_path);
$current_show = preg_replace("/^.*\//", "", $current_path);
$current_show = preg_replace("/\./", " ", $current_show);
$current_show = trim($current_show);
// Is the show name present?
if ($current_show != '')
{
// Is this the same show that we already looked up?
if ($show_name == $current_show);
else
{
// Get a tvdb mirror
if ($mirrorUrl == '')
{
// Query tvdb for a list of mirrors
$mirrors_xml = file_get_contents("http://thetvdb.com/interfaces/GetMirrors.php");
$mirrorsXml = new SimpleXMLElement($mirrors_xml);
$mirrorUrl = $mirrorsXml->Item[0]->interface;
}
$series_id = getSeriesId($current_show, $mirrorUrl);
$show_name = $current_show;
}
// Parse out the Season number
preg_match("/[Ss][0-9][0-9]/", $season_episode, $matches);
$season = $matches[0];
$season = str_ireplace("S0", "", $season);
$season = str_ireplace("S", "", $season);
// Parse out the Episode number
preg_match("/[Ee][0-9][0-9]/", $season_episode, $matches);
$episode = $matches[0];
$episode = str_ireplace("E0", "", $episode);
$episode = str_ireplace("E", "", $episode);
// Get the episode information
$episodeInfo = getEpisodeInfo($series_id, $season, $episode, $mirrorUrl);
// Create the ATVFiles XML data
print "Creating XML for $show_name $season_episode\n";
$episodeXml = createXmlData($episodeInfo, $show_name);
file_put_contents($path . ".xml", $episodeXml);
// Create the screenshot png
if ($createPng == 'y')
{
$original_path = escapeshellarg($original_path);
print "Creating PNG for $show_name $season_episode\n";
exec("/usr/bin/mplayer -really-quiet -nosound -ss $pngSeconds -frames 2 -vo tga $original_path > /dev/null 2>&1");
// If two screenshots exist, delete the second one
if (file_exists("./00000002.tga"))
{
rename("00000002.tga", $path . ".png");
unlink("./00000001.tga");
}
else
rename("00000001.tga", $path . ".tga");
}
print "Created PNG/XML for $show_name $season_episode\n\n";
}
}
}
}
break;
default:
print "An invalid action was chosen.\nValid choices are: NEW and ALL.";
}
?>
I simply type in terminal...
php -q Grabber.php /Volumes/EXTREMEII/TV/FamilyGuy ALL
And it auto creates the screenshots at preset intervals with the xml files and auto renames all to match.
The problem is it uses thetvdb.com which is an open source project and thus heavily underfunded. I have to run the script three or for times before it completes all episodes. Their server can't handle all the requests.