Playing streams off the web with FFplay

© Mmagellan - freeimages.com

© Mmagellan - freeimages.com

Compact Radio

With just a few lines of shell code, you can build a flexible and easily adaptable stream player.

You don't need to start resource-hungry multimedia applications to get a bit of Internet radio. Some command-line programs on Linux can play streams off radio stations. And, a simple shell script is quite enough as a wrapper to manage Internet radio stations easily or to download streams and then play them at your leisure.

The core of the script is a module from the FFmpeg suite [1], which also includes FFplay along with FFmpeg, FFprobe, and FFserver.

FFplay lets you easily enjoy a web station on the command line (Figure 1). For example, the following command is all you need to play the WABC radio station from New York:

$ ffplay http://8703.live.streamtheworld.com:80/WABCAM_SC

With this approach in mind, and with some Bash magic, you can cobble together a slim radio receiver for the shell.

Figure 1: Thanks to the individualized window title, you can easily tell which station FFplay is currently playing.

Collecting URLs

When searching for a good Internet address that can handle most radio stations, you'll sooner or later land at Live-radio [2]. You can find hundreds of radio stations there, in various genres from rock to classical to talk.

As mentioned previously, you simply give the FFplay program a URL as a parameter that it uses to call up a radio station stream. To get this URL, you need to open the PLS files, which are actually meant for the external player, in an editor. You can get these files from Live-radio. Listing 1 shows the sample structure of such a file.

Listing 1

Sample File Structure

[playlist]
File1=http://1531.live.streamtheworld.com:80/WAALFMAAC_SC
File2=http://1531.live.streamtheworld.com:3690/WAALFMAAC_SC
File3=http://1531.live.streamtheworld.com:443/WAALFMAAC_SC
Title1=WAALFMAAC_SC
Title2=WAALFMAAC_SC-Bak
Length1=-1
NumberOfEntries=3
Version=2

The content in square brackets on the first line makes the contents pretty obvious: It's essentially a playlist. The Title1 is the display name of the radio station; File1 through File2 provide the station's URLs (there can be one or more of these). Because we're talking about a continuous stream, a Length1 of -1 indicates that the player should continuously stream the broadcast. The other entries are largely self-explanatory. Sometimes, the PLS file indicates two or more streams, of which you can choose the one you want.

Homemade

You now need a script for a small web radio that connects the URLs with a name suitable for selectability. This is done via an associative array in Bash. In this case, you start it with a declare statement along with the -A option.

The assembled URLs now go into the array. In Listing 2, the array is set up on lines 3 through 7, where the display names act as keys. Thus, all entries are in one place, and you don't need to alter the actual script code later if you add new stations.

Listing 2

URLs in the Array

01 #!/bin/bash
02 declare -A STATION
03 STATION["CBS San Francisco"] = "http://2133.live.streamtheworld.com:80/KCBSFMDIALUP_SC"
04 STATION["WAAL 99.1 FM"]="http://1531.live.streamtheworld.com:80/WAALFMAAC_SC"
05 STATION["News Talk Radio 77"]="http://8703.live.streamtheworld.com:80/WABCAM_SC"
06 STATION["WFAN Sports Radio - AM 660"] = "http://8703.live.streamtheworld.com:80/WFANAMDIALUP_SC"
07 STATION["The Lake - WLKK - FM 107.7"] = "http://3143.live.streamtheworld.com:80/WLKKFM_SC"
08
09 clear
10 echo "Select radio station:"
11
12 select ENTRY in "${!STATION[@]}"; do
13   TITLE="${ENTRY}"
14   URL=${STATION[${ENTRY}]}
15   ffplay -x 300 -y 100 -window_title "${TITLE}" ${URL} &>/dev/null
16 done

Line 9 includes a simple clear to clear the terminal before you begin the program output with an echo command. Line 12 has a select statement that uses the key in the previously defined array to build a menu. Here, the exclamation point before the name of the array variables ensures that shell outputs the key. The [@] subscript for STATION receives these values enclosed in quotes so that the select statement interprets the space characters in the names correctly.

After the do statement, two variables TITLE and URL obtain the correct assigned values. After that, ffplay plays the station, with the subsequent options controlling width, height, and title of the output window. The &>/dev/null command at the end ensures that the program messages don't show up on the screen.

Some stations take a few seconds before FFplay picks up the stream, at which point the output window appears and the software plays the station. If the radio program doesn't suit you, simply shut off the station and select another one from the menu. You end the shell script with the Ctrl+C key combination.If you want to extend the list with further stations, simply expand the associative array at the beginning of the script with the corresponding entries. Be careful, however, not to have any same-named keys, in which case the shell will reassign the key to the newer entry.

To install the script system-wide, it would help to keep the station list in a separate file. This would let users each maintain their own list of stations. In principle, the only change to the script would be in lines 3 through 7 by replacing the URL lines with a source <filename> statement.

Recording

Taking things a bit further, it may at some point occur to you that it would be nice not only to hear the radio station but to record a program on it. Because streams often already contain MP3 files, you can use FFmpeg to convert the stream into an MP3 file (see Listing 3).

Listing 3

Converting to MP3

$ ffmpeg -i http://87.118.64.215:8000/ -acodec copy $(date +"%Y-%m-%d_%H%M%S").mp3

The program copies the actual user data (with the -acodec copy option). During this process, it adds a real header to the file that converts the file to a full-fledged MP3. You can then copy the file to another device, such as a smartphone, so as to fully enjoy the recordings.

To make things even easier, insert this line in a script or create a keyboard shortcut or start button on the command bar or menu, so that you can have things at the push of a button.

Be careful, however, to activate the Run in terminal option when applying the button or keyboard shortcut; otherwise, you can't stop the recording with Ctrl+C, and it will run along happily in the background until you shut down the computer or issue a kill command.

Conclusion

The script in Listing 2 easily can be enhanced in many ways. One possibility, as already mentioned, is outsourcing the station list for individualized listings. Alternatively, you could provide the recorded audio files in a separate selection.

Moving from an idea to a multimedia tool is often very easy in Linux. The large number of command-line tools that have appropriate functions make it easy to include these functions into a corresponding script. You can then tailor the program to your needs and open possibilities that many classic media players don't necessarily provide.

Infos

  1. The FFmpeg suite: http://www.ffmpeg.org
  2. Live-radio: http://www.live-radio.net