mwolson.org Blog - /Tech

Wed, 11 Jul 2007

Copying entire albums to my GP2X, preserving order, part 2

I found the ommpc2x media player for the GP2X recently. It basically provides a front-end for MusicPD. I've sent in some patches to make it able to resume a song when starting, if you were playing a song when last exiting the program. It's a very valuable feature to have, since I use the GP2X as a car audio player.

My patches seem to have made it into the 0.1.2 release. There's also a tarball I made that has my patches applied against 0.1.1 here — I haven't had the chance to review the 0.1.2 release yet.

Now that I have MusicPD on this device, I decided to tweak my copy-to-gp2x script for copying albums to the GP2X, preserving order. This new version of the script removes tracks that were listened to, preserves the position in the track that I am currently listening to, and copies in new albums at the end. It even regenerates the MusicPD song information database on an SD card so that I don't have to do that from the GP2X at all. It assumes that your song information database is at $OMMPC2X/.mpdstate.

#!/bin/bash

DEST=/media/disk/Music
DEVICE=/dev/sdf1
OMMPC2X=/media/disk/Utils/ommpc2x
MPD_CONF=/stuff/sounds/scripts/mpd.conf

# Current track number
cnt=0
# Formatted track number
fcnt=$(printf "%03d" $cnt)
# List of tracks to work on
track_list=

# Don't allow spaces to terminate a "for" item
IFS="
"

# Toggle this to enable debug mode, where no files are actually
# changed (with the exception of the mpd database, but that's safe)
#DEBUG=echo
DEBUG=

function delete_old_tracks () {
    echo Deleting old tracks ...
    if [ -f "$OMMPC2X/.mpdstate" ]; then
        local current=$(cat "$OMMPC2X/.mpdstate" | \
            grep "^current:" | head -n 1 | \
            sed -r -e 's/^current: *([0-9]+)$/\1/')
        local bop=$(cat "$OMMPC2X/.mpdstate" | \
            grep -n "^playlist_begin" | head -n 1 | cut -d':' -f1)
        cat "$OMMPC2X/.mpdstate" | head -n $bop | \
            sed -r -e 's/^current: *([0-9]+)$/current: 0/1' \
            > "$OMMPC2X/.mpdstate.new"
        bop=$(expr $bop + 1)

        # Remove old
        local remove=$(cat "$OMMPC2X/.mpdstate" | \
            tail -n +$bop | head -n $current | \
            sed -r -e 's/^([0-9]+): *//')
        for i in $remove; do
            $DEBUG rm -f $DEST/$i
        done

        # Set track_list
        current=$(expr $current + 1)
        track_list=$(cat "$OMMPC2X/.mpdstate" | \
            head -n -1 | tail -n +$bop | tail -n +$current | \
            sed -r -e 's/^([0-9]+): *//')
    else
        echo Cannot read MPD data
        exit 1
    fi
}

function get_count () {
    fcnt=$(printf "%03d" $cnt)
    cnt=$(expr $cnt + 1)
}

function move_remaining_tracks () {
    echo Renaming unlistened tracks ...

    for track in $track_list; do
        tb=$(basename "$track")
        oldcnt=$cnt
        get_count
        $DEBUG mv "$DEST/$track" "$DEST/${fcnt}_${tb}"
        echo "$oldcnt:${fcnt}_${tb}" >> "$OMMPC2X/.mpdstate.new"
    done

    echo Done.
}

function copy_album () {
    album=$1
    echo Copying album $(basename "$album") ...

    for track in $(cat $album); do
        tb=$(basename "$track")
        oldcnt=$cnt
        get_count
        $DEBUG cp "$track" "$DEST/${fcnt}_${tb#*-}"
        echo "$oldcnt:${fcnt}_${tb#*-}" >> "$OMMPC2X/.mpdstate.new"
    done
}

function finalize_mpd () {
    echo Finalizing mpd settings ...
    echo playlist_end >> "$OMMPC2X/.mpdstate.new"
    $DEBUG mv "$OMMPC2X/.mpdstate.new" "$OMMPC2X/.mpdstate"
    # Re-create the database, otherwise tracks won't be recognized.
    mpd --create-db ${MPD_CONF}
}

delete_old_tracks

move_remaining_tracks

while [ -n "$1" ]; do
    copy_album "$1"
    shift
done

finalize_mpd

echo Done.

echo Unmounting SD card ...
$DEBUG gnome-mount --unmount -d $DEVICE > /dev/null
echo Done.

Add a comment

Name: 
Your email address: 
Your website: 
 
Comment: