I’m exploring the option of using a single, authoritative URL for a broadcast which can be sourced from a constantly changing number of locations without the listener being aware of this fact. Icecast 2.3.1 has all the configuration and administration options for this to be possible on paper, though in practicality, this is proving close to impossible using only the options in Icecast.
Icecast 2 has a concept called fallback mounts. This means that a mountpoint can be configured to have a secondary mountpoint to fall back to in the case that the first’s source disconnected. This peaked my interest since it also includes the option to fallback to the primary when it’s source reconnects. An obvious use for this is an “all circuits are busy” kind of message in the case the the primary is offline and the ability to remove the message automatically when the primary comes back.
But what if this could be used to switch between a primary source and many different sources which are broadcast from remote live locations, without requiring the listener to reconnect? It turns out that not only does Icecast offer a way to define a static mount point as a fallback, it also has an interface via HTTP to update the fallback for any mountpoint. This means that a dynamic fallback can be configured for a single static mount.
In practice, the current release of Icecast makes this difficult, if not impossible. The dynamic fallback configuration functions erratically, if at all. A dynamic fallback cannot be configured to reconnect to the primary source when it reconnects. This could be solved by detecting when the source reconnects and issuing a move listeners HTTP command to the server to bring them back. But this also isn’t good enough because if the primary source is offline, and a listener connects to it, HE WILL NOT FALLBACK TO THE DYNAMIC MOUNTPOINT! Said listener will get nothing, a 404 error that the source isn’t connected. If there is a static fallback defined in the Icecast configuration, the listener will be connected to this one. This is obviously a bug, though the Icecast release hasn’t been updated since 2005 so I’m not expecting anything to be done for me.
After ruling out dynamic fallbacks via HTTP, I moved to another option. If fallbacks can only be configured properly in the server XML file, then I’d have to make an interface to modify that file when a live source connects and reload the server configuration to update the fallback. This would produce the same results as HTTP fallbacks but would function properly.
So I tried it and it worked…but.
There appears to be a problem with changing a stream’s source with the mp3 codec and iTunes as the listener. Each time a fallback sequence is executed, listen to primary, kill primary, listen to fallback, restart primary, listen to primary, the audio begins to skip, much like a dirty CD. After about 30 seconds, the stream will either “fix itself” by rapidly skipping until it stopps, like it’s trying to catch up to something or the server will disconnect with the error that iTunes couldn’t keep up. I don’t know if it’s the client or the server that’s causing this. I’ll do tests with other clients and codecs.
So for now there’s only one solution I can think of despite all these limitations. Generate a unique URL which points to a script with a query string. The script will parse this query string and reply with a HTTP 302 Moved Temporarily redirect to the proper Icecast stream. The mountpoint that is defined as the “proper stream” is held in a database and can be changed through a standard client interface. The end result? A single authoritative server URL, despite the fact that the stream URLs are constantly changing. But what about the people already listening when a stream URL gets updated? They will have to be moved via an HTTP request to the server.