Page 1 of 1

XML Export and TVPedia

Posted: Mon Sep 10, 2007 5:27 pm
by sdaniels
Any way to get XML export so I can drop it in my Apple TV?

What about TVPedia to organize my TV Shows. With DVRs and TIVO to GO it seems the only next logical step.

Posted: Tue Sep 11, 2007 2:33 am
by danco
I think there would be problems with TVPedia, given the differences between TV programs in various countries, and a lack of detailed information.

I use DVDPedia, with a note that the item is not actually a DVD.

Posted: Tue Sep 11, 2007 3:42 am
by Conor
A lot of users use DVDpedia for their TV shows. An issues with DVDpedia and TV shows is that if you link several episode movie files to an entry you can only play the first one from the full screen. This will be fixed in the next version; If you have all 12 episodes of Dexter season one in a single entry it will pop up with a menu to select what episode to play in full screen. Give DVDpedia a try for your TV shows an if you find any short comings do send us feedback.

Good to know you would like a direct export to AppleTV; since DVDpedia has a regular XML export keep in mind that using a SXLT transformation you can change it into an AppleTV readable file. We are waiting for Apple to come up with an official way of talking to the AppleTV, instead of having to trick it with web servers and routing. If you do set something up with your AppleTV we would love to hear about it.

Apple TV Setup

Posted: Tue Sep 11, 2007 5:11 pm
by sdaniels
I have the built in Apple File Server (Client) activated on my Apple TV, and it connects to a 1 TB My Book on my Apple AirPort Extreme.

I list as...

/TV Shows/Animation/Family Guy/

File is in format of...
Family Guy S01E01 - Death Has A Shadow.m4v

I have a screen capture of...
Family Guy S01E01 - Death Has A Shadow.png

I have an XML file...
Family Guy S01E01 - Death Has A Shadow.xml

As...

<media type="TV Show">
<title>S1.E1. Death Has A Shadow</title>
<artist>Family Guy</artist>
<summary>Death Has A Shadow</summary>
<description>
After Peter heavily drinks at a bachelor party, even though he told Lois he would not, he gets fired from his job at the Happy-go-Lucky toy factory for being hung over. Peter soon applies for welfare, but after a mix-up, gets sent a check for $150,000. Eventually, Lois finds out, and Peter decides to return the money by dumping it from a blimp at the Super Bowl. He is arrested as a result, and his family ends up coming to his rescue.
</description>
<episode>1</episode>
<season>1</season>
<rating>TV-PG</rating>
<published>1999-01-31</published>
</media>

And everything shows up as if I where using iTunes.

Can my DVDPedia export my movie and TV information as XML?
I can't seem to find it.

I actually bought DVDPedia because I rip all my Movie and TV DVDs to my drive and then put the discs in a crate under my basement stairs. Using DVDPedia I know what I have without getting filthy under my stairs.

Posted: Wed Sep 12, 2007 1:10 pm
by Nora
The .dvdpedia export is the XML format. With such a simple XML it might be even easier to create a text export template and place it inside the Templates folder in ~/Library/Application Support/DVDpedia/Templates. The inside of the text file would be:

Code: Select all

<meta name="PageSplit" content="1" />
<!--BeginRepeat-->
<media type="TV Show"> 
<title>S[Key:CustomOne],E[Key:CustomTwo]. [Key:Title]</title> 
<artist>[Key:Title]</artist> 
<summary>[Key:Title]</summary> 
<description> 
[Key:Summary]
</description> 
<episode>[CustomTwo]</episode> 
<season>[CustomOne]</season> 
<rating>[Key:Rated]</rating> 
<published>[Key:Release]</published> 
</media>
<!--EndRepeat-->
This assumes that custom one and custom two fields are season and episode information. The problem with this export is that the file names will be numbered in the order that the movies are in; so it might not work with the AppleTV. In the end I think you would need an AppleScript or Terminal script that would rename all the XML files and place them in the correct folders. I just wanted to give you some details about how the DVDpedia export works as you have more knoledge about the AppleTV than I do.

Thanks.

Posted: Wed Sep 12, 2007 5:28 pm
by sdaniels
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.

Posted: Thu Sep 13, 2007 6:10 am
by Conor
That is a useful script; switching from that to DVDpedia would be a lot of work, that script has the advantages that it will look up the information based only on the file name and create the screenshots for you. Will keep it in mind as we better DVDpedia with things that our users would want.