Skip to content

Instantly share code, notes, and snippets.

@Pigpog
Last active October 12, 2023 09:25
Show Gist options
  • Save Pigpog/48943c9bbfe990c4a0cf2aab327620d7 to your computer and use it in GitHub Desktop.
Save Pigpog/48943c9bbfe990c4a0cf2aab327620d7 to your computer and use it in GitHub Desktop.
FOR MPD - Skips songs you don't like. Uses a per-song score, calculated based on whether you skip the song or let it play. The only dependency is MPC, as this script is almost entirely BASH. When the next song's score is negative, the script "rolls the dice" and if the score is <= the dice roll, it will skip it when it comes on.
#!/bin/bash
# Automatically skips songs you dont like
# Skipping a song decreases its score
# Playing it for >15 seconds increases it
# Songs are skipped randomly based on their score
# Location of database file
DBFILE=~/scripts/database
# Replaces grep -m1 -F $1 $DBFILE
# Outputs first line that matches *PATTERN
# Should be more efficient :)
search(){
IFS=\ ;
while read -r score title; do
[[ "$title" = "$1" ]] && echo "$score $title" && return 0;
done < $DBFILE
return 1;
}
# Replacement for tr -d '[]'
sanitize(){
echo "${1//[\[\]]/}";
}
# esoteric - remove if you're not me
echo "Loading..." > /dev/shm/mpdcurrent;
while true;
do
SKIPNEXT=0;
NOWPLAYING=`sanitize "$(mpc current)"`;
[ -z "$NOWPLAYING" ] && NOWPLAYING="!!!!!!!!!!!!!!!!";
DBLINE="$(search "$NOWPLAYING")";
SCORE=${DBLINE% *};
[ -z "$SCORE" ] && SCORE=0;
echo "Song: $NOWPLAYING";
echo "Score: $SCORE";
QUEUED=`sanitize "$(mpc queued)"`;
QUEUEDLINE="$(search "$QUEUED")";
# If a song is queued, roll dice
# If score <= roll, skip next song
[ ! -z "$QUEUEDLINE" ] && [ ${QUEUEDLINE% *} -le -$(( RANDOM % 6 )) ] &&
SKIPNEXT=1 && echo "Skipping next: $QUEUED";
# esoteric - remove if you're not me
echo "$SCORE | $NOWPLAYING" > /dev/shm/mpdcurrent;
# Count seconds until song changes
TIME_PLAYED=$(TIMEFORMAT='%0R'; time ( mpc current --wait ) 2>&1 1>/dev/null);
# The rest of this code runs when the song changes
[ $SKIPNEXT = 1 ] && [ "`sanitize "$(mpc current)"`" = "$QUEUED" ] &&
mpc next -q && continue;
if [ $TIME_PLAYED -lt 15 ]; then
echo "Played $NOWPLAYING for less than 15 seconds";
NEWSCORE=$(((SCORE-1)));
else
echo "Played $NOWPLAYING for more than 15 seconds";
NEWSCORE=$(((SCORE+1)));
fi
if [ -z "$DBLINE" ]; then
echo "Not found in database; adding";
echo "$NEWSCORE $NOWPLAYING" >> $DBFILE;
else
echo "Updating existing database entry"
DB="$(<$DBFILE)";
echo "${DB/$DBLINE/$NEWSCORE $NOWPLAYING}" > $DBFILE;
fi;
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment