Monday, December 31, 2012

Android Based Car Media Player

IMG_20130104_002039_0
Nexus One in car holder
My trusty Nexus One was finally retired from active service after the power button failed (again for the third time) and the headphone jack started to be rather intermittent.  To work around the broken button I installed CyanogenMod 7.2 and breathed a bit of new life into the phone.  But alas, it was time to upgrade to a Galaxy Nexus.
After the N1 sat around on my desk for most of the summer and autumn I decided it was time to make something useful from it.  Since the BlueTooth still works properly I can still use it to connect to the car as a media player.

Ideally the N1 Media Player will live in our car and do the following:
  1. Play Music
  2. Automatically Fetch NPR News Programs
  3. Sync Recently Added Music and Podcasts
  4. Stand Up in the Car -Link to Thingiverse Thing-
Check after the jump for specifics

Play Music

The best media player I've found for Android is PowerAmp.  It has lots of options, a nice interface and options for control via headset remote or over BlueTooth A2DP.  There's even a nice selection of widgets that look great and are easy to use.

Automatically Fetching NPR News Programs

Getting the Shows

NPR provides a nice API for finding recent shows so I built a tool to use the API and download the latest NPR news shows to my Linux box from a cron job.  It was a great way of learning some basic Python while I was at it.  See the README for installation instructions.
Configure NPR-Podcast-Download with the following options to make Android friendly playlists:
[main]
maxeps=3
outpath=~/media/Podcasts/npr/
keep=4
apikey=YOUR000API000KEY
genericm3u=True
minsegments=23

Add the following line to your user's cron (in this case user:media) to download NPR shows automatically every day at 03:01 AM:
01 03 * * *    /home/media/bin/npr_podcast.py >> /home/media/npr_podcast.log

Getting the Shows onto the N1 

The shows wait on the server for rsync to pull the latest shows to the phone and delete older shows.  The rsync backup for Android handles the transfers.
The instructions at the developer's web page are a little unclear as to how to set up if you are unfamiliar with ssh and key pairs.
  1. Install rsync backup for Android
  2. In the app touch the menu button and choose 'Generate Keys'
  3. Touch OK
  4. The application will offer several methods to get the public portion of the key off of the phone.  
    • I used $ adb pull /sdcard/dss_key.pub  
  5. Place the dss_key.pub in the home directory of the user that will be hosting the podcasts and do the following to add the public key to your linux host:
    • $ cat dss_key.pub >> ~/.ssh/authorized_keys
    • $ chmod 700 ~/.ssh
    • $ chmod 600 ~/.ssh/authorized_keys
  6. Test your setup with your phone plugged in via USB:
    • $ adb shell
    • ssh -y -i /sdcard/dss_key @
    • you should see the following message:
ssh: Warning: failed creating //.ssh: Read-only file system
Host '192.168.10.9' key accepted unconditionally.(fingerprint md5 ac:fc:89:68:9a:e2:8c:cd:2f:77:23:71:49:28:39:83)
You can ignore the 'Warning: failed creating...' message.  This is due to a poor configuration of the ssh client on the phone but has been worked around with the -y option (accept keys unconditionally).  This isn't a best practice, but for these circumstances, it is acceptable.
SSH is a robust and relatively secure system for remote logins and expects some basic level of security and sanity on the host.  If you are prompted for a password following the connection check /var/log/auth.log for clues as to why the key-pair authorization failed.  A common problem are incorrect permissions on the home and .ssh directories.  The user's home directory must NOT be group or world writeable (minimum 755) and the .ssh directory must be 700 and the authorized_keys file must be 600.

Then configure a profile with the following options:
Name: Podcasts
Local file or directory (on this device): /sdcard/Podcasts
Username (login): {your linux user}
Server (IP or hostname): {your ip/fqdn}
Port: 22
Dropbear SSH private key (generated by dropbear tool): {browse to your key}
Remote file or directory (on server): {/full/path/to/mp3/directory/root}
Additional rsync options: {leave as default}
[X] Close log window after job is done -- tick this after you have confirmed everything works
[X] Delete remote files that are no longer in source -- this will delete files on the PHONE as per the setting below
[X] rsync in reverse direction (from server to this device)


Test your configuration.  Files from your server should automagically show up on your device.

Getting the Shows onto the N1 Automatically

Llama can determine your location based on cell phone towers, wifi networks and other information.  When the N1 is in range of the home network it will rsync the latest episodes.
After new media is added to the phone many media players such as PowerAmp need to rescan the SD card in order for new media to show up in the player.  After downloading the episodes, it is important to force a rescan and then launch your media player of choice to allow a full rescan before you use it.
Configure a Llama task to run either at a specific time or in response to being in proximity to your home network.  I have the following task setup to run late at night when the car is in the garage and charging:
--Download Podcasts--
Conditions:
WiFi Network Connected: {home network}
Charging Status: {Charging from USB or AC}
Time Between: {05:00-05:50}
Actions:
Locale plugin: rsync backup for Android

--Rescan Media--
Conditions:
Time Between: {5:51-6:01}
Actions:
Run Application: Rescan Media
Run Applications: PowerAmp

Playing the Shows Easily

The genericm3u=True option for the nprpodcast script will produce a new playlist for each NPR news program in the root of the mp3 directory.  A Music or Poweramp playlist shortcut for each show can be created on the homescreen.  As long as PowerAmp has rescanned the media, the generic links should automatically launch the desired show.  

Sync New Music and Podcasts

There are all sorts of tools out there like The Missing Sync and DoubleTwist to synchronize iTunes playlists across a WiFi connection.  I've found most of them to be terribly cumbersome and flaky.  It also depends on my Mac being available when the phone client tries to connect.
Instead of using one of these tools, I've found it easier to just use find and rsync to update new music.  

Finding New Music

The script below finds 'new' music and adds a symlink to a directory that can be copied by rsync.  Adjust '-mtime -N' where N is the age in days since the file was added.  The script also attempts to leave out the annoying meta files that netatalk sprinkles around the directory (-type d -name '.AppleDouble' -prune -o.

#!/bin/bash
# Script to make symlinks for new music (last 100 days)
# clean out older tracks
rm /home/media/AUDIO/Music/new_music/*.mp3
# find recent music and create symbolic links 
find /home/media/AUDIO/Music/ -type d -name '.AppleDouble' -prune -o -name "*.mp3" -mtime -100 -print0| xargs -0 -I file ln -s file /home/media/AUDIO/Music/new_music

Run this script on Sunday mornings from crontab on the linux box:
01 01 * * 0      /home/media/bin/link_new_music

Synchronizing New Music

Rsync can be used to pull music from the linux box once again with a minor adjustment to follow symlinks.
Name: Podcasts
Local file or directory (on this device): /sdcard/Media/recently_added
Username (login): {your linux user}
Server (IP or hostname): {your ip/fqd}
Port: 22 
Dropbear SSH private key (generated by dropbear tool): {browse to your key}
Remote file or directory (on server): {/full/path/to/recently_added/directory/root}
Additional rsync options: -vHrLtD --chmodDu+rwx,go-rwx,Fu+rw,go-rw --no-perms
[X] Close log window after job is done -- tick this after you have confirmed everything works
[X] Delete remote files that are no longer in source -- this will delete files on the PHONE as per the setting below
[X] rsync in reverse direction (from server to this device)

Making it Automatic

Create a Llama action as before to run at a different time than other rsync jobs.  Make sure to rescan the media library after the job is done.  
Advanced...
[X] Delay event
Delay minutes: 15
Conditions:
WiFi Network Connected: {home network}
Charging Status: {Charging from USB or AC}
Time Between: {02:00-04:00}
Actions:
Locale plugin: rsync backup for Android
Run Application: Rescan Media

Syncing Recently Downloaded Podcasts

I use iTunes to keep my podcasts up to date.  I haven't found a good way to automate the procedure for downloading podcasts yet.  I have been using The Missing Sync to update podcasts and playlists, but occasionally it totally loses its mind and deletes all the podcasts and playlists (and media associated with the playlists).  Obviously this is not a good solution for unattended updating.
Until I find some way to automagically export iTunes playlists and push the contents to the linux media server, this feature will have to wait.

Some Useful CyanogenMod Settings

Making the N1 More Car Friendly

To make the N1 a little more car friendly I disabled the lock screen and set the track ball to wake the phone.

Settings > CyanogenMod Settings > Input > Trackball wake [X]
Tablet tweaks  > Disable lockscreen [X]


No comments:

Post a Comment

Thanks for thinking of us and leaving a comment!
Please leave your name so we know who you are!
If you want to remain an Anonymous Coward you can do that of course, but we like you guys and want to know who we're talking to!