Requirements     

               
Prerequisite knowledge
Prior knowledge of working with audio in Flash, using ActionScript, Adobe Flash Builder and/or Adobe Flash Professional is required. This article describes more advanced strategies to control and play streaming audio in Flash Player.
Required products
Flash Builder (Download trial)
Sample files
User level
Intermediate
   
Streaming audio servers, such as Icecast and SHOUTcast are popular examples of online hosting technologies used for Internet radio. Many desktop and mobile applications can play these audio streams, including WinAmp, VLC, and many others. As an alternative to requiring listeners to install applications, Internet radio streams can also be played in the browser using either the HTML5 audio tag or Flash Player.
 
In Flash, you can use the Sound object to play Icecast streams. All you need to accomplish this is to specify the URL of the sound source. However, the Sound object was not designed for streaming audio. Its behavior is to buffer all sound data. This results in increased memory usage, which is clearly not desirable for Internet radio applications.
 
Data Generation Mode (available in Flash Player 10.1 or higher) enables dynamic media content creation using ActionScript. With Data Generation Mode, a wide range of media formats can be consumed by Flash. One example is the Adobe HTTP Dynamic Streaming (HDS), which makes extensive use of Data Generation Mode. In this article, you'll learn how to use Data Generation Mode for Icecast audio streaming.
 

 
Understanding Icecast protocol

Icecast delivers streaming audio over HTTP protocol. In order to stream audio, an application requests the URL of the audio stream from an Icecast server. For example, the URL to an audio stream looks similar to like this:
 
http://streaming.example.com/radio
The information shown below illustrates a typical response to this request:
 
HTTP/1.0 200 OK Content-Type: audio/mpeg icy-br:128 ice-audio-info: bitrate=128;samplerate=44100;channels=2 icy-br:128 icy-description: Radio station description. icy-genre:genre icy-name:Name icy-pub:1 icy-url:http://streaming.example.com Server: Icecast 2.3.2-kh30-advert-14 Cache-Control: no-cache Expires: Mon, 26 Jul 1997 05:00:00 GMT Pragma: no-cache
The response is followed by the delivery of audio data. During the stream, there is a persistent connection between application and Icecast server, and the server continuously pushes audio data to the client.
 
Icecast supports several audio formats, including MP3 (MPEG-1 Layer III), Ogg Vorbis, and AAC (Advanced Audio Coding). Due to its popularity, this article and the accompanying sample project code focus on streaming audio with the MP3 file format.
 
For more information, please refer to the Icecast website.
 

 
Streaming audio files with Flash

There are two strategies you can use to play audio files in Flash Player downloaded over HTTP. When working with the MP3 file format, you can use the Sound object. When you are streaming AAC, you can use the progressive download capabilities in Flash.
 
 
Using Sound object
The Sound object in ActionScript 3 can be used to play MP3 audio data. It allows you load and play a sound file specified by an URL. (In Flash Player 11, you can also specify PCM data or compressed MP3 data as a ByteArray to Sound object.) You can write an Icecast player using the Sound object with just a few lines of code:
 
var sound:Sound = new Sound(); sound.load(new URLRequest(“http://media.example.com/stream.mp3”)); sound.play();
However, streaming audio is not the intended use of Sound object. The ActionScript documentation describes it this way: The Sound class lets you create a Sound object, load and play an external MP3 file into that object, close the sound stream, and access data about the sound, such as information about the number of bytes in the stream and ID3 metadata.
 
The Sound object stores all sound data received in memory. This means that an MP3 stream at 128k bits-per-second (bps) results in storing about 1 MByte of data per minute. This behavior will eventually result in memory overrun (especially when using memory constrained devices). Another drawback of using the Sound object is that it only supports MP3 or PCM formats; AAC is not supported.
 
Which leads to the next option: progressive download.
 
 
Using progressive download
Progressive download is the most popular and easiest way to play a video file using Flash. The video file is hosted on a web server and you simply specify the URL of the file. Flash Player starts downloading the file, and as soon as sufficient data is received, playback commences. The download process happens as quickly as possible, but the received data is cached on disk.
 
Progressive playback supports Flash Video (FLV and F4V file formats). Progressive playback also supports a wide range of audio and video compression formats, including H.264, VP6, MP3, and AAC. Please note that unlike FLV, MP4 is not a streaming format, so the user may be required to download the entire file before starting playback. The following code sample demonstrates playing an M4A file (AAC audio data in an MP4 container) hosted on a web server:
 
var netConnection:NetConnection = new NetConnection(); netConnection.connect(null); var netStream:NetStream = new NetStream(netConnection); netStream.play(“http://media.example.com/sample.m4a”);
You cannot use NetStream to play an audio-only MP3 file (however, MP3 carried in FLV container works), or AAC carried in other than M4A container.
 

 
Using Data Generation Mode

As described in the previous section, the NetStream object that works with progressive download provides several advantages, such as streaming capabilities and support for a wide range of codecs. However, it is limited to streaming FLV and F4V containers.
 
Flash Player 10.1 introduced Data Generation Mode, which allows you to specify media data as a ByteArray. This means that you can now set it up to support a wide variety of media containers to stream MP3, AAC, VP6 and H.264 codecs.
 
 
Flash Video (FLV) format
Data Generation Mode requires the use of FLV container. If your media data is in a different container, it first must be converted to FLV. The FLV file format is specifically designed to stream media and it is capable of representing a single audio and/or video stream (see Figure 1).
 
The FLV data stream starts with a nine byte long header. This header includes the characters "FLV", a version number (which is usually 1), and indicates whether the stream contains audio and/or video data. The rest of the FLV stream consists of alternating media data (tags) and back-pointers (the size of the previous tag). Each audio or video tag contains the tag header and the media data (see Figure 2).
 
The tag header is 11 bytes long. It includes the tag type, data size, timestamp, and stream ID. The tag type must be set to 8 for audio streaming. The data size is the entire size of the tag (including header). Timestamp is the message time in milliseconds and the stream ID must be set to zero. The tag header is followed by the payload. For audio tags, there is an additional one byte (two bytes for AAC) of header data, as shown in Figure 3.
 
The first four bits in the tag header indicate the compression format, and use 2 for MP3 and 10 for AAC. The sampling rate is indicated at the next two bits, which is a binary 00 indicating 5.5 kHz, a binary 01 indicating 11 kHz, a binary 10 indicating 22 kHz or a binary 11 indicating 44 kHz. Since AAC supports a wider range of sampling rates, you must always set AAC streams to 44 kHz. The last two bits indicate whether 8 or 16 bit-depth is used, which describes whether the sound being streamed is mono or stereo. When streaming AAC, there is an additional header byte, which indicates whether the data is an audio specification or compressed data. Audio specification is usually two bytes long and includes the file's compression method, sampling and channel information. The audio header is followed by the compressed data.
 
 
MPEG format
The most popular format for Icecast by far is MP3 (MPEG-1 Layer III). The audio data is carried in frames and each frame contains a header and associated data. The header is four bytes long and includes a sync word, an MPEG version, layer information, sampling frequency, number of channel, and more. For more information, please see this description of the MPEG Audio Frame Header. For MPEG-1 Layer III, each frame is composed of 1152 samples. If you use the 44.1 kHz sampling rate, one frame contains about 26 ms of audio data. The size of the compressed frame can be calculated based on the bitrate and sampling rate. After receiving data from the server, you must first find the MPEG header, so that the application can start decoding and playing the streaming audio right away.
 
In an MP3 file, the ID3v1 tag is used to describe meta information about the file. The size of ID3v1 is 128 bytes and it is located at the end of the file. In Icecast, this information can be embedded into the stream, but most of the time it is missing and is instead obtained using a separate HTTP request to the server.
 
 
Putting the pieces of a streaming audio player together
There are three components of a simple Icecast player. First, you'll use the UrlStream Progress event to receive media data. It is important to note that you cannot assume that the received data starts at an MPEG frame header. You'll need to locate the beginning of an MPEG header first. You can accomplish this by looking for the sync word and then parsing a potential header.
 
Since the sync word may appear in compressed data as well, I have used the following algorithm for synchronization: When the sync word is found, the potential header is checked for illegal values. Then, I calculate the frame length given the sampling rate and bitrate. I use this value to skip the current frame and look for the sync word in the next frame. If the second sync word is found, then it is likely that the player has achieved synchronization and decoding begins. If synchronization becomes lost at any time, the above algorithm repeats to achieve re-synchronization.
 
You should also not assume that the received data ends with full MPEG frame, so buffering is needed. Secondly, you'll need to decode the MPEG header. Since it is unlikely that the stream will change properties (such as sampling rate) it may be sufficient to decode a single MPEG header, depending on the content you are streaming. Finally, based on the information in MPEG header, you create FLV audio tags and pass the resulting FLV stream to the NetStream object.
 

 
Advanced tips for streaming audio files with Flash

When the URL of an audio player is different than URL of the audio source, the web server serving the audio data must have a cross-domain policy file. For more information, read the Developer Center article titled Cross-domain policy file usage recommendations for Flash Player. Below is an unrestrictive sample policy file that provides access from any host:
 
<cross-domain-policy xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance xsi:noNamespaceSchemaLocation="http://www.adobe.com/xml/schemas/PolicyFile.xsd"> <allow-access-from domain="*"/> </cross-domain-policy>
When using URLStream in Flash Player, you will not have access to HTTP response headers. You can either use an AIR application to access HTTP headers or implement your own URL loader on top of the Socket class. In practice, however, you should not rely on HTTP headers. Most of the information is available from the stream itself (including the bit rate, sampling rate, number of channels, and other data).
 
Icecast supports user authentication, which can be implemented using the URLRequestDefaults class.
 
Since you have direct access to sound data, you can develop some pretty cool features. For example, you can display the audio wave format and the resulting spectrogram. You can also add sound recording capability by saving the sound data in MP3 format. And finally, you can implement some buffering and provide rewind capabilities.
 
In addition to the MP3 format, Icecast supports AAC and Ogg Vorbis formats as well. AAC provides better sound quality than the older MP3 format. To deliver streaming audio, AAC data is most likely carried in either the Audio Data Interchange Format (ADIF) or via Audio Data Transport Stream (ADTS). You can parse these containers and create FLV audio tags in order to use the audio file with Data Generation Mode. Flash Player does not natively supports Vorbis audio. However, it is possible to play Ogg/Vorbis media using Data Generation Mode. You can use ActionScript to parse Ogg containers and decode Vorbis audio. To learn more details, see this description of a Flash Vorbis player.
 

 
Overview of a sample Icecast application

To get started creating your own streaming audio players, review the sample Icecast application I developed. It utilizes a simple ActionScript 3 library to play MP3 Icecast audio. If you haven't already, be sure to download the sample files linked at the beginning of this article so that you can review its structure and code.
 
The sample application contains the following files:
 
IcecastPlayer.as – Main entry point. It manages loading, synchronization, and playback.
 
Flv.as – Creates the FLV header and audio tag header.
 
MpegHeader.as – Parses the MPEG header.
 
IcecastPlayerEvent.as – Defines playback status and error events.
 
When using Flash Builder, please follow these steps to create your own Icecast player:
 
  1. Create a new Flex Library Project and name it icecastPlayer.
  2. Replace the icecastPlayer/src folder located in the provided sample files.
  3. Notice that the icecastPlayer/bin/icecastPlayer.swc is generated automatically.
  4. Create a new ActionScript Project and name it icecastPlayerApp.
  5. In the properties of the icecastPlayerApp, select ActionScript Build Path pane. Click the Add SWC… button and specify the icecastPlayer.swc generated in Step 3.
  6. Add the following source code to icecastPlayerApp.as file:
package { import com.icecastplayer.IcecastPlayer; import flash.net.URLRequest; import flash.display.Sprite; public class icecastPlayerApp extends Sprite { public function icecastPlayerApp() { var player:IcecastPlayer = new IcecastPlayer(new URLRequest("http://media.example.com/stream.mp3")); player.play(); } } }
  1. Specify the URL of an Icecast stream. Visit the Icecast Directory to obtain sample streams. Please download any M3U playlist to your computer, open it with a text editor and select a URL for this sample project.
  2. Run the application to hear the audio stream.
I have tested the library with several Icecast servers, using bitrates ranging between 48 kbps to 192 kbps and sample rates of 44 kHz and 48 kHz. All the sources I tested were using MPEG-1 Layer III audio.
 

 
Where to go from here

In this article, I described how to use the Data Generation Mode in Flash Player to play streaming audio with Icecast. Data Generation Mode was introduced in Flash Player 10.1, so this strategy does require users to install Flash Player 10.1 or higher. Data Generation Mode is a very powerful and advanced API, enabling you to implement features that are not supported by Flash Player. You can also create streaming audio players for Flash Player that previously required additional server side components.
 
To learn more about working with Icecast, see the following online resources:
 

More Like This