ashuffle
Fork changes: Keep 2 songs in list instead of 1, to avoid foobar2000 clients occasionally stopping playback between tracks when streaming through MPD:s http output (might break but seems to work)
Table of Contents:
features
ashuffle is a C re-implementation of my ashuffle python script, an application for automatically shuffling your mpd library in a similar way to a more standard music player's "shuffle library" feature.
usage
ashuffle has two modes. The first one (and the simpler of the two) is to simply queue some number of songs randomly selected from your mpd library. To do this you simply run:
$ ashuffle --only 10 # ashuffle --only <number of songs to add>
which will add 10 random songs to your queue.
In the second (more interesting) mode, ashuffle will wait until the last song in the queue has finished playing, at which point it will add another song to the queue. In this creates a 'stream of music' where songs will be continuously played, at random, to infinity. Additionally, since ashuffle only adds one song at a time, and only adds that song once the last song in the playlist has finished playing, you still retain control over your queue. This way, you can add some song you want to hear to the queue, and the random songs will simply continue afterwards.
Additionally, ashuffle uses mpd's idle functionality so it won't drain cpu polling to check if the current song has advanced.
To use the second mode, run ashuffle without the --only
argument.
$ ashuffle
running in a non-standard configuration
If you're running MPD on a non-standard port or on a different machine, ashuffle
will respect the standard MPD_HOST
and MPD_PORT
environment variables to
set the host and port mpd is listening on respectively.
Also following standard MPD tools, a password can be supplied in the MPD_HOST
environment variable by putting an @
between the password and the hostname.
For example, one can run ashuffle as follows:
$ env MPD_HOST="<password>@<hostname>" MPD_PORT="<port>" ashuffle ...
Or without the password by just omitting the <password>
and @
from the
MPD_HOST
variable.
--nocheck
shuffling from files and By supplying the -f
option and a file containing a list of song URIs to
shuffle, you can make ashuffle shuffle and arbitrary list of songs. For
example, by passing -f -
to ashuffle, you can have it shuffle over songs
passed to it via standard in:
$ mpc search artist "Girl Talk" | ashuffle -f -
As explained in more detail below, if song URIs are passed to ashuffle using
this mechanism, ashuffle will still try to apply exclusion rules to these
songs. If the song URIs you want ashuffle to shuffle over do not exist
in your MPD library (for example if you are trying to shuffle URIs with the
file://
schema), ashuffle will exclude them by default. If you pass the
--nocheck
option to ashuffle, it will not apply the filtering rules, allowing
you to shuffle over songs that are not in your library.
help text
usage: ashuffle -h -n [-e PATTERN ...] [-o NUMBER] [-f FILENAME]
Optional Arguments:
-e,--exclude Specify things to remove from shuffle (think blacklist).
-o,--only Instead of continuously adding songs, just add 'NUMBER'
songs and then exit.
-h,-?,--help Display this help message.
-f,--file Use MPD URI's found in 'file' instead of using the entire MPD
library. You can supply `-` instead of a filename to retrive
URI's from standard in. This can be used to pipe song URI's
from another program into ashuffle.
-n,--nocheck When reading URIs from a file, don't check to ensure that
the URIs match the given exclude rules. This option is most
helpful when shuffling songs with -f, that aren't in the
MPD library.
See included `readme.md` file for PATTERN syntax.
patterns
Patterns are a list of key-value pairs given to the --exclude
flag. A pair is
composed of a 'field' and a 'value'. A field is the name
of an MPD tag (e.g. artist, title, album) to match on (case insensitive) and
'value' is a string to match against that field. So, if I wanted to exclude
MGMT's album 'Congratulations' in the shuffle I could supply a command
line like the following:
$ ashuffle --exclude artist MGMT album "Congratulations"
Since typing in an exact match for all songs could become quite cumbersome, the 'value' field will match on substrings, so you only have to specify part of the search string. For example, if we wanted to match Arctic Monkeys album 'Whatever People Say I Am, That's What I'm Not' we could shorten that to this:
$ ashuffle --exclude artist arctic album whatever
Multiple --exclude
flags can be given, the AND result
of all flags will be used to match a given song. For example, if we wanted to
exclude songs by MGMT and songs by the Arctic Monkeys, we
could write:
$ ashuffle --exclude artist MGMT --exclude artist arctic
Additionally, the -f
flag can be used to shuffle over more complex matches. For
example, if we wanted to listen to only songs by Girl Talk except the Secret
Diary album, we could use mpc
to generate a list of Girl Talk songs and then
use a --exclude
statement to filter out the Secret Diary album:
$ mpc search artist "Girl Talk" | ashuffle --exclude album "Secret Diary" --file -
shuffle algorithm
Currently ashuffle is using a fairly unique algorithm for shuffling songs. Most applications fall into two camps: true random shuffle, and 'random list' shuffle. With true random shuffle, no restrictions are placed on what songs can be selected for play. It's possible that a single song could be played two or even three times in a row because songs are just being draw out of a hat. With 'random list' shuffle, songs to be shuffled are organized into a list of songs behind the scenes. This list is then scrambled, and then played like a normal playlist. Using this method songs won't be played twice in a row, but the once the playlist has been played it will either loop (playing the same random set again), or be re-scrambled and played again, so it can still get repetitive. Also, since there's no chance that a song can be played again, it won't feel very random, especially when listening for a long time. I often start noticing song order once the random-list wraps around.
ashuffle's approach is an attempt at a happy medium between these two approaches. Essentially, it keeps two lists of songs, a 'pool' of the songs it's shuffling, and a 'window' which is a short, ordered, playlist of songs. When the program starts, ashuffle builds the window randomly by taking songs out of the pool, and adding them to the window. When a new random song is added to the MPD queue, the 'top' song of the window, is taken off, added to the queue, and then put back into the pool. Then another song is added to the window so that the next request can be fulfilled.
dependencies
The only dependency is 'libmpdclient' which, you can probably install via your package manager. For example on debian based distributions:
sudo apt-get install libmpdclient-dev
or on OS X using brew:
brew install libmpdclient
building
Download the latest release, untar/unzip it and then cd into the directory and run:
make
Then run
sudo make install
to install the binary. If you want to use a prefix other than /usr/local
you
can supply an alternate by running make install
like so:
sudo make prefix=<prefix> install
You can uninstall the program later by running
sudo make uninstall
Note: You'll have to supply the prefix again if you used a custom prefix.
Oh, and in the case you're wondering why it's called 'ashuffle' it's because it implements 'automatic shuffle' mode for mpd.