Tuesday, October 14, 2008

Apple TV / Boxee / TV Shows Integration

So this past week I have been messing around with Boxee for the Apple TV. Boxee is a media center application that is based on the XBMC (Xbox Media Center) that has been ported to other OS's (Windows/Mac). While the XBMC has been ported to them as well, Boxee has some Social Networking integration that I find rather interesting...

Anyway, I installed this software on my Apple TV because, well, it looked cool and I was tired of trying to get my Apple TV to talk to my network, and this seemed like a good solution to my issue

Little did I know that this would open up a whole new avenue for playing videos :)

After waiting ever-so-patiently (almost to the point of forgetting about it) I received by alpha (oh, I forgot to mention it Boxee is in the alpha stages... very extreme alpha) invitation to Boxee...

While you don't need the invitation to install the software, it gives you a login to use to social networking side of the program.

So I installed it on my Apple TV using the atvusb-creator (found here), which is a really nifty app if you want to install ssh (which if you don't have, shame on you) or some bin stuff that you need if you're working on the Apple TV (no keyboard support remember?)

In order to get this working, you need to do the following steps:
  1. Insert a “bootable” USB drive into your Mac
  2. Run the ATVUSB-Creator and select which plug-ins you’d like to install
  3. Remove the USB drive and plug it into your Apple TV
  4. Power on your Apple TV and the patchstick will run the ATV bootloader
  5. After the bootloader finishes, remove it and restart your Apple TV
  6. It now has options for Boxee / XBMC on the main menu
  7. Click on Boxee, then select update (this will download boxee from the Internet)
  8. Once boxee is done installing, restart your Apple TV
  9. click “Boxee”, then select “Boxee” in the sub-menu to start boxee.
So after completing the steps outlined above, and you've received and setup your alpha account, you get this:


Which is ever so cool, heh, sorry, I'm really big on interfaces and I'm kinda down with this one.

So... after fiddling around with this for a while, setting up my SMB share on my desktop (which was made much easier by Boxee) and watching a few episodes of Stargate to test out how it works I started to look a bit closer at what we have here.

And to my surprise, I found the following:


And what do we have here you ask? Only the most awesome aspect of Boxee that I've seen yet... torrent integration!

After a little digging I found that Boxee integrated rtorrent into it's media center app. rtorrent is a command line bittorrent client written in C++. After reading a bit more into Boxee I found that it watches a directory for torrent files, and when you place on there, it automatically starts downloading it, with a bunch of nifty little settings like setting the up/down speed, max/min number of peers as well as port ranging, so if you have more than one torrent going on different computers it doesn't freak out :)

So, after finding said feature, I decided to test it out by throwing a few torrents that I have on my laptop into the directory (/Users/frontrow/Library/Application Support/BOXEE/UserData/Torrents/) to see how well it works, and I have to say, I'm pretty impressed, after a few hours of downloading, I have a nice little library built up:


The other awesome thing I found out about this is that when a new video is added to the library, Boxee will go out and find the relevant information for the show/movie as well as the synopsis for an episode (with a cool feature to hide said synopsis if you haven't watched the show yet).

So after thinking about this for a while, I realized that this would be a great feature if I could somehow integrate my TV Shows application with Boxee. TV Shows is a Mac program that lets you subscribe to a show and it will go out to the intertubes that look for new episodes of shows that you are subscribed to:


As you can see, I've built quite a subscription to shows...

So, you may be asking yourself at this point, doesn't this guy have a DVR that can record his shows for him?

Well, yes of course I do, but sometimes I want to watch something without having to fast forward through commercial, or maybe my dvr freaks out and doesn't record an episode. So this is really handy because I work nights and am usually not home to watch TV anyway.

So, after thinking about it for a few hours, I decided that the best thing would be to figure out a way to have my mac automatically move any new torrents that TV Shows downloads into the directory for Boxee to download for me.

This is where my new friend Python comes in. After fiddling around with it for a while, I wrote a nice little script to move any new torrents that TV Shows gets into a mounted SMB share from the Apple TV. So I came up with the following:

#! /usr/bin/env python

import os
import array
import pickle
import shutil

os.chdir('/Users/mike/Movies')

for i in os.listdir(os.getcwd()):
if '.torrent' in i:
shutil.move(i, '/Volumes/frontrow/Library/Application Support/BOXEE/UserData/Torrents/')
Pretty nifty huh? Well, after a bit of testing I realized that I wanted a bit more functionality
built into this. After some searching, I found that most UNIX systems have a built in sendmail application, totally sweet!

So, after a bit more testing, adding a few lines here and there, I came up with the following:

#! /usr/bin/env python

import os
import array
import pickle
import shutil
import time

MAIL = "/usr/sbin/sendmail"

count = 0

mssg = 'To: youremail@example.com \n' \
+ 'From: MikesTorrentBot\n' \
+ 'Subject: New Torrents Added to AppleTV on ' \
+ str(time.strftime('%x')) + ' at ' + str(time.strftime('%X')) + '\n\n' \
+ 'The following torrents were added the the appletv:\n\n'

os.chdir('/Users/mike/Movies')

for i in os.listdir(os.getcwd()):
if '.torrent' in i:
shutil.move(i, '/Volumes/frontrow/Library/Application Support/BOXEE/UserData/Torrents/')
mssg += i + '\n'

if '.torrent' in mssg:
p = os.popen("%s -t" % MAIL, 'w')
p.write(mssg)
exitcode = p.close()
if exitcode:
print "Exit code: %s" % exitcode

Basically what this little script does is scrape the /Users/mike/Movies directory (this is where TV Shows drops new torrents when it finds them) and if it finds one then it will move the torrent into the mounted SMB share and send me an email with the date and time telling me what torrent it moved.

So this is all well and good, but this isn't going to accomplish anything without me running it every 15/30 minutes, and I'm not home when I need this to run, so I need to find a way to have this run without me there.

My first instinct would be to setup a cron job to do this, which I did, because, well, that's how I roll :p But this got me thinking, how does TV Shows run every half hour without being a cron job? So I did some digging and stumbled upon launchd which is a daemon that takes over for cron on macs. After looking over the launchd entires, I found that this is where TV Shows runs every half hour. So I create a little plist file to run my script every 15 minutes:

[~]$> cat /Users/mike/Library/LaunchAgents/net.mike.robotorrent.plist
"



Disabled

Label
net.mike.robotorrent
ProgramArguments

/Users/mike/Movies/torrent

RunAtLoad

StandardErrorPath
/Users/mike/Desktop/Robotorrent.log
StartCalendarInterval

Minute
25

StartInterval
900

"

I placed this plist file in /Users/mike/LaunchAgents/ and ran the following command to load the plist into launchd:
launchctl load /Users/mike/LaunchAgents/net.mike.robotorrent.plist

Once you run this command it'll load the plist and run the command specified in the Program Arguments key at the interval defined in StartInterval. It will start the interval at the minutes specified in StartCalendarInterval - Minutes. It'll also write an error log into a file on my desktop so I can come and check it when I get home in the evening to see if there were any errors in the script.

So once I loaded this into launchd I sat back and waited to see if this thing would work like it's supposed to, and lo and behold, TV Shows downloaded a new torrent, my script kicked off at the specified time and sent me an email letting me know that it added the new torrent to the directory on the Apple TV. I then switched to the Apple TV and found that it was already downloading the new show.

Totally killer

So I know this post isn't very instructive in the way of trying to do this, since it very macish and most of the people I know don't have mac, but I thought it was cool.

The next step for my script is to pretty much kill the TV Shows daemon and write a wrapper for it into my script so I don't have to wait for it to run to run my script. Initially, I was going to port the TV Shows script to python and integrating it that way, but since I'm reluctant to learn Ruby (which is what the core of TV Shows is written in) I decided that it would be easier to just write a wrapper.

The same goes for the mounted SMB share on my mac, I'm going to modify the script to see if the share is mounted, and if it isn't, it will go ahead and mount it and continue on.

Well, I think that's enough for now, so in the words of my coworker:

Happy Hacking!

Oh yeah, and I forgot... Clay's Mom :p

Had to put that in there :)