My Apple TV

The Apple TV runs a stripped-down MacOS 10.4, and mounts the root filesystem read-only on bootup.

Jailbreak

First, use this to “jailbreak” your Apple TV. This will enable SSH.

Then log in, install your ssh public key, and disable password authentication for ssh logins. I haven't been able to figure out how to change the frontrow user's password without bricking the AppleTV (dscl and niutil won't work).

mkdir .ssh
# install your key in .ssh/authorized_keys
chmod go-rwx .ssh
sudo bash
mount -uw /
echo -e 'root ALL=(ALL) ALL\n%admin  ALL=(ALL) ALL\nfrontrow ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers
echo 'PasswordAuthentication no' >> /etc/sshd_config
mount -ur /
reboot

Time Zone

sudo ln -fs /usr/share/zoneinfo/US/Pacific /etc/localtime

Disable the obnoxious startup video

mv /System/Library/CoreServices/Finder.app/Contents/Resources/Intro.m4v \
   /System/Library/CoreServices/Finder.app/Contents/Resources/Intro.m4v-

Enable Kext Loading

It turns out that the simplest and most reliable way to enable kext loading is to install nitotv and use its “smart installer”:

ssh appletv
sudo bash
cd /tmp
wget http://nitosoft.com/nitoTVInstaller_tt.zip
unzip nitoTVInstaller_tt.zip
cd 'nitoTV Take Three/'
./installme

When Apple TV interface restarts, go to the “nitotv” menu and choose Settings, Install Software, Smart Installer. The smart installer puts kextstat in the wrong place, so:

sudo ln -s /usr/bin/kextstat /usr/sbin/kextstat

OpenAFS

Everything seems to work great for world-readable content – I can even stream 1mbps H.264 video over AFS without a hiccup.

ssh frontrow@your-appletv-ip-address
sudo bash
mount -uw /

cd /tmp
wget http://www.openafs.org/dl/openafs/1.5.51/macos-10.4/OpenAFS-1.5.51-Tiger.dmg
#wget http://www.openafs.org/dl/openafs/1.4.11/macos-10.4/OpenAFS-1.4.11-Tiger.dmg
hdiutil attach OpenAFS-*-*.dmg

# we use tar because stupid "pax" will rip up symlinks in its path...
mkdir openafs
cd openafs
gzip -dc /Volumes/OpenAFS/OpenAFS.pkg/Contents/Archive.pax.gz | pax -r   
tar clpf - . | tar -C / -xvlpf -
/Volumes/OpenAFS/OpenAFS.pkg/Contents/Resources/postinstall 

mv /Library/OpenAFS/Tools /SeedScratch/OpenAFS-Tools
ln -s /SeedScratch/OpenAFS-Tools /Library/OpenAFS/Tools

# a 5GB cache
echo /afs:/var/db/openafs/cache:5000000 > /private/var/db/openafs/etc/cacheinfo

ln -sf /usr/bin/kextstat /usr/sbin/kextstat

cat >> /private/var/db/openafs/etc/config/afs.conf <<\EOF
afs_post_init_stuff() {
  (while true; do sleep 1s; fs checks megacz.com; done 2>&1 >/dev/null) &
  disown -h %1
}
AFS_POST_INIT=afs_post_init_stuff
EOF

mount -ur /
reboot

  • The postinstall script can't find cmp, but that doesn't seem to matter.

  • The last two steps relocate /Library/OpenAFS/Tools to /mnt, which is mounted read-write (it seems to be the volatile partition for media storage) because OpenAFS fails in strange ways if it can't write to some part of that directory (not sure which part) and / is mounted read-only on bootup.

  • Although world-readable content works great, there's no kinit, and aklog segfaults.

  • It would be great to have a working k5start so I could give the Apple TV its own service principal.

Creating Additional Startup Jobs

sudo bash
mount -uw /

export NAME=MyStartupItem
mkdir -p /System/Library/StartupItems/$NAME
cat > /System/Library/StartupItems/$NAME/StartupParameters.plist <<EOF
{
  Description     = "My Startup Item";
  Provides        = ("$NAME");
  Requires        = ("Resolver", "Disks");
  OrderPreference = "None";
  Messages =
  {
    start = "Starting $NAME";
    stop  = "Stopping $NAME";
  };
}
EOF

# put your file in /System/Library/StartupItems/$NAME/$NAME
chmod +x /System/Library/StartupItems/$NAME/$NAME

More:

sudo bash
mkdir -p /mnt/local
mount -uw /
mkdir -p /opt
ln -s /mnt/local /opt/local
mount -ur /
cd /tmp
wget http://netpbx.de/tmp/samba3_macports_bin.tar.bz2
tar -xvjpf samba3_macports_bin.tar.bz2 -C /
cat > /opt/local/etc/samba3/smb.conf <<\EOF
[global]
   workgroup = MYGROUP
   server string = Samba Server
   security = user
[rootfs]
   comment = rootfs
   path = /
   valid users = frontrow
   public = no
   writable = yes
   printable = no
EOF
/opt/local/bin/smbpasswd -a frontrow

mkdir -p /mnt/impostor /mnt/mute /mnt/presburger /mnt/carnap
export NAME=MountAll
mkdir -p /System/Library/StartupItems/MountAll
cat > /System/Library/StartupItems/MountAll/MountAll <<\EOF
#!/bin/bash
  /opt/local/sbin/nmbd -c /opt/local/etc/samba3/smb.conf
  /opt/local/sbin/smbd -c /opt/local/etc/samba3/smb.conf
  mount_nfs 192.168.1.199:/root/dvds /mnt/impostor
  mount_nfs 192.168.1.182:/root/dvds /mnt/mute
  mount_nfs 192.168.1.198:/root/dvds /mnt/presburger
  mount_nfs 192.168.1.194:/root/dvds /mnt/carnap
EOF

DVDpedia

sudo bash
mount -uw /
cd /tmp
wget 'http://para9.com/downloads/DVDpedia%20Front%20Row.zip'
unzip DVDpedia\ Front\ Row.zip
cd /System/Library/CoreServices/Finder.app/Contents/PlugIns/
gzip -cd /tmp/DVDpedia*.mpkg/Contents/Packages/dvdpedia.pkg/Contents/Archive.pax.gz | pax -r

I find it useful to keep my DVDpedia folder in /afs/ so that it is automatically shared between my mac and my Apple TV.

ln -s /afs/megacz.com/media/dvdpedia DVDPedia
ln -s /afs/megacz.com/media/dvdpedia Library/Application\ Support/DVDPedia

Remove Unnecessary Menu Items

As described here ->http://wiki.awkwardtv.org/wiki/Removing_unused_buttons_from_the_Frontrow_menu.

sudo bash
mount -uw /
cd /System/Library/CoreServices/Finder.app/Contents/PlugIns/
mv Photos.frappliance Photos.frappliance.old
mv SoftwareMenu.frappliance SoftwareMenu.frappliance.old
mv nitoTV.frappliance nitoTV.frappliance.old
mount -ur /
reboot  

Install VNC

As described here

sudo bash
mount -uw /
cd /tmp
wget 'http://downloads.sourceforge.net/project/osxvnc/Vine%20Server%28OSXvnc%29/Version%203.0/VineServer3.0.dmg'
hdiutil attach VineServer3.0.dmg
cp -r '/Volumes/Vine Server/Vine Server.app/Contents/Resources/OSXvnc' /Library/StartupItems
cp    '/Volumes/Vine Server/Vine Server.app/Contents/Resources/OSXvnc-server' /Library/StartupItems/OSXvnc/
sed -i .tmp 's_VNCARGS.*_VNCARGS="-localhost -rfbnoauth -swapButtons -dontdisconnect"_' /Library/StartupItems/OSXvnc/OSXvnc
mount -ur /
reboot

More

I wish I could jump to specific points in a video

Install XBMC10

Switch to the “Alaska Revisited” theme.

Edit the file Applications/XBMC.app/Contents/Resources/XBMC/system/keymaps/joystick.AppleRemote.xml and replace the <FullscreenVideo> section with this:

scp joystick.AppleRemote.xml 'appletv-up:Library/Application Support/XBMC/userdata/keymaps'

<FullscreenVideo>
  <joystick name="AppleRemote">
    <button id="1">VolumeUp</button>
    <button id="2">VolumeDown</button>
    <button id="3">Rewind</button>
    <button id="4">FastForward</button>
    <button id="12">Pause</button>
    <button id="6">Stop</button>
    <button id="5">OSD</button>
    <button id="8">Fullscreen</button>
    <button id="9">Rewind</button>
    <button id="10">FastForward</button>
  </joystick>
</FullscreenVideo>

To Do

  • aklog?

  • k5start?

  • Get a receiver with a remote-controllable volume (Apple TV video playback is line-level only)

  • The Apple TV sleep mode doesn't send the correct DMPM signals over its HDMI port, so the monitor won't turn off its backlight when the Apple TV is idle. This sucks.

  • The Apple TV uses Quicktime 7 for playback (not Quicktime X), so there is no support for Sample Aspect Ratio. This means that videos encoded with non-square pixels (which is most DVDs) are displayed in “stretched” format.