Remote Wireless Music Syncing Android and Linux

February 13th, 2011 by Strawp

Recently, an Android version of Winamp was released and included in its feature list was very useful wireless syncing with the Windows version of Winamp. Unfortunately, my file server at home doesn’t run Windows and Winamp under Wine is an unstable mess, so attempting to use that feature was out. Like a good Linux user, I didn’t take this lying down – we don’t sit around like Windows users waiting for someone to build the solution for us, we cobble something together using tools already available! What I decided to do was to emulate the mechanism that I came up with when I built my Car PC. Basically, the core of wireless syncing in the Car PC was rsync, combined with a little bit of logic to get a list of music track locations to pull over. By offloading some of that logic onto the server, this seemed possible.

First, I installed an rsync app for Android and tested it out. Rsync backup is just a front end for rsync, which is perfect because it lets you use all the normal rsync options, allows public key authentication (so you never need to enter a password) and displays rsync’s output to a log window. I wanted to pull files from my server so in my rsync profile I selected “rsync in reverse” and added the command line options “-vHrtDL --chmod=Du+rwx,go-rwx,Fu+rw,go-rw --no-perms --progress --partial” most of which is the default for a new profile, but I added:

  • -L, to follow symlinks
  • --progress, to display file transfer progress
  • --partial, to allow file transfer resuming

Android won’t know any of the new music files have been added yet, so they won’t show up in any music players (which all look up available tracks in the built-in Android media database), so you need to install something like SDrescan to run after the files have copied over which will magically make them visible in the music app of your choice.

That’s the phone side sorted out, I just need something sensible to point it at – I don’t want rsync recursing over my entire music collection wirelessly, it would take ages.

On the server, I’m running the (somewhat ageing) Firefly Media Server, which indexes and serves music for my Roku Soundbridge. I’d previously written a data abstraction class in PHP for the sqlite database it runs on, so I used that to produce a script (to run periodically under cron) which picks a list of albums from a playlist (created by another script) and creates a bunch of symlinks to them in the folder that I set as the target in my rsync profile, the idea being I have a regularly changing folder which one rsync command can look at to pick up new music.

I now have wireless syncing that works anywhere with an internet connection, as well as on the local network (unlike Winamp) and the idea of keeping a static rsync profile and using a source folder full of symlinks provides a cunning way of pushing content onto your phone. It would be quite easy to create something like a web interface to pick files on the server and have symlinks of them created on a single rsync source folder. On top of this, Rsync backup provides hooks for Tasker to link into, so you could set this up to run automatically at some opportune moment.

2 Responses to “Remote Wireless Music Syncing Android and Linux”

  1. Rupert Says:

    Hi

    Having tried lots of options, I am also using firefly to serve my music (mainly because it supports smartplaylists and universal play counts).

    I’ve tried to use your scripts above, but I get the following error:

    PHP Notice: Undefined property: FireflyDb::$db in /home/rupert/Documents/ruperts/Code/pl/firefly_db.php on line 15
    PHP Notice: Undefined property: FireflyDb::$db in /home/rupert/Documents/ruperts/Code/pl/firefly_db.php on line 15

    Not knowing anything about PHP, I am little lost. Any ideas, and dependencies I might be missing (this is on Ubuntu btw).

    Also, care to tell how to use your lastfm playcount update script with firefly?

  2. Strawp Says:

    FireflyDb::$db is a PDO object (PHP Data Objects) representing the SQLite3 database.

    sudo apt-get install php5-sqlite

    should sort you out.

    The lastfm script, you mean this one? http://svn.strawp.net/scripts/firefly/mark_played_from_lastfm.php

    I have it set up in cron to run every 30 minutes. You will need to replace the user name with your own lastfm user name (and put your own API key in there, possibly). The script will try to create the file “.lastfm_last_grab.php” in the same folder as itself, so that should be writable and you should have firefly_db.php either in the same folder, or somewhere in PHP’s include path (I have a ~/lib/ folder which php.ini can point to). When you run it, it will first take the largest list of songs it can from last.fm, then mark the date/time it did it (in .lastfm_last_grab.php), if it was successful, then only query what songs you’ve listened to since then.

    For each song it will attempt to match it against a song in Firefly based on artist/title/album, then just artist/title if that fails and if the playcount is 0 will up it to 1. This could just be a simple increment, it’s just not how I have it set up.

    Note that last.fm does some pretty robust cleaning on artist and track names, so if you’ve scrobbled “Who, The”, it will store and send back “The Who” and firefly won’t find a match in your database.

    Let me know if you get it working.