Recording Icecast livestreams, a foolproof method.
If you want just the how-to guide skip to the end of this post. I’m including the backstory because I think it’s mildly interesting.
There are several podcast live streams I enjoy listening to at certain times of the week. However, due to the fact that I can’t always be around at the right time to listen to them live, I sometimes miss out.
A fair question would be, why not just listen to the published show? Well, I have a few reasons.
- I like to have the show as soon as possible.
- I actually enjoy unedited podcasts more than edited ones. There are often stories or jokes that don’t make it to the final show, and are only a part of the live stream.
- I enjoy hearing the hosts talk to each other about some of the behind the scenes aspects of creating the show.
- It’s interesting to hear if and when the hosts mess up, and how they will potentially fix or work around that in editing.
- Even though the audio quality is worse, I find it easy enough to listen to. The above points more than make up for the lack of high audio fidelity. I will admit, part of the fun is collecting these files that very few people have.
These live streams in question run on the on Icecast platform. This is fairly old technology, so there’s not much documentation on how to record or work with these streams. So I got to work on finding a solution. I needed 3 things:
- A way to save the output of the live stream to a file on disk.
- A method to try to constantly connect to the stream. That way it would connect right when the stream started and it would be able to pick back up in case of a disconnection. (I also needed to make sure that the first file was not overwritten if the stream reconnected, I found that out the hard way.)
- And finally, I needed a way to trigger this at certain times of the day.
I considered trying to use the command tool Streamripper. However, as far as I can tell, it hasn’t updated since 2008. That normally wouldn’t matter, but it hasn’t been updated to support recording secure HTTPS streams. That made it useless for my purposes since every stream I was interested in was HTTPS.
Finally, I discovered FFMPEG. I was already familiar with it but did not realize it had this ability. If you’re not familiar with FFMPEG, it’s a command line tool that can manipulate audio in video in almost limitless ways. However, it requires extensive Googling skills to find the series of commands that will accomplish what you want. Thankfully, the way to record is a one-liner. You’ll just need the direct url to the stream. Let’s use a local station, WFIU as an example:
ffmpeg -y -i http://hannibal.ucs.indiana.edu:8000/wfiu_hi output.mp3
However this wasn’t enough. I wanted a way to spam that command over and over. That way I could start the command before the stream and catch the first part. This has the added benefit of reconnecting quickly in case of a dropout. But, I can’t overwrite the first file. Here’s the shell script I came up with:
while [ $i -le 1320 ]; do
ffmpeg -y -i http://emf.streamguys1.com/sa008_mp3_high_web $(date +”%FT%H%M%S”).mp3
This turned out to be a reliable way to capture the entirety of a livestream. It uses a loop to attempt connecting around 2 times a second, so you can do the math on the appropriate amount of seconds for your needs. With a cron job it is easy to record streams at any time of the day. The output is a file with the exact date and time the stream started, so no files will be over written. If the script does need to reconnect, you’ll end up with multiple files, which you can stitch together with an audio editor. I like to use Fission.
If my 7 year old self would have had this technology, he would have loved it. There were certain songs on the radio he would always try to record with Voice Memos, before the days that Spotify and YouTube made music more readily available.
If I knew how to write MacOS apps I would create a GUI app for this exact purpose. None exist, sadly.