Requirements
Prerequisite knowledge
Successful completion of Part 3 in this tutorial series is recommended. Previous experience deploying streaming video online is helpful.
User level
Beginning
Required products
Flash Media Server (Download trial)
Sample files
This article is the fourth in our series of beginning-level tutorials about Adobe Flash Media Server 4.5. This particular tutorial gets you started using FMS 4.5 to stream audio into a Strobe Media Player available to you through the Open Source Media Framework (OSMF).
Here are all of the articles in the series (links will become active as the articles are published):
Part 7: Streaming to iOS devices (to come)
Part 8: Streaming to Android devices (to come)
Part 9: Security features (to come)
So far in this series, we have dealt only with streaming video files. Still, there will be times when you want to stream audio through Flash Media Server. The first thing you need to know about audio and Flash Media Server 4.5 is that it is a completely different game from working with local audio using ActionScript 3. In ActionScript, a number of Sound classes are used to manage audio. When it comes to FMS 4.5, those classes play a minor role. The reason is simple: the file is being added to a stream and, as such, the attachAudio() method from ActionScript 3 is, for all intents and purposes, rendered useless due to a completely different delivery method.
Flash Media Server 4.5 can stream several different audio formats: SPEEX, G.711, Nellymoser, MP3, and AAC. There are a few "flavors" of the AAC format and Flash supports AAC+, HE-AAC, AAC v1, and AAC v2. That's the good news. The bad news is that AAC content can only be played through Adobe Flash Player 9.0.115.0 or later. This makes sense because this was the Flash Player update released in conjunction with the introduction of H.264 playback in late 2007. Still, the most common audio formats you will encounter are MP3 and AAC. For a great overview of the AAC format, check out this blog post by Fabio Sonnati: How AAC works.
Now that you know what you can use, we'll now show you how to actually use it.
 
Streaming an audio file
In this example we are going to show you how to play an audio file through Flash Media Server 4.5. It's really not that much different from streaming video.
To get started:
    Download the files for this tutorial and unzip the download.
  1. Create an application for the audio files. Though we covered this step in Part 2: Streaming on-demand video, it is important that you understand that the creation of the folder structure for a streaming audio application is exactly the same as that for a video application. The application is the name of the folder. Inside that folder is a folder named streams and inside that is a folder named _definst_ .The media to be streamed—in this case, an audio file—is placed in the _definst_ folder.
  2. Create a new folder named AudioStreams at C:\Program Files\Adobe\Flash Media Server 4.5\applications. Open the AudioStreams folder and add a new folder named streams. Inside this folder place a new folder named _definst_ and copy the four audio files in the Exercise to the _definst_ folder.
Note: The authors would like the thank William Hanna, Dean of the School of Media Studies and Information Technology at the Humber Institute of Advanced Learning and Technology in Toronto, Canada, for permission to use the AndreHprofile.mp3 clip, which was produced by the students in the Radio Broadcast program at Humber.
  1. Open the SimpleAudio.FLA file. When it opens, you will see that we have added the layers to the Timeline (see Figure 1). The layers contain the interface, a text box to display what is going on between the server and the SWF file, and an Actions layer for the code.
Figure 1. The interface contains a text box that will tell you what is going on.
  1. Click in Frame 1 of the ActionScript layer and open the Actions panel.
  2. When the panel opens, click in Line 1 of the Script pane and enter the following code:
import flash.net.NetConnection; import flash.net.NetStream; import flash.events.NetStatusEvent; var nc:NetConnection = new NetConnection(); var ns:NetStream;
As you did with on-demand video, before getting the audio to play, you need to create a NetConnection object and give the object a name: in this case,ns. With the housekeeping out of the way, you can turn your attention to connecting to the server and listening in on the messages between the server and Flash.
Note: For the past couple versions of Adobe Flash Professional, when you assigned a class to a variable, the import statement for that class was added to the top of the Script pane. This feature is nice because it is a common best practice to import the classes. The problem is, it is somewhat inconsistent in Flash. Sometimes the statements are added and sometimes they aren't. Recognizing this, it has become standard within the Flash community not to rely on this feature and to add the required import statements manually instead.
In this instance, you are going to use a common handler—netStatusHandler
—to listen to both the connection and the stream for four specific messages: The connection is made, the connection is rejected, the stream has started to play, or the stream is not found. Here's how:
  1. Press Enter twice and add the following code:
nc.connect("rtmp://localhost/AudioStreams"); nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler); function netStatusHandler(e:NetStatusEvent):void { traceField.text = e.info.code + "\n" + traceField.text; trace(e.info.code); switch(e.info.code){ case "NetConnection.Connect.Success": beginStream(); break; case "NetConnection.Connect.Rejected": break; case "NetStream.Play.Start": break; case "NetStream.Play.StreamNotFound": trace("Can't find the stream."); break; } }
We'll briefly step through this function for you. Its purpose is to catch and react to four specific NetStatusEvent events: connection made, connection rejected, the stream has started to play, and the stream is not found. As these events occur, the actual message will appear in the text box in layer 2 when you test the project, detailing an activity log for the audio stream.
Obviously, if there is a connection— NetConnection.Connect.Success —the audio file should start to play (through invocation of the beginStream() function, in this example). If there isn't a connection— NetConnection.Connect.Rejected —check that your copy of FMS 4.5 is actually running and make sure the spelling of the application in the code matches the name of the application's folder.
The next check is to ensure the stream is playing. NetStream.Play.Start is the message that confirms this. The final message— NetStream.Play.StreamNotFound —is self-explanatory and is usually resolved by making sure you have the correct folder structure and path to the audio file. Now that the tests are in place, you can turn your attention to the audio file.
  1. Press Enter twice and add the code that gets the audio to play:
/* this function will handle creation of the NetStream object. we invoke NetStream.play() to begin streaming. */ function beginStream():void { ns = new NetStream(nc); ns.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler); ns.play("mp3:AndreHprofile"); }
As you can see, the "magic" happens with the netStatusHandler() function. The first step is to add the NetConnection to the stream and then listen for the stream-level messages between the server and the SWF application. If everything is good to go, theplay() method of the NetStream class will look for an MP3 file named AndreHProfile and add it to the stream.
  1. Save and test the movie.
 
Controlling an audio stream
In the previous exercise, we showed you how to create an application that streams an audio file and how to get it playing. If we were to stop there, you would be well within your rights to start complaining. It is not exactly a best practice to play an audio file with no way of letting the user turn the darn thing off. In this exercise, we are not only going to enable the user to stop playback, but also show you how to display the time and how to pause a track.
To get started:
  1. Open the ControlAudio.fla file in your Exercise folder. When it opens (see Figure 2), you will see we have added the layers and, in the Controls layer, we have added a couple of buttons from the Flash. If you open the Properties panel, you will also note that we have given each button an instance name.
  1. Click in Frame 1 of the Actions layer and open the Actions panel. When it opens, enter the following into the Script pane:
import flash.net.NetConnection; import flash.net.NetStream; import flash.events.NetStatusEvent; import flash.events.Event; import flash.events.MouseEvent; var isPlaying:Boolean = false; var nc: NetConnection = new NetConnection(); var ns:NetStream; addEventListener(Event.ENTER_FRAME, monitorTime); nc.connect("rtmp://localhost/AudioStream"); nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler); function netStatusHandler(e:NetStatusEvent):void { traceField.text = e.info.code + "\n" + traceField.text; trace(e.info.code); switch(e.info.code){ case "NetConnection.Connect.Success": beginStream(); break; case "NetConnection.Connect.Rejected": break; case "NetStream.Play.Start": break; case "NetStream.Play.StreamNotFound": trace("Can't find the stream"); break; } }
There isn't much difference between this code and the code from the previous project. Still, there are some important additions. The first is the isPlaying variable. We are going to be tying a couple of functions to the condition of whether the audio is playing or not. We also want to show the user how much time has elapsed while the audio track is playing. To do this, we create a listener that will keep an eye on the time.
  1. To get the stream moving, press Enter twice and enter the following code:
function beginStream():void { ns = new NetStream(nc); ns.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler); ns.play("mp3:AndreHprofile"); ns.pause(); timeField.text = "ready"; }
At first glance it might strike you as a bit odd that as soon as we turn on the stream, we pause it. We have to, because a stream starts playing immediately and, in this case, the radio report will come blaring out of the user's speakers. This is not what we want. We want to give the user the opportunity to turn it on or off.
  1. To start that process, press Enter twice and enter the following code, which assigns functions to the buttons on the stage in the Control layer:
playBtn.addEventListener(MouseEvent.CLICK, playStream); pauseBtn.addEventListener(MouseEvent.CLICK, pauseStream); stopBtn.addEventListener(MouseEvent.CLICK, stopStream);
  1. Now that you have told Flash what each button is supposed to do, it's time to write the code for those three functions starting with playStream() . Enter the following:
function playStream(e:MouseEvent):void { if(!isPlaying){ ns.resume(); isPlaying = true; } }
The logic for the Play button is really quite efficient. The first line checks to see if the stream is not playing— (!isPlaying) —when the button is clicked.There are only three possible states for the audio not to be playing: the beginNetStream() function has paused the stream, the user has clicked the Pause button, or the user has clicked the Stop button. In any case, the stream is resumed—the audio track starts playing—and the isPlaying variable's Boolean value is set to true .
  1. Press Enter twice and enter the functions for the Pause and Stop buttons:
function pauseStream(e:MouseEvent):void { if(isPlaying){ isPlaying = false; ns.pause(); } } function stopStream(e:MouseEvent):void { isPlaying = false; ns.close(); timeField.text = "stopped"; }
There's not much new here, other than the text in the timeField being changed to "stopped"
when the Stop button is clicked. The key point, if you are new to working with streaming media, is that you are not really starting, stopping, or pausing the audio track itself, as you would through the use of the Sound object. You are informing the server either to no longer send audio data along the stream, or to resume the transmission of audio data along the stream.
  1. The last code block to enter is the time display in the Output layer. Press Enter twice and type:
function monitorTime(e:Event):void { if(isPlaying){ timeField.text = Math.round(ns.time) + " seconds..."; } }
There's not much new here, other than the text in the timeField being changed to "stopped"
when the Stop button is clicked. The key point, if you are new to working with streaming media, is that you are not really starting, stopping, or pausing the audio track itself, as you would through the use of the Sound object. You are informing the server either to no longer send audio data along the stream, or to resume the transmission of audio data along the stream.
  1. The last code block to enter is the time display in the Output layer. Press Enter twice and type:
 
Playing and controlling multiple audio files
So far in this exercise you have been playing with a single file. Now that you know how to do that, we'll show you how let a user choose among multiple audio files.
Phil Darling, the son-in-law of one of the authors, is the bassist and founder of a rather hot "indie" band in Toronto named The TinBangs. The group has just released an EP that contains three songs, and the plan is to stream them out to let their fans hear the new work.
Note: The authors would like to thank Phil Darling and the other members of the band for letting us use these files for this example.
This means the user needs to be given the opportunity to pick from among three songs. For ths purpose, we have chosen to go with the List component that is packaged with Flash Professional CS 5.5.
Note: There are other ways to approach this project, ranging from using the ComboBox component to using an XML document as the DataProvider. We have chosen to go with the List component due to space constraints.
To get started:
  1. Open the SelectAudio.fla file located in your Exercise folder.
  2. When the file opens, select the first frame of the actions layer and open the Actions panel.
  3. Click in Line 1 of the Script panel and enter the following code to import the following seven classes:
import flash.net.NetConnection; import flash.net.NetStream; import flash.events.NetStatusEvent; import flash.events.Event; import flash.events.MouseEvent; import fl.data.DataProvider; import fl.controls.List
To use the List component, you need to use the DataProvider class to feed the data into the List component and the List class from the controls package to get the component working.
  1. With the classes established, you can now create the play list. Click in Line 6 of the Script pane and enter:
var playList:Array = new Array(); playList.push({label:"White Lies (Timekiller)",data:"WhiteLies(Timekiller)"}); playList.push({label:"Young Lions", data:"YoungLions"}); playList.push({label:"Your Sky Is Falling", data:"YourSkyIsFalling"}); audioList.dataProvider = new DataProvider(playList); audioList.addEventListener(Event.CHANGE, switchStream);
We start by creating an array and giving it the name playList. Each item in the play list is going to appear in the List component. This component requires two pieces of information. The first is label , which is the text that will appear in the component when the application is running. The second is the data to use, which in this case is the name of the audio file. The List component is then told that playList will provide the data for the component. We are also going to listen for the user to make a selection in the List (Event.CHANGE) and, when this is detected, to execute the switchStream() function.
  1. To write the switchStream() function, click in line 44 of the Script pane and type:
function switchStream(e:Event):void { ns.play("mp3:" + e.target.selectedItem.data); if(!isPlaying){ ns.pause(); } }
The major change here is in the play() method. Instead of entering the name, you grab the data portion of the list item and use it instead.
  1. Save and test the file. As you can see (in Figure 3) and hear, you have just created an application that lets you choose from three files. The neat thing about this is that it is no great stretch to go from three songs to 30 songs, or even more.
The next part in this tutorial series walks you through the process of streaming HTTP Dynamic Streaming (HDS) content and also shows you how to use the multiple bitrate feature of Flash Media Server 4.5. We'll see you there.
 
Where to go from here
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License. Permissions beyond the scope of this license, pertaining to the examples of code included within this work are available at Adobe.