Soma.fm and Mplayer

2018/12/20

I like to listen to soma.fm at work. I also like to do everything (as much as possible) in the command line so I don't have to context switch between applications too much. For years I've used mplayer to listen in. I eventually got tired of forgetting the playlist URL and wrote the following bash function so that I'd only have to remember the name of the playlist I wanted.

soma() {
  mplayer -playlist http://somafm.com/"$1"
}

This worked well for a couple of years, really. I usually only listen to one or two stations and can easily remember the name of the station's playlist file. Today I decided that I wanted to be able to explore new stations with this shell function as well. Enter the new bash function and a bash completion script.

The new bash function parses https://somafm.com/listen for the MP3 streams and prints them to STDOUT:

somalist() {
  curl -s https://somafm.com/listen/ | awk -F '[<>]' '/MP3:/ { print $4 }' | awk -F '"' '{print $2}' | tr -d \/
}

This is not great but it works, for now. Parsing html with awk/bash/sed or any other generic interpreter is always hit or miss. Right now this works. In the future, maybe it won't work so great. I'm prepared to accept this and fix it as needed. Now that we have a command that can play our playlists and one that can list them, we need tie it all together with bash completion.

Bash completion scripts are what automatically tab complete options and arguments. These can be static or dynamic. In our case, we want to provide the output of somalist() to the user when they type soma and press the <tab> key. On MacOS the following file should be placed in /usr/local/etc/bash_completion.d (assuming you're using Homebrew). If you're on Linux, it will likely be /etc/bash_completion.d. Consult your distribution specific documentation for more details:

#!/usr/bin/env bash

_soma_completion() {
    if [ "${#COMP_WORDS[@]}" != "2" ]; then
        return
    fi

    COMPREPLY=($(compgen -W "$(somalist)" -- "${COMP_WORDS[1]}"))
}

complete -F _soma_completion soma

Source this file with source /usr/local/etc/bash_completion.d/soma and try it out by typing soma followed by the key. As an added bonus, it will give you the most closely matching result if you type a partial name in.

Conclusion

This works for me. It's a little fragile but I found it useful enough that I'd share it. Check out my Github if you're interested in some of the other scripts I whip up and updates to this if I decide to make improvements in the future.

<< Building GRPC on CentOS 6 Sports in my Life >>