Shoutcast/Icecast in FP10 without hogging system memory
Over at tunamedia.co.uk, we’ve released a demo of Flash movie playing Shoutcast streams using the new Sound API features available in Flash Player 10. Take a look.
Over at tunamedia.co.uk, we’ve released a demo of Flash movie playing Shoutcast streams using the new Sound API features available in Flash Player 10. Take a look.
Over the weekend I was taking a look into whether Silverlight might be a better bet than the Flash player for delivering streaming audio (Shoutcast in particular) to end-users. I built an extremely simple application that points a MediaElement at a Shoutcast stream (using the same url tweaking trick oulined in this previous post) and plays it back. Once again, looking through the documentation, it becomes apparent that Microsoft are trying to steer developers towards the use of their own streaming server solution.
So bearing this in mind, is Silverlight a viable browser solution for delivering legacy streams that fall out of the bracket of their own “streaming solution”? It can play back Shoutcast streams across domains in just the same way that Flash can but suffers the same fundamental problem suffered by Flash. There is no means of informing the player that an mp3 stream delivered over http is not intended for download, so the player keeps the whole stream in memory with the expectation that the download will end at some point… with Shoutcast it never does and the player consumes memory (ultimately ALL of the memory, if left playing long enough). So, both Flash AND Silverlight end up in the same basket on this front, slowly consuming all system memory. I think that this is stupidly limiting, and an API extension to drop played data would be a pretty simple enhancement. At the cost of promoting and protecting their own server products, both Adobe and Microsoft are missing a very fat slice of consumer ears.
Here’s a verbatim copy of my reply to a question asked on the FlashBrighton mailing list about online radio stations and Flash:
Question:
Hey,
I’ve been asked to build a little widget that streams a selection of free-to-air online radio stations. I know that this is possible, but does it require a specific server setup or can I just point a netstream object at a URL?
TIA
Answer:
Currently there are 2 options (neither of them particularly satisfying):
Option 1:
Sound.play can be used on audio/mpeg content type Shoutcast/Icecast streams (i.e. standard mp3 Shoutcast). You can establish the stream URL by opening the published .pls (Winamp playlist file) in a text editor.
Shoutcast servers (DNAS) sniff the User-Agent header, and if you are going for the root of the streaming server (e.g. http://shoutcastServerLivesHere.net:8000/), then it will inspect the User-Agent. If it matches a browser type, then it will serve up a page of HTML rather than the stream itself. Unfortunately Flash in the browser does indeed send a “bad” user-agent, as this comes from the browser, not flash. You can work around this by adding a semicolon to the path (i.e. http://shoutcastServerLivesHere.net:8000/; ) which fools the DNAS server into handing you the stream. I’m not sure what the deal is with Icecast (this uses something called mountpoints, so I don’t believe that the root ever resolves to a stream).
When using Sound.play, you can (with limitations), use this across domains… however some of the API that allows inspection of the data is disabled, such as computeSpectrum.
Because the ICY protocol (used both by Shoutcast and Icecast) is infact a superset of HTTP, when you call mySound.play on a shoutcast stream, it is in all respects the same as a normal file download. However, in this case the download never ends. So, somewhat problematic is the fact that a playing Shout/Icecast stream will eventually consume all memory on the client (although I’ve heard that Flash conks at about the 1 hour mark, but I have not proved this). This means that periodically, you will have to kill the sound, drop all references to it and reload it. You can either do this while the current stream is playing (and risk maxing out the 2 connections per domain browser limit), or completely stop and restart the sound (with a short break inbetween). Whichever method you use, the 2 soundswill very rarely sync up perfectly and you’ll be left with a discontinuity in the audio that listeners will hear. Most online examples of this technique seem to do this at around the 10 minute mark (although I reckon you could go to about 1/2 hour). Using this method will never expose the optional metadata that is embedded in the stream because Flash cannot send the “Icy-MetaData” header to switch the server into sending these metadata packets. Even if it could, it would break the integrity of the MP3 stream meaning that the Sound API would not work.
Option 2:
Wowza Media Server offers a Shoutcast/Icecast to Netstream convertion. Pricey, but nice. You won’t suffer memory issues on the client using this, and it will relay the metadata embedded in the stream too. It can also repackage AAC Shoutcasts such that newer Flash players can play these streams too (no server recompression required).