Playing music from the command line
Last updated: December 29, 2013
By far the most common way for modern unix users to listen to music on their computers is to use a graphical music player based on the concept of scrollable playlists which are loaded from files. The most well known and widely used of these players in XMMS, which is designed to look like the Windows program WinAmp (or at least, how WinAmp used to look almost 10 years ago, when it was simple). When I first switched from Windows to Linux in 2000, this was how I played my music too. (update in 2012: Wow, XMMS! I think that's probably considered a bit old school these days. Maybe VLC is the new standard GUI?)
In recent years, however, I have played my music exclusively from the command line, using simple programs like mpg321 (for mp3s) or ogg123 (for Ogg Vorbis files). mpg321 is a GPL clone of mpg123, and they're largely interchangeable. I do this for a number of reasons. Probably mostly because I have a very strong minimalist streak, but a definite second place is the rather more convincing fact that playing my music from the command line allows me an absolutely unprecedented amount of flexibility. This short document explains how by naming my music collection appropriately I can quickly play whatever I want however I want in a straightforward and maintenance free way. I think this is a good showcase example for the idea that the command line is generally the best way to do things once you know how.
What's in a name?
All the mp3s in my music collection are named according to the following scheme:
/home/luke/Music/<Band>/<Album>/<Track Number> - <Song title>.mp3
This scheme has been chosen to allow me a level of flexibility which is simply unachievable using graphical, playlist based players like XMMS or BMP. Using mpg321 (or, just as well, ogg321), I can do the following:
Play every song in my collection in a continuous random loop (this is what the -Z switch does):mpg321 -Z /home/luke/Music/*/*/*
Play every song by Dragonforce in a continuous random loop:mpg321 -Z /home/luke/Music/Dragonforce/*/*
Play the Manowar album "Gods of War" with its original track ordering (the track numbers at the start of the filenames take care of this when there is no -Z):mpg321 /home/luke/Music/Manowar/Gods\ of\ War/*
Play three completely arbitrary albums with their original track order, one after the other with no intervention required:mpg321 /home/luke/Music/Andromeda/Extension\ of\ the\ Wish/* /home/luke/Music/Rammstein/Sehnsucht/* /home/luke/Music/Iced\ Earth/Horror\ Show/*
Thanks to tab completion in any modern unix shell, I can belt out any of the above commands in well under 10 seconds (typically I issue these commands while my working directory is /home/luke/Music, so they're actually shorter than you see above). Commands I issue commonly I typically put aliases for in my ksh profile file (e.g. playall plays everything in a continuous random loop) so I can do them practically without thinking.
Another really neat option is being able to group music together into genres using symbolic links. If /home/luke/Music/Genres/Power\ Metal contains symbolic links to the artist directories for all my power metal bands, then I can use:
mpg321 -Z /home/luke/Genres/Power\ Metal/*/*/*
to play all my power metal music in a continuous random loop. Of course, you aren't limited to groupings by genre. This is basically a way of creating arbitrary playlists, which can be thrown together very quickly because you can add entire albums or bands with a single symbolic link.
The GUI alternative
In order to get this sort of flexibility out of XMMS or BMP, I'd need to maintain a huge pile of playlist files - one of all my songs, one per band and one per album. Creating each playlist would involve a slow and repetitive process of mouse dragging and clicking. I would have to tediously update several playlists every time I added new music to my collection. If I ever renamed my Music directory to anything else, all of these playlists would become broken. I could write little scripts to automatically generate playlists, which would make things a bit less of a pain and more robust, but who wants to have to do that?
When I'm using any of the commands above, I have basic playback control using the keyboard. Pressing Ctrl-C will skip to the next song that is in line to be played. Double-tapping Ctrl-C within a short enough time span will terminate mpg321, permanently stopping playback until I issue the command again. If I just want to pause playback temporarily, I use Ctrl-Z to put mpg321 to sleep, and then use fg to wake it up again to resume playback.
Alternatively, most command line players allow for some more "proper" keyboard control. mpg123 takes the -C option to enable "terminal control" mode, where the space bar pauses and unpauses playback, pressing 'f' skips one track forward and 'b' skips one track back, etc. mpg321 isn't quite as good in this regard. The -K option enables "Basic Keys", in which 'n' skips the current song and 'm' toggles a mute mode. This doesn't really give you much control beyond what you can get with Ctrl-C and a physical mute button on your laptop body or keyboard. (update in 2013: I got an email from someone pointing out that I had the -C and -K options back-to-front in the above. It only took six years for anybody to notice!)
One thing that is easy to do in a GUI music player but not on the command line is to skip immediately to one particular song. I don't consider this disadvantage great enough to cancel out all the other advantages, though: it's quick enough to press Ctrl-Z to put the current command to sleep, use tab completion to quickly write out a new command to play just that one song and then use fg to resume the previous command. This probably isn't quite as quick as scrolling through an alphabetically sorted list and double clicking, but I don't really find myself jumping to particular songs all that often anyway.
What if I don't want to listen to mp3 files on my hard drive, but instead want to listen to an internet radio station? mpg321 doesn't support streaming audio, but mpg123 does, with the -@ option. The following command plays Soma FM's popular "Groove Salad" station:
mpg123 -@ http://somafm.com/startstream=groovesalad.pls
I just alias salad to this so I don't have to remember it. Of course, you can play any of Soma FM's stations by changing the url. Go to the station's page and look for the line that looks like this:
Listen: AAC: 128k 64k 32k MP3: 128k 56k 32k
Click on the MP3 link for the quality you want and it will take you to a separate page, with a "Start stream in external player now" link at the top. Copy the URL of that link and pass it to mpg123 -@ and you should be fine.
The following command plays Slay Radio:
mpg123 -@ http://www.slayradio.org/tune_in.php/128kbps/listen.m3u
Again, I just alias this to slay. You can play Slay radio at lower quality (to save bandwidth or reduce stuttering on a slow connection) by replacing the "128kbps" in the URL above with "56kbps" or "24kbps".
Free up screen real estate, disk space and RAM and, more importantly, listen to your music the way you want to, when you want to - play your music from the command line!