My favorites | Sign in
Project Logo
                
Code license: Mozilla Public License 1.1
Labels: Red5, 3D, Sandy, Flash
Feeds:

Get the latest updates here

The api is here.

There are now two engines. I recommend 'OmniCron' for larger scale projects for it's network efficiency over the 'Engine', and the outright smoothness in the animations. I recommend the Engine as a quick and easy entry point. The Omnicron starts where the Engine finishes.

Multi User Interface For Red5 And Sandy Flash

Red5

The coolest thing in streaming technologies that I know about is the Red5 project. The entire power of the server is beyond the scope of this writing. A little different than most available media servers…. Well, that is an understatement. I really don’t have a deep knowledge for java, but Red5 offers an enormous API to create, literally, any application you could think of. My use has been primarily to stream live media into firefox. The server can handle clients at different “scopes” and track attributes which you define. It handles remote shared objects, and what appears to me as the coolest thing in flash, the Sandy Flash 3d engine. Now, for sure, Im a total n00b in both actionscript and java, so often I do things the first way that worked, rather than the conventional ways that seasoned programmers may operate. It may also help to know that I’m self taught and learned most concepts in c++, writing directshow source filters for fun, and consequently love object oriented programming.

Sandy Flash

Wow, this is awesome stuff! Having a 3 dimensional scene and moving objects around in space is striking to the eye on a web page. What if I could create a 3 dimensional space to watch flash movies and join up with friends online? That’s what interested me in compiling some of the tutorials. First it was the Flex integration tutorial, and then Simple Move. Ok, so where to go from here? There are some basics about the Net Connection Class that need to be examined in regards to connecting to the red5 server.

//The basic connection with some added parameters.

nc=new NetConnection();
nc.addEventListener( NetStatusEvent.NET_STATUS, netStatusHandler );
nc.addEventListener(AsyncErrorEvent.ASYNC_ERROR,netStatusAsynErr);
nc.objectEncoding = flash.net.ObjectEncoding.AMF3;
nc.connect(address,name,password,type);


//Basic handling goes as follows.
private function netStatusHandler(event:NetStatusEvent):void
{
    switch( event.info.code ) 
    {
               case "NetConnection.Connect.Success":
	 //Start your engine    
	break;
                    
               case "NetConnection.Connect.Closed":
               // Clean up
	break;
                    
               case "NetConnection.Connect.Failed":
               // Clean up
	break;                    
    }
} 

Put them together

So since I myself am learning the sandy library, and really built the whole engine off of the simple move tutorial, I’ll use it to explain what the heck is going on under the hood. Please, if you haven’t tried the Jump Start tutorial which houses ‘simple move’, look at it now. I’m going to take pieces of it and throw it at you. On the server side, I’ve basically provided a few handy call backs. Red5 calls you with names as people join and leave. I’ve added public interface to send asynchronous messages to both all clients or a particular client.

http://www.petitpub.com/labs/media/flash/sandy3/jump-start.shtml

The idea is to share the world3d between multiple connected people, display them in the world as some Sandy Flash object, and give them freedom to move about the world independently in real time as the Sandy Flash world allows them to. I use red5 to store two vectors, one for position , and one for rotation. I allow the server to be queried for these positions and then move the Sandy Objects to the coordinates. The red5sandy engine handles all the dirty work, and the default behavior is multi-user 3d real-time action. Dig in...

The engine connects to the server, approves the name, notifies ”new user” to the other clients, then comes back to execute the first Sandy code.

    world = World3D.getInstance();
    world.container = this;
    world.root = createScene();
    world.camera = new Camera3D( 200, 200 );
    world.camera.z = -200;
    world.root.addChild( world.camera );

Here the engine issues the "world ready" event. In the engine, I have stripped out the createScene(); function from the Simple move tutorial and now it doesn’t create a scene, but still creates and returns the ‘group’. Catch the world ready event, and begin adding children to the world.root. Add some spheres or something truly immaculate! Here is the beauty of the red5 sandy engine... You can connect to the same game in different .swf files, each with its own roll in the mutual world, such as pilot and gunner, aboard the same vessel, or opponents on the ground being attacked from the others in the air. Onward...

I have a unique name registered on the server, I have added some spheres or other shapes to explore with my friends after the World ready event. And now the World Events really start flying! First comes the list of connected clients. A user_add event is issued with a new unique name for each one. I make a box and give it that name so the engine will move it according to the new clients attributes. It may be handy to know that I made so if you set the new object visible=false; the engine will make it visible after the first call for its position. This is a crude way to avoid objects jumping from world origin to some actual start position as new clients join.

public function newPlayer(event:WorldEvent):void
   {
    var box:Box = new Box( event.uName, 30, 30, 30, "tri", 3 );
    var lineAttr:LineAttributes = new LineAttributes( 0.5, 0x2991BB, 0.4 )
    var materialAttr:MaterialAttributes = new MaterialAttributes( lineAttr );
    var skin:Appearance = new Appearance(
                    new ColorMaterial( 0xE0FC9C, 1, materialAttr ) );
    box.appearance = skin;
    red5.world.root.addChild( box );
   }



The engine also tells me when to update my attributes on the server with an event ”move_now”. For me the most fun is a first person perspective, for that I would update my position with my camera coordinates. Other clients see my camera’s position represented as an object.

This example below uses a box as my player piece as in third person perspective.

var pos:Array=new Array(6);
            pos[0]=box.x;
            pos[1]=box.y;
            pos[2]=box.z;
            pos[3]=box.rotateX;
            pos[4]=box.rotateY;
            pos[5]=box.rotateZ;
            red5.red5SetPostion(pos);

Asynchronous messages

So far this is all fine and dandy, but the real fun comes from individual interaction with your associates. Lets send messages and make things happen. Im going to invent a messaging system. Two methods to talk. Long and short messages. The short message is a string array(4); Must be 4 or the server will disconnect you. More is ok, not less. The long message is 9 parameters. If the first parameter is your own unique name, the message is broadcast to all clients. Other wise it is delivered to the client with the unique name matching parameter 1. If you send less than 9 parameters red5 will disconnect you, but sending “” for parameters is sufficient. No nulls!

Lets use longMessage() to shoot a torpedo at the other clients, and add our forward velocity to the mix to add some realism to the scene. This torpedo will not require server updates for position after creation. Refer to the VTorp class in the red5world package. It adds itself to the world at the vectors you feed it, animates itself with a timer, and removes itself after a certain “life” timer expires. The format of the message is arbitrary. I have basically set up 1 for owner/target, 6 for vectoring, 1 for type, and 1 for some value. You can do any thing you want here, and even expand the parameters server side.

Following the rules I set up server side, if my unique name is parameter 1, the message will be sent to all clients.

var ob:Array=new Array(“myname”,myX,myY,myZ,myRx,myRy,myRz,”torpedo”,mySpeed);
red5.red5LongMessage(ob);

And for the client about to be blown up…we need to catch the event that the Red5 interface issues.

red5.addEventListener(WorldEvent.MESS_LONG, longMessage);

public function longMessage(event:WorldEvent):void
 switch(event.longMess[7])
     {    
     case "torpedo":
       var wu:VTorp = new VTorp(event.longMess[0]+"torp", vw.world.root,
        Number(event.longMess[1]),
        Number(event.longMess[2]),
        Number(event.longMess[3]),
        Number(event.longMess[4]),
        Number(event.longMess[5]),
        Number(event.longMess[6]),
        Number(event.longMess[8]));
     break;    
     }

I generate a unique name for the new object. This particular object animates itself without server calls, and all copies of this object are uniform across the clients, so they all experience the same effect, from the message.

Notice that red5 passes strings in this engine, and you need to make numbers. The engine does convert numbers to strings automatically for you.

Coming soon, Setting Up Red5

Although why wait for me? There is a large number of tutorials explaining how to set up and deploy the red5 server. I have provided a compiled application with defaults to work with the sandy engine defaults, and added some of the most frequently asked questions, such as being notified when a client connects, and how to get a list of broadcast stream names.

var red5:Engine=new Engine(“andy”);
             	red5.red5Connect();

This will result in attempting to connect the localhost/engine application with the password “changeme”.

To connect to another server, call something like this.

vw=new Engine(unqName);
            	vw.cam3dWidth=800;
            	vw.cam3dHeight=400;
            	vw.debug=true;
            	vw.red5Address(“rtmp://badassflash.org/flashslasher”,”1(secret)password”);
	vw.red5Connect();

And finally, add our red5 world to the stage!

spriteContainer.addChild(vw);

To end the server session, call

vw.red5Close();

I prefer using eclipse and running it as a java application in the eclipse environment locally while developing, and luckily, having the funds presently to host a full blown centos install to invite others to enjoy, I can safely share the worlds. I will note that the requirements of the engine are far less than hosting video streams, and I invite others to experiment. There is an adjustable ticker that can also be used to reduce bandwidth. Another advanced technique modern games use is to interpolate positions and get velocity updates as well, but I have only showed you the threshold of the potential available in combining red5 and Sandyflash.

Andy Shaules

Red5 and Sandy advocate

Get the latest updates here









Hosted by Google Code