HOWTO: Archive Audio Streams in to mp3 Files
I am an NPR junkie, and my new place gets awful reception. And for a long time I have admired TiVo and wondered if my life might not be better if I had a DVR for NPR programs. Add to that KQED’s obnoxious plugin/popup window and the fact that I use an older version of RealAudio to avoid Spyware, which stutters and rebuffers all the time, and I have enough motivation to rig up something different.
I have rigged up a simple system to schedule rips of programs broadcast on the KQED audio stream in to easily manageable .mp3 files. If I had one of them iPod thingies I could even listen to the radio programs on the bus. I might even get around to warezing this to interested friends via BitTorrent and CSS, which would leave us another technical explanation.
Ingredients used:
- FreeBSD running on an old laptop, for automatic, hands-free operation.
- mplayer, to rip the Windows Media stream off KQED’s web site.
- lame, to convert the audio in to mp3.
- Two shell scripts, cron, and at, to automate everything.
Where is the Audio Stream?
Mplayer is mighty and awesome, but unfortunately, you can not just click on a web page and feed it to mplayer. (Well, maybe you can and I am just dumb.) So, the first task is to find something for mplayer to chew on. In my case, this means going to http://www.kqed.org/ and clicking on the “Listen” link and selecting Windows Media and copying the URL to listen manually. You can then fetch that URL and examine the contents, and find a URL that starts with mms://. If you can play this URL in mplayer, then you are doing well.
I would share an example, but this part of KQED’s web site is throwing errors at the moment.
Ripping
I set up a simple script that launches lame and mplayer, then sits and waits for a specified time, and kills these programs off. Crude, but effective.
Scheduling
Ah, the potentially trickier part comes with scheduling. I thought this over for a couple days, and figured that a slightly clever shell script should do the trick. I wrote a script called “today” which defines a few functions, such as everday() and weekday() and runs through what the schedule should be, depending on the day of the week. It then schedules rips of the appropriate programs via at at command. You could also do a comparison with the date command to schedule special one-off recordings.
Anyway, the today script is run out of cron at midnight:
0-21:33 djh@yomama ~> crontab -l 0 0 * * * $HOME/bin/today
One other trick, on FreeBSD you have to give yourself permission to use at:
0-21:35 djh@yomama ~> cat /var/at/at.allow djh
Making it Better
Do check out the comments that follow for tips and tricks, especially Shawn Dowler who has gone and wrote a page about his revised versions of the scripts.
Responses
John
Very cool scripts! Thanks a bunch, this is working fine under FC2/linux.
To get mp3 tags in I installed mp3info and added at the end of the recorder script:
mp3info -a NPR --l $showname -t ${showname}-`date +%Y%m%d-%H%M` $ofileThat groups all the recordings for NPR/Show in itunes/mt-daapd :D
dannyman
Great tip, John. I’ll look in to integrating that in to the scripts at some point. :)
-danny
John
Danny, couple more minor updates
1) cut down on email (for Linux, anyway)
crontab entry should end as
>/dev/null 2>&1in the recorder script, end the lame and mplayer commands with
>/dev/null2) Also in recorder, you can get cleaner and smaller audio using:
$lame="/usr/bin/lame -S -V6 --vbr-new -q0 -b32 -B56 --lowpass 13.4 --athaa-sensitivity 1"(files about 10% smaller, less weird garble noise because of the low pass filter.)
and finally,
3) the correct format for mp3info is:
mp3info -a NPR -l $showname -t $dfile $ofileThanks again!
Sven
Hi, thanks for the very cool scripts. I often find it hard to connect to my favorite radio station on the first try using mplayer (crowded stream or something). So, i came up with the following function for the recorder script, which launches mplayer again if it quits:
# define function connect() to attempt connecting several times # by restarting MPlayer if it quits connect() { local i=1 while [ $i -le $1 ] do echo "Atempt connecting... $i" $mp -cache $cache -ao pcm:waveheader:file=$fifo $url > /dev/null & sleep 5 wait $! i=$[$i+1] done }You call it with the number of trials and kill it after sleeping:
# attempt connecting in background connect 6 & sleep ${duration}m kill $!Sometimes this leaves an instance of mplayer running. I don’t know why. The same could be done with the lame part in order to continue encoding when a stream has been lost. I am bash newbie, so I hope this is not too crude. Thanks again, especially for the “at” part in the today script.
beemer
I could not get recorder to work as is. Discovered that -aofile is deprecated; changed the command from
$mplayer -ao pcm -aofile $fifo $url &
to
$mplayer -ao pcm:file=$fifo $url &
Still can’t get ‘today’ to run.
Shawn Dowler
I took the ideas of this script and added some additional functionality. I have had no problemst running the today script, except that bash doesn’t seem to like an empty function. If you don’t want to use everyday (same goeas if you don’t want to use weekday) then you should comment it out and all references to it.
Here is a link to my scripts:
http://walkingtowel.org/2006/03/03/record-streaming-audio-with-linux-part-ii/
walking towel » Blog Archive » Record Streaming Audio with Linux: Part II
[…] I said I was looking into getting FIFOs working so that the filesize requirements would be reduced. It’s also more efficient this way. I was heavily influenced by the two scripts created by danny. […]
Orlando
Hi, i just wanted to know, how would I go about using these scripts on a hosted Linux web server? For example i want to automate a recording from station then make it be stored in a specific folder, to be listen to by viewers on the site at a later date. I am assuming i can install mplayer and the other parts into the directory on the webserver and beging from there and run a cron job from there etc..
it would be really helpful if you could help, thanks!!
rory
Here’s a more fleshed out version of a similar script…
http://www.netstreamshifter.com/2009/06/time-shifting-internet-radio-aka.html
Comment
Tiny Print:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>