Introduction
In my Apple TV review, I walked through the basic features of the Apple TV network multimedia player. I really liked the product, but it was lacking in some areas—the most glaring being its limited support for video formats. The only supported video formats for the Apple TV are H.264 and MPEG4. I also found that I couldn’t use the bulk of its internal 160GB drive since I was synching it only with my 80GB laptop. Finally, I was disappointed that the Apple TV couldn’t make use of the Network Attached Storage (NAS) devices I tend to collect on my LAN.
Fortunately, all these shortcomings can be addressed with a little creative, warranty-voiding work. Soon after the Apple TV was released, a number of people started taking it apart to see what made it tick. It was quickly apparent that the ATV could easily be extended, since internally it runs a stripped-down version of Apple’s OS X, executing on an x86 processor.
In this how to, I’ll try out some of the extensions that have been released for the box, and I’ll add a simple one of my own—the ability to transparently synchronize media files from my NASes to the Apple TV.
Getting Started
Any time you’re trying to modify a product like this, the most important step is to get command-line access so that you can poke around a running system and easily make changes. The hacking community quickly found that the standard secure-shell daemon (sshd) copied from an x86-based OSX system would start up and run fine on the Apple TV. But the limiting factor for many people was the process of getting it going.
The hack required taking the box apart, removing the hard drive, attaching a 2.5 inch IDE adaptor, mounting the drive on an OSX system, copying the file over, adding startup scripts, and then putting it all back together. Fortunately, as time went on, the process evolved and became much easier.
It was found by the folks over at AwkwardTV.org that one could build an Apple TV-bootable USB memory stick that would do the whole process and more automatically. This bootable USB stick (called the “Patchstick”) is what I used to get my system going. And if you want to follow along, you can download the script that builds it here. You’ll also need to download and mount the latest Apple TV update from Apple, found here. Once you have the components, follow the instructions found in the zip file to build your Patchstick.
Note that the script and the described Patchstick building process is designed for an Apple OS X system. Windows and Linux uses can play along, but it will be a bit more work to build the Patchstick. (Instructions can be found here.)
Alternatively, you can take your chances on a pre-built Patchstick image found on the torrent networks, but like most files on the torrent networks, there’s no guarantee about what you’re getting and you may be violating Apple’s copyright on some of the components used.
Once you have the Patchstick built, it’s just a matter of plugging it into the rear USB port and cycling power. If you’ve done everything right, you’ll get a decidedly non-Apple-like bootup screen with lots of errors and warnings as seen in Figure 1.
Figure 1: Apple TV Boot under Patchstick
If it boots, don’t worry about the errors, as they are harmless and you’ll never see them again.
Awkward TV
Once the boot comes to an end, remove the USB stick, and cycle power again. If everything worked, you’ll come back to the standard Apple TV main menu, but you’ll end up with a single new entry, “Awkward TV”, as shown in Figure 2.
Figure 2: Awkward TV Menu Entry
The Awkward TV selection (called an Apple TV plugin) is designed to allow you to download and install additional custom plugins, and also allows you to turn on both the sshd daemon, and an AFP file server. Figure 3 shows the Awkward TV sub menu.
Figure 3: Awkward TV Submenu
From this screen, you can see that I’ve enabled both the SSH and the AFP server. But this brings up one difficulty with expanding the ATV. When the Apple TV was first released, Apple included many extra, unused capabilities. But when the version 1.1 update came along, many of these unused capabilities, such as the AFP server, were stripped from the box. And Apple didn’t just strip the executables, they also stripped many capabilities from the operating system kernel itself.
For example, under version 1.0, it was possible to remotely mount a Windows file share from the ssh command-line. But after the update, kernel support for Windows file-shares was removed, making it more difficult (but not impossible) to access Windows shares.
The Patchstick USB key supports both the original and the updated version, so you can modify your system even if you’ve taken the 1.1 upgrade. But if you’re using a stock 1.1 system, you’ll have to work a bit harder to extend the ATV.
Alternatively, you can use the “Factory Restore” option from the “Settings” menu to take you back to a 1.0 system and then you can do a selective upgrade to just take the additional 1.1 functionality, such as YouTube support. This process is described here and is the road I’ve decided to take for now. Depending on what Apple releases in the future, I may change my mind, but for now, I’m sticking with a 1.0+ system.
Once you’ve used the Awkward TV to enable SSH, you can log into the ATV with a user of frontrow and a password of frontrow. From my OSX command-line, the login command looked like:
# ssh [email protected]
Note the use of the .local domain. Once the SSH daemon is up, it advertises itself on the network using Apple’s Bonjour protocol so it can be automatically located. But Windows and Linux users will need to determine the box’s IP address for login. Similarly, you can move files back and forth to the ATV using the secure copy command, scp, or if you’ve turned on the AFP server, mount it and move your files easily.
Plugins
So what can you do once you’ve turned on ssh support and have command-line access to the box? Plenty. For starters, I quickly mounted shared network drives from my NASes on the network, greatly expanding my storage capabilities.
Under version 1.0, this is a piece of cake because support is in place for Windows shares, AFP shares and NFS shares. But under version 1.1, things get a bit more difficult. As mentioned earlier, native support for Windows network shares is gone, so you’ll have to move to external support for Windows network shares. For NFS shares, you can move the mount command back onto the box from another OS X system so that’s pretty easy, and you can re-enable AFP support in a similar fashion.
There are a few efforts underway to automatically mount the network shares, but the easiest way to accomplish it is to put your mount commands into a user-created boot-time script called /etc/rc.local.
As for what others are adding to their boxes, the AwkardTV.org web site lists lots of different features. There is information on everything from setting up a remote desktop to setting the box up in a Xgrid compile farm to installing a LAMP stack. All these things are cool, but what I was looking for was a way to extend the video capabilities of the product and that means adding video codecs.
One popular source of OSX-compatible video codecs is Perian. Codecs are provided for a number of different formats including the two most popular: XviD and DivX. If you already had Perian installed on your Mac, and you used the Patchstick creation script, then the codecs were likely installed to your Apple TV as part of the Patchstick boot. If not, then download and install the Perian package on your Mac, then copy the /Library/QuickTime/Perian.component directory to the same location on your Apple TV.
Note that Perian.component is a directory tree, not a single file, so you’ll have to do a recursive copy to move it around. When manually adding components to the system directories on your Apple TV, you’ll have to go through a couple of steps.
First, the main operating system partition of the drive is mounted read-only. To correct this, from an Apple TV command-line you’ll re-mount the OS partition using the command:
# sudo mount -ow /
Sudo Allows non-privileged users, like Frontrow, to issue privileged commands. If you haven’t issued the sudo command for a while, it will prompt for the Frontrow user’s password (frontrow). Once the drive is mounted read/write, you can copy files wherever you need them (such as the /library/QuickTime/ directory). You’ll be prefixing your copy commands with the sudo directive in order to get the right privileges. Once you’ve finished your modifications, you’ll put the OS partition back in read-only mode:
# sudo mount -or /
So now that you’ve got the codecs installed, you can play your DivX and XviD files right? Wrong. Unfortunately, the Apple TV movie player has already screened out everything except MPEG4 and H.264 files and there’s no good way to fix that. The alternative is to move your files over to the ATV yourself, or reference them from a network drive and install an alternate movie player.
Alternative Movie Players
As of this writing, there are three different actively-developed players that you can use, Sapphire, nitoTV and ATVFiles.
All three alternative players have their plusses-and-minuses. Sapphire specializes in TV shows and keeping track of what has already been watched. nitoTV operates outside of the Quicktime frame-work and can be used for viewing ripped DVDs in the form of VOB files. And ATVFiles provides a general-purpose viewer. All three can be automatically installed via the Awkward TV menu at the top-level (Figure 4).
Figure 4: Awkward TV plugin downloads
I’ve had occasional failures doing an automatic install, so if your plugin fails to show up in the top-level Apple TV menu, download it manually from the Awkwardtv.org web site, move it to the ATV, unzip it and rename it to the /System/Library/CoreServices/Finder.app/Contents/PlugIns/ directory using a similar procedure as above.
Finally, a manual installation requires restart of the Apple TV finder. Here’s a cryptic one-liner that finds the Finder process id (pid) and issues a kill command which causes it to be re-spawned:
$ sudo kill `ps -ax | grep [F]inder | awk '{print $1}'`
Once the plugins are successfully installed, you should find new top-level items on the Apple TV menu.
ATVFiles
Figure 5 shows the ATVFiles plugin when browsing my Movies directory from the home directory of the Frontrow user.
Figure 5: ATVFiles Movie Listing
As you can see, the plugin supports movie cover art and displays it in the same way as the standard Apple TV movie menu. There is also support in place for user-gathered metadata such as title, actors, year, genre, etc. When you pause on a movie, the image shrinks down a bit and the metadata is displayed. It’s a very nice plugin and fits into the system nearly seamlessly.
I found this plugin had no trouble playing any of my DivX or XviD movies, even some 720p DivX movie trailers that I mounted to the Apple TV over a NFS connection. And since it uses the QuickTime framework, all the same controls as the standard player work including resuming a movie where you last left off. The only complaint I had was the fact that the very first time you enter a large directory, it can take a long time for the plugin to react as it catalogs all the files.
Sapphire
The Sapphire plugin is similar in behavior to the ATVFiles player, except it has additional menus for seeing only un-viewed movies, marking movies as played, un-played, etc. Both of these two plugins played nearly every movie in my collection—the exception being MPEG movies, both in MPEG1 format and MPEG2 format. Apple sells a MPEG codec for $20 and others have gotten it to work on the Apple TV. But as of now, it doesn’t seem to work for me.
nitoTV
But all is not lost with MPEG files. The nitoTV plugin works outside of the standard QuickTime format and supplies all of its own codecs. It also can play most of my files including all of my standard-definition MPEG movies and VOB files ripped from DVDs—even with some crude DVD menu support. Unsurprisingly, an attempt to play a MPEG2 1080i movie was unsuccessful with major pauses and stutters. The Apple TV CPU just isn’t up to the task of 1080i.
One downside to nitoTV at the moment is that it’s not as polished as the others. And since it works outside the Quicktime framework, it can’t take advantage of the hardware acceleration used in the Apple codecs. In addition, it’s not as seamless in use. When a movie is selected from a nitoTV menu, the screen flashes and goes green before the movie kicks in. And I’ve had persistent issues where the movie often plays “behind” the menu, i.e. you can hear it but not see it.
I assume these issues will eventually be resolved, since the plugin is in an early state of development. There’s also a rumor that nitoTV will begin using the standard Apple DVD playback framework, so you’ll be able to play ripped DVDs just like physical DVDs with all the DVD menu control and same user interface. That will be very cool and may cause me to finally rip all my DVDs to a big network drive.
Synchronization
So now that we can play almost every movie around, it’s time to move on to the next task. As mentioned earlier, my Apple TV 160GB drive was mostly empty since I’ve been using iTunes to sync with my 80GB laptop. It would be nice to do arbitrary, automatic synchronization from any of my computers or NAS devices, so that’s what I set out to do.
The basic task will be for the Apple TV to periodically check an external source to see if any changes have been made, and if so, move them over. We could make the synchronization two-way, but for now, I’m satisfied with a one-way sync. The tool I’m most familiar with for this type of work, is rsync.
Rsync is a powerful tool providing fast incremental synchronization between directories, local and remote. It’s available on a number of platforms, including Apple’s OS X. Unfortunately it’s not included on the Apple TV. But a quick copy of the rsync binary from my OS X machine to the Apple TV /usr/bin/ directory solves that issue.
Next, we need to set up a script to define our synchronization. For my purposes, I created a scripts subdirectory in the home directory of the Frontrow user. Inside that directory, I created the following simple script, called periodic.sh, which defined my transfer:
#!/bin/sh # Check to see if we are already running, if so exit if test -e /tmp/time ; then echo "Already running"; exit 0; fi # create a timestamp touch /tmp/time # synch from a remote system, to the local rsync -r [email protected]:appleTVDropBox/ /Users/frontrow/Movies/local/ # remove the timestamp rm /tmp/time
This script lacks a bit of bulletproofing to protect against a crash and the subsequent stale timestamp file, but it’s a start.
In order for the script to run properly in an unattended mode, you’ll need to set up a trusted, no password required, ssh relationship between the Apple TV and the remote system. There’s not room in this article for this step, but you can find a good description of the process here. This also assumes that the remote side is running a ssh daemon and that rsync is available on the remote side. OS X users can just turn on Remote login under the Sharing system preference. Windows users have a more involved process, and Linux users likely already have rsync, and are running a ssh daemon.
After you get the ssh relationship set up, make the script executable (chmod +x periodic.sh) and try it out a few times to make sure it runs and that it doesn’t ask for a password. An alternative to using ssh and a remote rsync command is just have the script do a network mount, let rsync do its thing on two “local” directories, and then unmount the network drive.
Once you’re satisfied with the script, you need to get it to run periodically. As an old Linux guy, my first thought was cron. Cron is a powerful tool designed to run processes at specified intervals. OS X includes cron, but once again, the Apple TV doesn’t.
Apple is also moving away from the use of cron toward a new system called launchd which is included on the Apple TV. So to learn something new, I ended up writing a launchd XML description file that specified how and when to kick off my synchronization script. The XML file was named periodic.plist and was placed in the /Library/LaunchAgents/ directory on the Apple TV. The following is my file:
<xml version="1.0" encoding="UTF-8"?> <DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label<key> <string>test<string> <key>Program<key> <string>Users/frontrow/scripts/periodic.sh<string> <key>ProgramArguments<key> <array> <string>Users/frontrow/scripts/periodic.sh<string> <array> <key>RunAtLoad<key> <true/> <key>ServiceDescription<key> <string>periodic<string> <key>StartInterval<key> <integer>1800<integer> <dict> <plist> <xml>
This file calls out the name of my script and tells the launchd daemon to run it every 1800 seconds.
The final step in getting the script to run is to tell the launchd about it with the following command:
# launchctl load /Library/LaunchAgents/periodic.plist
Similarly, an “unload” can be used to remove the script. Now with this in place, I have transparent, unattended synchronization between my Apple TV and other systems on my network. Very cool.
Conclusion
The combination of Apple’s polished user interface, and the AwkwardTV additions make the Apple TV a killer system for me. It’s fun to us, can handle more of my multimedia library than any other network multimedia system I’ve tried so far, and is easily extendible.
The only downsides for me at the moment are its lack of 1080 support and its reliance on third-party developers for full functionality. But even if nothing more ever came out of the independent developers, the system would still be more capable than anything else I’ve tried so far.
Some might argue that deploying a PC with Microsoft’s Media Center is a better answer. But I don’t want a full-fledged, costly PC with its excessive noise and power consumption; not to mention having to reboot the TV every “Patch Tuesday” that comes along. The Apple TV is tiny, nearly silent, draws only 18 Watts of power and starts at $300. For me, that’s a hard combination to beat.