Log in

27 December 2008 @ 12:30 am
nprlive: Listen to NPR's live audio stream  
This is a horrible, horrible hack. I only put it up because it fits in my mplayer theme. It's a hack for several reasons: 1) it relies on the current line-by-line layout of XML/HTML rather than parsing it according to the language, and 2) it relies on how NPR's web site currently works (although surprisingly it works over 6 months after it was originally written). I wrote it one night when I was sick of listening to any of the audiobooks I had, as well as BBC 7 (you'll note that this script is kinda-sorta like my first script posted here, bbc7live).

sysadmin@artoo:~$ nprlive
MPlayer 1.0rc2-4.2.3 (C) 2000-2007 MPlayer Team
CPU: Intel(R) Core(TM)2 Duo CPU E6750 @ 2.66GHz (Family: 6, Model: 15, Stepping: 11)
CPUflags: MMX: 1 MMX2: 1 3DNow: 0 3DNow2: 0 SSE: 1 SSE2: 1
Compiled with runtime CPU detection.
mplayer: could not connect to socket
mplayer: No such file or directory
Failed to open LIRC support. You will not be able to use your remote control.

Playing mms://a1671.l2063252432.c20632.g.lm.akamaistream.net/D/1671/20632/v0001/reflector:52432?v1st=&mt=5.
STREAM_ASF, URL: mms://a1671.l2063252432.c20632.g.lm.akamaistream.net/D/1671/20632/v0001/reflector:52432?v1st=&mt=5
Resolving a1671.l2063252432.c20632.g.lm.akamaistream.net for AF_INET6...
Couldn't resolve name for AF_INET6: a1671.l2063252432.c20632.g.lm.akamaistream.net
Resolving a1671.l2063252432.c20632.g.lm.akamaistream.net for AF_INET...
Connecting to server a1671.l2063252432.c20632.g.lm.akamaistream.net[]: 1755...
unknown object
unknown object
file object, packet length = 960 (960)
unknown object
stream object, stream ID: 1
unknown object
unknown object
data object
mmst packet_length = 960
Cache size set to 64 KBytes
Cache fill: 12.50% (8192 bytes)
ASF file format detected.
[asfheader] Audio stream found, -aid 1
Clip info:
copyright: 2008
comments: Visit http://www.npr.org/audiohelp/progstream.html for more information.
Forced audio codec: mad
Opening audio decoder: [ffmpeg] FFmpeg/libavcodec audio decoders
AUDIO: 44100 Hz, 1 ch, s16le, 20.0 kbit/2.84% (ratio: 2501->88200)
Selected audio codec: [ffwmav2] afm: ffmpeg (DivX audio v2 (FFmpeg))
AO: [pulse] Failed to connect to server: Invalid argument
AO: [alsa] 48000Hz 1ch s16le (2 bytes per sample)
Video: no video
Starting playback...
A:1237294.6 (343:41:34.6) of 2133437440.0 (-24.-8) 0.6% 15%

Here's the code. I hope it doesn't lower whatever respect you may have for me.

while true; do
GET `GET 'http://www.npr.org/templates/dmg/dmg_wmref_em.php?id=1&type=5&date=&au=1&pid=06532611&random=0755420114&guid=000825B1A009071C5F633BAA61626364&upf=Linux%20i686&mtype=WM&ssid=&topicName=News&subtopicName=Program_Stream&prgCode=&hubId=&thingId=&tableModifier=' \
| grep ENTRYREF \
| awk '{print $2}' \
| sed -e 's/href="//' -e 's/"$//' ` \
| grep mms:// \
| awk '{ print $2 }' \
| sed -e 's/href="//' -e 's/"$//' \
| xargs mplayer

It's an infinite loop to compensate for any breaks in the program stream. It uses the GET command, which is part of the libwww-perl library. Note that it's called twice, first within a pair of backticks ("`"), then outside of the backticks. The URL is awful, which is NPR's fault. It probably could be simplified; most URLs that long are because the programmers are lazy and embed all the state data into the call even if they aren't needed.

But NPR doesn't deserve all (or even much) of the blame for this hack. First I grep for a keyword, then count positions in the grepped line, then do some string replacements, more grep, more counting, and more replacements. The result is a mms:// URL that is passed to mplayer via xargs.

It's a hack, and very brittle.