This page shows how to create a simple radio command to play and stop different BBC radio stations on a Raspberry Pi. Once set up, you can just type radio BBC4 to get your favourite station playing. This is useful for various reasons, for instance if you have a room with just an amplifier and speakers in then, with a Raspberry Pi, you can listen to the radio (and with other software your music collection). You can also listen to BBC 6 Music which you cannot get on FM.
Attention!
2014-05-18: There is now a second, updated post on getting BBC radio on a Raspberry Pi.
Getting BBC radio streaming from a Raspberry Pi is something I’ve been wanting to do since I started playing around with them. I’ve seen various impressive solutions involving re-purposing old portable radios but I never got the hang of what needed doing in software.
This tutorial is based on a Raspberry Pi with the latest version of Raspbian installed (2014-01-07), updated using rpi-update. The OS also has some other packages installed to enable it to be a UPnP renderer. This is all documented in a previous post.
Part of the complication with BBC radio stations is that the URLs required to stream from change periodically. First of all therefore we need a script to find the URLs and cache them. The “playlist” URLs do not change, but their contents does. Lets look at one using the “curl” command:
$ curl http://www.bbc.co.uk/radio/listen/live/r1_aaclca.pls NumberOfEntries=2 File1=http://bbcmedia.ic.llnwd.net/stream/bbcmedia_intl_lc_radio1_p?s=1399793891&e=1399808291&h=6c19055ef19b6b3acafc59f381af6fc6 Title1=No Title Length1=-1 File2=http://bbcmedia.ic.llnwd.net/stream/bbcmedia_intl_lc_radio1_q?s=1399793891&e=1399808291&h=5ada50d070397aa72d01532281aad710 Title2=No Title Length2=-1
The actual URL for streaming is the one following File1=. What we need to do is download all the playlists we want and extract each of these URLs. To do this, create a script called bbc_radio_update, e.g. using sudo vi /usr/local/bin/bbc_radio_update:
#!/bin/bash set -e URLS=/var/local/bbc_radio/urls rm -f $URLS declare -A radios radios["BBC1"]="http://www.bbc.co.uk/radio/listen/live/r1_aaclca.pls" radios["BBC1x"]="http://www.bbc.co.uk/radio/listen/live/r1x_aaclca.pls" radios["BBC2"]="http://www.bbc.co.uk/radio/listen/live/r2_aaclca.pls" radios["BBC3"]="http://www.bbc.co.uk/radio/listen/live/r3_aaclca.pls" radios["BBC4"]="http://www.bbc.co.uk/radio/listen/live/r4_aaclca.pls" radios["BBC4x"]="http://www.bbc.co.uk/radio/listen/live/r4x_aaclca.pls" radios["BBC5l"]="http://www.bbc.co.uk/radio/listen/live/r5l_aaclca.pls" radios["BBC5lsx"]="http://www.bbc.co.uk/radio/listen/live/r5lsp_aaclca.pls" radios["BBC6"]="http://www.bbc.co.uk/radio/listen/live/r6_aaclca.pls" radios["BBCan"]="http://www.bbc.co.uk/radio/listen/live/ran_aaclca.pls" for k in "${!radios[@]}" do pls=${radios[$k]} curl -s $pls | grep File1 | sed "s/File1=/$k, /" >> "$URLS" done
We then need to make the script executable (by root), create a directory for the output URLs to be placed and run the script:
$ sudo chmod 744 /usr/local/bin/bbc_radio_update $ sudo mkdir /var/local/bbc_radio $ sudo bbc_radio_update
To look at the output, just cat the file (note the contents of this file changes: your will not be the same):
$ cat /var/local/bbc_radio/urls BBC4, http://bbcmedia.ic.llnwd.net/stream/bbcmedia_lc1_radio4_p?s=1399723465&e=1399737865&h=2cebe3f0ad99df0e6f0f4e56ca4d7736 BBC6, http://bbcmedia.ic.llnwd.net/stream/bbcmedia_lc1_6music_p?s=1399723579&e=1399737979&h=b85295564b4afb786f533d75023ba57c BBC1, http://bbcmedia.ic.llnwd.net/stream/bbcmedia_lc1_radio1_p?s=1399723596&e=1399737996&h=7a36c56eac5cc55114da6d8f5dfa8558 BBC3, http://bbcmedia.ic.llnwd.net/stream/bbcmedia_lc1_radio3_p?s=1399723367&e=1399737767&h=5857c11d8507a3bef9ed74ae6d59921a BBC2, http://bbcmedia.ic.llnwd.net/stream/bbcmedia_lc1_radio2_p?s=1399723512&e=1399737912&h=dad579513911b0b087cb474b7a448c6f BBC4x, http://bbcmedia.ic.llnwd.net/stream/bbcmedia_lc1_radio4extra_p?s=1399723639&e=1399738039&h=60b10f86626cb7150269aa08e2b27910
To make this script run every day (at 6.25am by default), put a symbolic link to it from the cron.daily folder:
$ sudo ln -s /usr/local/bin/bbc_radio_update /etc/cron.daily/
Now we have the necessary URLs we need to play them. Although I use gstreamer with gmediarender as a UPnP renderer I cannot get it to play the BBC stations so instead we use mpd and control it with mpc. Firstly we need to install them (and ignore the errors):
$ sudo apt-get install mpc mpd ...etc... Setting up mpc (0.22-1) ... Setting up mpd (0.16.7-2) ... insserv: warning: script 'mathkernel' missing LSB tags and overrides [....] Starting Music Player Daemon: mpdlisten: bind to '[::1]:6600' failed: Failed to create socket: Address family not supported by protocol (continuing anyway, because binding to '127.0.0.1:6600' succeeded) Failed to load database: Failed to open database file "/var/lib/mpd/tag_cache": No such file or directory . ok
At this point if we try to use mpc, mpd can’t access the ALSA output. Looking in /var/log/mpd/mpd.log we see:
output: Failed to open "My ALSA Device" [alsa]: Failed to open ALSA device "hw:0,0": Device or resource busy
Edit /etc/mpd.conf and comment out some lines:
audio_output { type "alsa" name "My ALSA Device" # device "hw:0,0" # optional # format "44100:16:2" # optional # mixer_device "default" # optional # mixer_control "PCM" # optional # mixer_index "0" # optional }
The key change may be the mixer_device line (not sure). Then restart the mpd service:
$ sudo /etc/init.d/mpd restart
Finally, we need a helpful script to make controlling mpd easy. Save this script as /usr/local/bin/radio:
In the script, “$1” is the first argument given to the radio command. So, for instance, with radio BBC4 $1 will be “BBC4”. The case statement deals with stop, status and stations and then for anything else we get to the “grep” in line 16. That searches the URLs file for e.g. “BBC4, ” and sends the output to /dev/null (to get rid of it). The next line asks if “$?” is equal to zero: “$?” is the return code of the last command (the grep) and if it is zero then it means that grep found something and so the station exists in the URLs file. In this case we clear the mpc playlist (and suppress the status message with “-q”), add the radio station’s URL to the queue and play it. To get the correct URL out of the file (for the mpc add command) we use grep again and pipe the output into the cut command which splits a line, setting the delimiter to a comma and choosing the second field.
Make it executable and try it out:
$ chmod 755 /usr/local/bin/radio $ radio BBC4 http://bbcmedia.ic.llnwd.net/stream/bbcmedia_lc1_radio4_p?s=1399790284&e=1399804684&h=32d5597bc6388bb9da0414c501c900ab [playing] #1/1 0:00/0:00 (0%) volume: n/a repeat: off random: off single: off consume: off $ radio status BBC Radio 4 [playing] #1/1 41:02/0:00 (0%) volume: n/a repeat: off random: off single: off consume: off $ radio BBC1 http://bbcmedia.ic.llnwd.net/stream/bbcmedia_lc1_radio1_p?s=1399790041&e=1399804441&h=6895cc667ccad6176fcfd7618960c7b8 [playing] #1/1 0:00/0:00 (0%) volume: n/a repeat: off random: off single: off consume: off $ radio stop
Options are “status”, “stop”, “stations” and the station names as found in the URL file (“BBC1”, “BBC2”, “BBC3”, “BBC4”, “BBC4x”, “BBC5l”, “BBC5lsx”, “BBC6”, “BBCan”). Obviously, the output could be tidied up but it’s good enough for now. If you use this on the same Raspberry Pi as you use for playing music via UPnP then you will find that the sound from both systems is mixed and comes out at the same time.
There’s lots of scope for using this command in other projects to enable easier control of the radio: watch this space!
Updates:
Comments
Comments powered by Disqus