Playing Internet radio streams with MPD/MPC (with a little bash and python)

I wanted a way to easily import Internet radio streams into MPC, and then be able to easily change the station to the next one in the playlist.
Scouring the web for radio streams was easy, and I soon got together a list of radio station URLs. The problem was, most of these URLs are playlists already, some .pls, some .m3u, and some are direct URLs to the stream.

I decided I needed to hack something together to parse these stream URLs, and pull out the raw feed URL, put these as items within a local playlist, and then something to wrap around MPC to control prev/next and display the Stream name in a better way.

MPC can move to the next or previous item in a playlist by passing it the “next” or “prev” parameters, and will return the name of the currently playing item when it is passed the “current” parameter.

I knocked together a bash script to parse through my list of streams (contained in a text file called streams.txt) and output to a playlist called playlist.m3u located in ~/playlists/
I’ve kept this as a static location as I had configured /etc/mpd.conf to read that folder as the playlist location (playlist_directory in mpd.conf)

The bash script reads each line in streams.txt, gets the playlist, does a bit of simple detection to see which type it is, and then grabs the stream URL from the playlist file. The only caveat to this is that if you accidentally enter the direct stream URL into streams.txt, then when the bash script grabs the playlist, it will actually just stream the audio to disk. That one caught me out for a few minutes!

Once the playlist is created, it pushes it to MPC, and then launches the python file, which uses curses and subprocess to display the stream name and control which stream is playing.

There’s still plenty of bugs in the code – I’m not a programmer by any means, but it’s an interesting little gadget that I had fun with:
echo Initialising stations, please wait...
#remove previous playlist
rm ~/playlists/playlist.m3u
#initialise mpc
mpc clear -q
mpc update -q
mpc -q repeat on
#iterate through streams.txt and parse for stream URLs
for URL in $(cut -d, -f2 < streams.txt) do wget $URL -q -O output.pls grep "File1=" output.pls | sed 's/File1=//g' > streamaddr
if [[ ! -s streamaddr ]]; then
grep "Ref1=" output.pls | sed 's/Ref1=//g' > streamaddr
if [[ ! -s streamaddr ]]; then
cat output.pls > streamaddr
export streamadd=$(cat streamaddr)
#add stream URL to playlist
echo $streamadd >> ~/playlist.m3u
rm streamaddr
#start mpc
rm output.pls
mpc load playlist.m3u
mpc -q update
import subprocess
import curses
import time
subprocess.Popen(["mpc", "play", "-q"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdscr = curses.initscr()
stdscr.addstr(0,10,"MPC Radio player (from streams.txt)")
stdscr.addstr(1,10,"Hit 'q' to quit")
currentplay = subprocess.check_output(["mpc", "current"])
key = ''
while key != ord('q'):
key = stdscr.getch()
currentplay = subprocess.check_output(["mpc", "current"])
if key == curses.KEY_LEFT:
subprocess.Popen(["mpc", "prev", "-q"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
elif key == curses.KEY_RIGHT:
subprocess.Popen(["mpc", "next", "-q"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
subprocess.Popen(["mpc", "stop", "-q"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

Sample streams.txt:

Share This!





2 responses to “Playing Internet radio streams with MPD/MPC (with a little bash and python)”

  1. Interested Reader Avatar
    Interested Reader

    Hey there,

    I know this is an old post from 2013, but maybe there’s still chances you check your comments from time to time. I had a question regarding the bash script – I copy-and-pasted and tried to run, but it throws an syntax error. “Unexpected token ‘|’ on line 10”. Is this script dated? I don’t see anything wrong with the pipe, really..

    Thanks in Advance!

    1. Admin Avatar

      Hey, my only thought is that the sed command on the line after should I think be on the end of line 10, rather than on it’s own line – that’s my fault, I should have checked it formatted correctly when I put it in the post.


Leave a Reply

Your email address will not be published. Required fields are marked *