Flash Streaming Review

FMS Review

Where do various files go?

When developing applications that utilize the Flash Media Server it is important to note what goes where.

On ITP's server you have a "flash" directory which maps to things that belong on the Flash Media Server. This would contain a series of folders which are your FMS "applications" and in those folders you have "asc" files which are server side actionscript.

In your normal "public_html" directory you place files that get shown in a web browser. These would be your compiled Flash (swf) and any HTML/images/javascript and so on.

AS3 files, "something.as" are files that contain client side actionscript and these are compiled into "swf" files. You can upload the .as files to the public_html but it isn't necessary to do so. On the other hand, you do need to upload the final .swf that you create out of them.

How do we write server side actionscript and why?

Last week we concentrated on AS3 and breezed over server side actionscript. We learned that we use NetConnection and NetStream to connect and stream to and from the server. We also learned that we don't need to do anything other than create a simple folder on the server side to allow this to happen.

We also looked at code for a server side file that enables video conferencing to happen. This file is an .asc file. Unfortunately, server side actionscript syntax is more like JavaScript than AS3 and takes a bit to get used to.

Expanding on our conferencing application:

Assuming you were successful in creating a SWF out of the conference.as code, let's go over the "main.asc" which we should put in our "flash" directory under a directory that we create. In this case, let's call it "conference".

Here is the main.asc file once again, with more comments and some modifications:

// Server side actionscript
// Reference here: 
// http://help.adobe.com/en_US/FlashMediaServer/3.5_SS_ASD/WS5b3ccc516d4fbf351e63e3d11a11aff5ba-7f8b.html

// Array to hold clients
videoStreams = new Array(null,null,null,null);
// Fill it up with null values

// On Start (when the application is first instantiated)
// Part of the "application" object.  We are overriding a built in method of that class, "onAppStart"
// You'll notice in the docs that their are many methods that we can override such as "onDisconnect", "onConnect" and so on:
// http://help.adobe.com/en_US/FlashMediaServer/3.5_SS_ASD/WS5b3ccc516d4fbf351e63e3d11a11afc95e-7edf.html
application.onAppStart = function()
{
	// trace is a "Global" function that is built-in.  It allows us to print to the FMS log for debugging
     trace("Starting Conference Application");
};

// On Connect: When a client connects from Flash using NetConnection
// http://help.adobe.com/en_US/FlashMediaServer/3.5_SS_ASD/WS5b3ccc516d4fbf351e63e3d11a11afc95e-7edf.html#WS5b3ccc516d4fbf351e63e3d11a11afc95e-7fe1
// The "client" object for the new client is passed in (newClient)
application.onConnect = function(newClient)
{
	// At the top we declared an array, videoStreams to hold the clients.  This allows us to determine which client represents which stream
	var done = false;
	for (i = 0; i < videoStreams.length && !done; i++)
	{
		if (videoStreams[i] == null)
		{
			// Client object
			// creating a property called clientName
			newClient.clientName = i;
			trace(newClient.clientName);
			videoStreams[i] = newClient;
			trace("New Client: " + i);
			done = true;
		}
	}
		
	if (!done)
	{
		// If all of the positions are in use
		// Don't let a new person connect
		application.rejectConnection(newClient);
		trace("sorry, full");
	}

	// Accept the connection
	application.acceptConnection(newClient); 

	// Here is where things get a bit tricky..  The clients can call functions on the server.  In this case, in our AS3 code we are doing this:
	/*
	// Listener for connection
	private function connectionHandler (e:NetStatusEvent):void 
	{ 
		// If we are connected
		 if (e.info.code == "NetConnection.Connect.Success") 
		 {
				// Create a responder to call a method on server and ask what stream we are
			   responder = new Responder(doEverything);
			   
			   // Call the streamSelect function on server with our new responder
			   nc.call ("streamSelect",responder); 
		 } 
	}
	*/
	// The above is on the client side and you'll notice the "nc.call("streamSelect", responder)".  This calls a server side function that is part of the "client" object on the server.  The response from the server will call a client side function, "responder".  Below is that server side function, part of the "client" object.  What it does is tells the client what it should call it's broadcasting netstream, "one", "two", "three", "four" depending on which position in the array it has.

	// Function that get's called by the client to determine where to go
	newClient.streamSelect = function() 
	{ 
		trace("Stream " + newClient.clientName + " used"); 

		//Send the property to Client object 
		return newClient.clientName; 
	};
};

// This is the end of the code from week5.  One issue with this code is that after 4 people have connected, it doesn't allow new connections, even if they have disconnected.  
// To rectify this, we have to use a application.onDisconnect():
//http://help.adobe.com/en_US/FlashMediaServer/3.5_SS_ASD/WS5b3ccc516d4fbf351e63e3d11a11afc95e-7edf.html#WS5b3ccc516d4fbf351e63e3d11a11afc95e-7fde
// Just like the application.onConnect we are passed in a "client" object.  Since we already assigned a "clientName" property, we can modify the array to free up a spot.
application.onDisconnect = function(oldClient)
{
	for (i = 0; i < videoStreams.length; i++)
	{
		if (videoStreams[i] != null)
		{
			if (videoStreams[i].clientName == oldClient.clientName)
			{
				videoStreams[i] = null;
			}
		}
	}
}
Updated conference.as
Try it

How about if we only let one person stream at a time?

main.asc
conference.as
Try it