Adding metadata to added iTunes videos

I have a problem. Or rather my wife does. She loves the AppleTV but it’s difficult for her to find content for her to watch. Why? Because our video content, other than genre metadata (added by hand – blech!), contains no metadata! Once again, coding to the rescue.

The ingredients:

  • Ruby (my language of choice du jour)
  • ruby-amazon - Clients itself to Amazon’s web service to perform keyword searches. Major caveat: The search results are nowhere near as accurate as those provided on the Amazon web site. I found this surprising. Why this has not been made into a Winblows XP Media Center Edition 2005 so that the wifey can have her relatively stable Windows Media Center as opposed to our previously slightly less stable, although somewhat more hacker friendly, SageTV.

At the moment, the program fetches descriptions, years (from the DVD release date, sadly, and not the original movie release, and DVD cover artwork from Amazon.com). As Amazon’s web service provides spurious accuracy, the program prompts me to select from one of ten candidate Amazon products to use as a source of metadata for any given movie.

The obnoxious part? I have yet to figure out how to programatically add artwork to a movie (IITTrack.AddArtworkFromFile barfs all over me) even though I am fetching it from Amazon.

require 'amazon/search'
require 'pp'
require 'win32ole'
#require 'net/http'
require 'uri'

$AWS_KEY = 'XXXXXXXXXXXXXXXXXXXX'  # bleeped out to protect the innocent
$ART_PATH = 'f:/movies/artwork/'

$app = WIN32OLE.new 'iTunes.Application'
exit if $app.nil?
$movies = $app.LibrarySource.Playlists.ItemByName 'Movies'



def find_dvd(title)
  retval = []
  req = Amazon::Search::Request.new $AWS_KEY
  res = req.keyword_search(title, 'dvd') 
  i=1
  res.products.each do |p|
    puts "#{i}. #{p.product_name} (#{p.release_date})"
    i+=1
  end
  print ">> "
  input = gets
  if input.match /s/
    return nil
  end
  input.match /(\\d+)/
  res.products[$1.to_i - 1]
end

def get_artwork(movie_track, movie_meta)
  response = Net::HTTP.get_response(URI.parse(movie_meta.image_url_large))
  title = movie_track.Name
  title.gsub! ':', '-'
  art_filename = ""
  art_filename << $ART_PATH << title << ".jpg"
  File.open( art_filename, 'wb') do |f| 
    f << response.body
    f.flush
  end
  art_filename
end

def update_metadata_for(movie_track)
  track = movie_track

  meta = find_dvd movie_track.Name
  if meta.nil?
    return
  end

  if meta.release_date
    meta.release_date.match /, (\\d+)$/
    track.Year = $1
  end

  art_filename = get_artwork track, meta
  if track.Artwork
    puts track.Artwork
    track.AddArtworkFromFile art_filename
  end

  if meta.product_description 
    meta.product_description.gsub!( /<(\\/?)(\\w+)>/, "")
    meta.product_description.gsub!( /\\s\\s.*/, "")
    puts meta.product_description
    track.Description = meta.product_description
  end

end

idx = 1
count = $movies.Tracks.Count
while idx <= count do
  movie = $movies.Tracks.Item idx
  puts movie.Name
  if movie.Description == ""
    update_metadata_for movie
  end
  idx += 1
end

Posted by evan on Sunday, April 08, 2007

blog comments powered by Disqus