Note: mp3blstr2dscrbblr is now hosted on GitHub.
This is a song submission script for last.fm/audioscrobbler. The script mp3blstr2dscrbblr.sh (mp3blaster to audioscrobbler) analyses the status file of mp3blaster and delivers the gattered information to a perl script.
mp3blaster doesn't have a native plugin interface. Thus we need to retrieve the needed data through a config file (mp3blaster -f <file>). Then, cron calls this script every 30 seconds. The script checks if the song plays at least 30 seconds (giving the listener enough time to skip it) and at most 59 seconds (preventing multiple submissions). This check can be disabled by calling the script with the parameter --force.
#!/bin/bash # # mp3blstr2dscrbblr.sh: last.fm/audioscrobbler song submission script for mp3blaster # # Copyright (C) 2006-2007,2012 Alexander Heinlein <alexander.heinlein@web.de> # # version: 0.4 # # mp3blaster status file (mp3blaster -f <file>) MP3_STAT="/tmp/mp3blaster" # perl audioscrobbler plugin directory # (http://search.cpan.org/~roam/Audio-Scrobbler-0.01/lib/Audio/Scrobbler.pm) #DIR="/home/scytheman/Audio-Scrobbler-0.01/lib" # plugin binary/script #BIN="../bin/scrobbler-helper" BIN="scrobbler-helper" # maximum retries if first submission failed MAX_RETRIES=15 # seconds to wait before second submission # this value increases during further retries WAIT=10 # check for existing status file if ! test -e $MP3_STAT then echo "$MP3_STAT doesn't exist, make sure mp3blaster is running with '-f $MP3_STAT'" exit fi # check for scrobbler binary if ! which $BIN >/dev/null then echo "$BIN doesn't exist, make sure libaudio-scrobbler-perl is installed" exit fi # first, check if the time of last modification is greather than 30s and less than 60s # because this script will be executed every 30s, so we don't submit the same song twice # and make sure we don't submit skipped tracks (user has 30s to skip the track) # # we calculate the difference between last modification time (-> stat) and current time # (-> date), both are seconds since 1970-01-01 00:00:00 UTC # seconds since last modification SSLM=$(echo "$(date "+%s") - $(stat -c "%Y" $MP3_STAT)" | bc) if [ "$SSLM" -lt 30 ] || [ "$SSLM" -ge 60 ] then echo "last modification time <30 or >=60" # user may skip this test by passing '--force' to script if [ "$1" = "--force" ] then echo "ignoring." else echo "specify '--force' to submit anyway" exit fi fi # check if song is playing otherwise there is the risc of submitting a song twice # because every time a song is paused, mp3blaster updates it's status file, thus # changing also time of last modification if ! grep -q "^status playing" $MP3_STAT then echo "no song playing" exit fi # we need 2 + 7 arguments: # -P <client> -V <clientversion> # title, artist, album, year, comment, genre, length # note: - comment will be left empty # - genre will be specified globally # unfortunately mp3blaster isn't recognized as client >:( CLIENT="mpd" CLIVER="0.11" # mp3blaster doesn't list the genre in the status file GENRE="rock" # now get all information from mp3blaster title=$(grep "^title " $MP3_STAT | cut -d ' ' -f2-) artist=$(grep "^artist " $MP3_STAT | cut -d ' ' -f2-) album=$(grep "^album " $MP3_STAT | cut -d ' ' -f2-) year=$(grep "^year " $MP3_STAT | cut -d ' ' -f2-) length=$(grep "^length " $MP3_STAT | cut -d ' ' -f2-) # check if we have artist and title # else print error message to stderr if [ "$title" = "" ] || [ "$artist" = "" ] then echo "error: $(grep "^path " $MP3_STAT | cut -d ' ' -f2-) has no/invalid ID tag" 1>&2 exit fi # and finally execute plugin if [ -n "$DIR" ]; then cd "$DIR"; fi # creating function and variable for multiple use SUBMIT="$BIN -P $CLIENT -V $CLIVER \"$title\" \"$artist\" \"$album\" \"$year\" \"\" \"$GENRE\" \"$length\"" submit() { "$BIN" -P "$CLIENT" -V "$CLIVER" "$title" "$artist" "$album" "$year" "" "$GENRE" "$length" >/dev/null } echo echo "executing $SUBMIT" echo submit retval="$?" # known return values: # 22 bad hostname # 104 Connection reset by peer # 110 connection timeout # 111 Connection refused (fuck you) # 114 couldn't complete handshake # 115 connection timeout # 255 couldn't complete handshake # 500 read timeout / EOF # last submission failed, resubmit if [ "$retval" == "22" ] || [ "$retval" == "104" ] || [ "$retval" == "110" ] || [ "$retval" == "111" ] \ || [ "$retval" == "114" ] || [ "$retval" == "115" ] || [ "$retval" == "255" ] || [ "$retval" == "500" ] then for ((i = 1; i <= MAX_RETRIES; i++)) do echo "waiting for $WAIT seconds..." sleep $WAIT echo "retry #$i: executing $SUBMIT" submit if [ "$?" == "0" ] then exit 0 fi # doubling next wait, server may be down for any length of time let "WAIT = $WAIT * 2" done echo "couldn't submit song after $MAX_RETRIES retries: $?" 1>&2 elif [ "$retval" != "0" ] then echo "return value: $retval" 1>&2 fi
# ~/.scrobbler_helper.conf example file # see `man scrobbler-helper' for detailed # information [global] username=last.fm-user password=password # Optional (the default is UTF-8) default_encoding=iso885915 # Optional (the default is "no") fix_track_name=yes
For periodic calls of this script through cron you need to set up a cron job (see man 5 crontab
). Run as user crontab -e
and add the following lines:
# m h dom mon dow command # cron runs only every minute, thus we need sleep here * * * * * nice -19 ~/scripts/mp3blstr2dscrbblr.sh > /dev/null & sleep 30s && nice -19 ~/scripts/mp3blstr2dscrbblr.sh > /dev/null #
or
# m h dom mon dow command # cron runs only every minute, thus we need sleep here * * * * * nice -19 ~/scripts/mp3blstr2dscrbblr.sh > /dev/null * * * * * sleep 30s && nice -19 ~/scripts/mp3blstr2dscrbblr.sh > /dev/null #
This script is licensed under the GPL 3.0.
2012-05-10 0.4
2007-09-25 0.3
2006-11-06 0.2
2006-06-16 0.1