sábado, 18 de diciembre de 2010

Install Blackberry PlayBook Simulator in Ubuntu 10.10

Today we are going to install the Blackberry Playbook Simulator, so you can create and test applications for this awesome device before running on the real device. This device is awesome, the specifications are very impressive, check all in the blackberry - playbook web page http://us.blackberry.com/playbook-tablet/, and like blackberry always say this device is Enterprise Ready :D.

The good news with the last update of the Blackberry Playbook site is the linux release of both products: the simulator and the sdk (i have been waiting for this!!!). So let's install the Blackberry Playbook Simulator in Ubuntu 10.10.

Requirements:

  • Blackberry Playbook Simulator.
  • VMware Player 3.1.3. If you have problems installing VMware Player in Ubuntu 10.10 check this.
The machine that i use for this installation has Ubuntu 10.10 - 64bits installed. 

The first we need is to install the Simulator, open the terminal change the directory where you download your installer and run the following command:
chmod +x BlackBerryPlayBookSimulator-Installer-Linux.bin  
This command will give execute permissions to our installer. Now execute the installer:
./BlackBerryPlayBookSimulator-Installer-Linux.bin  

 Now you get the installer interface:


Click next and read the License Agreement, click in the I accept radio button and then click next, the next screen is very important:


Select in which folder do you want to install the Simulator, well the only thing you will get is the image for the simulator, click next and review the Pre-Installation Summary.


Click install, once the installer finish click the Done button, now go to folder where you just install the Simulator, in this folder find the BlackBerryPlayBookSimulator.iso, now we start our VMware Player.



Now create a new virtual machine click the Create a New Virtual  Machine button this will show the new Virtual Machine Wizard,   click Next and this will bring the following screen:


Select the Installer from iso and then click Browse and select the BlackBerryPlayBookSimulator.iso image, this will display an alert we fix this later. Now click Next and the following screen appear:

Take care about the Operating System and Version options both must be Other and Other then hit Next.


In this screen you have to specify the name and the location of the virtual machine then click next.


Here specify the disk size and the type of virtual disk, make sure you select the single file virtual disk and click next.

In this screen click the Customize Hardware button.



Here there are some settings you must check in your virtual machine:

  • At least 1 Gb of Ram is recommended.

  • In the Display category check the Accelerate 3D graphics.


Then click Save and Finish the installation, during the installation a new screen appeared, just say yes:



Now wait a moment.... and the Blackberry PlayBook simulator will be running in your VMware Player :D.




In my next post i will show you how to install the Blackberry PlayBook SDK and create your first application for this simulator of course in Linux and specifically in Ubuntu. If you have any question about this tutorial let me know.

martes, 14 de diciembre de 2010

Java AMF Client: Using AMF with JSP

In this post i will be posting how to get the efficient AMF connection to work with a Java client specifically JSP, you can use any other java client but for this port i will use JSP.

There are times when you want an efficient protocol to transport data, ok you can use AMF but what about the client... most of people think that since AMF is a protocol created by Adobe you should use a Flash Player client to get this work, the true is that you could use another type of client like Java for example, so let see how can we use this.

BlazeDS has a class called AMFConnection this will help us to get the work done so let get stated:

 Requirements:

  • Eclipse IDE
  • BlazeDS: You must have some knowledge in setup BlazeDS, if not check my tutorial About Connect BlazeDS with Java (Spanish) or you can check this good tutorial of Technical Evangelist Sujit Reddy - Setting up BlazeDS.
  • MySQL and Mysql Driver.
So first create a database, call it test_db and a table called person, this table has the following columns:

Now populate the table with some data, if you work with little amount of data you can't see the real power of AMF, but for this example some records will be enough, here there is a small Sql script for doing that. 

In the Eclipse IDE, we need to import our BlazeDS war file and add the Mysql driver, i call the project AMF_Client, the project should look like this.


Now we create a package hierarchy for our project:
    

In the dto package create a Person class and add the following:

Person.java

package dto;

public class Person {
private int id_person;
private String first_name;
private String last_name;
private double salary;
public int getId_person() {
return id_person;
}
public void setId_person(int idPerson) {
id_person = idPerson;
}
public String getFirst_name() {
return first_name;
}
public void setFirst_name(String firstName) {
first_name = firstName;
}
public String getLast_name() {
return last_name;
}
public void setLast_name(String lastName) {
last_name = lastName;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}


In our dao package create a DBHelper class for the connection, an interface PersonDAO and a class PersonDAOImp for the implementation.

DBHelper.java // There will be a lot of ways to do a database connection but i prefer this.

package dao;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

import com.mysql.jdbc.Driver;

public class DBHelper {
private static Connection conexion;
private DBHelper(){
}
public static Connection getConnection() throws SQLException{
Class driver = Driver.class;
if(conexion == null){
try{
conexion = DriverManager.getConnection("jdbc:mysql://localhost:3306/test_db","","");
}catch(SQLException ex){
throw new SQLException(ex.getMessage());
}
}
return conexion;
}
}


PersonDAO.java

package dao;

import java.sql.SQLException;
import java.util.List;

import dto.Person;

public interface PersonDAO {
public List getPeople() throws SQLException;
}


PersonDAOImp.java


package dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;


import dto.Person;

public class PersonDAOImp implements PersonDAO{
private Connection conexion;
@Override
public List getPeople() throws SQLException {
List people = new ArrayList();
try{
conexion = DBHelper.getConnection();
PreparedStatement pstmt = conexion.prepareStatement("SELECT * FROM person");
ResultSet rs = pstmt.executeQuery();
while(rs.next()){
Person person = new Person();
person.setId_person(rs.getInt(1));
person.setFirst_name(rs.getString(2));
person.setLast_name(rs.getString(3));
person.setSalary(rs.getDouble(4));
people.add(person);
}
}catch(SQLException ex){
throw new SQLException(ex.getMessage());
}
return people;
}
}    

Now create another class in the package services call this PersonService and put the following.

PersonService.java

package services;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import dao.PersonDAO;
import dao.PersonDAOImp;
import dto.Person;

public class PersonService {
private PersonDAO personDAO = new PersonDAOImp();
public List getPeople() throws SQLException {
List people = new ArrayList();
try{
people = personDAO.getPeople();
}catch(SQLException ex){
throw new SQLException(ex.getMessage());
}
return people;
}
}

We need to configure BlazeDS so we can use the Java AMF Client in our JSP page, open the remoting-config.xml located in WebContent/WEB-INF/flex add the following:

remoting-config.xml
    

<?xml version="1.0" encoding="UTF-8"?>
<service id="remoting-service" 
    class="flex.messaging.services.RemotingService">
    <adapters>
        <adapter-definition id="java-object" class="flex.messaging.services.remoting.adapters.JavaAdapter" default="true"/>
    </adapters>
    <default-channels>
        <channel ref="my-amf"/>
    </default-channels>
<destination id="PersonService">
<properties>
<source>services.PersonService</source>
</properties>
</destination>
</service>



Now we are going to create a JSP page for handling the PersonService result.

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<%@page import="flex.messaging.io.amf.client.AMFConnection"%>
<%@page import="flex.messaging.io.amf.client.exceptions.ClientStatusException"%>
<%@page import="java.util.List"%>
<%@page import="dto.Person"%>
<%@page import="java.util.ArrayList"%>
<%@page import="flex.messaging.io.amf.client.exceptions.ServerStatusException"%><html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Java AMF Client</title>
</head>
<body>
<%
AMFConnection amfConexion = new AMFConnection();
String amfUrl = "http://localhost:8080/AMF_Client/messagebroker/amf";
try{
//Make the conexion
amfConexion.connect(amfUrl);
}catch(ClientStatusException ex){
out.write("An error has ocurred");
}
//Make the remote call to out service
List<Person> people = new ArrayList<Person>();
try{
people = ((ArrayList<Person>)amfConexion.call("PersonService.getPeople"));
}catch(ClientStatusException ex){
out.write("An error has ocurred");
}catch(ServerStatusException ex){
out.write("An error has ocurred");
}
%>
<table border="1">
<tr>
<td>ID</td>
<td>First Name</td>
<td>Last Name</td>
<td>Salary</td>
</tr>
<%
for(Person p : people){
%>
<tr>
<td><%out.print(p.getId_person());%></td>
<td><%out.print(p.getFirst_name());%></td>
<td><%out.print(p.getLast_name());%></td>
<td><%out.print(p.getSalary());%></td>
</tr>
<%
}
%>
</table>
</body>
</html>


Now your run the project and you should have something like this:


That's all you have running a project with Java AMF Client, remember the true power of AMF comes when you deal with large amounts of data, this tutorial only explains the basics with few rows. 

Here is the complete source code of the Project, any trouble or suggestion let me know. 




sábado, 4 de diciembre de 2010

Red5 + BlazeDS = Realtime Video Chat Tutorial Part 4: BlazeDS chat.

This is the last part of the Series Red5 + BlazeDS = Realtime Video Chat. In this part we are going to build a normal chat with BlazeDS so users can chat with al the people connected on the application. To accomplish this we need explore the messaging features in BlazeDS and also see a little about Consumer / Producer in Flex.

First in our server side open the services-config.xml and add the following channel:

services-config.xml

        <channel-definition id="my-streaming-amf" class="mx.messaging.channels.StreamingAMFChannel">
        <endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/streamingamf"
                class="flex.messaging.endpoints.StreamingAMFEndpoint"/>
               <properties>
                   <idle-timeout-minutes>0</idle-timeout-minutes>
                   <max-streaming-clients>10</max-streaming-clients>
                   <server-to-client-heartbeat-millis>5000</server-to-client-heartbeat-millis>
               </properties>      
        </channel-definition>

In the code above we define a new StreamingAMF channel called my-streaming-channel now we need to specify that we are going to use this channel in our chat, now open the messaging-config.xml and add:

    <destination id="chat">
        <channels>
            <channel ref="my-streaming-amf"/>
        </channels>
    </destination>

We are creating a destination for out chat and specify that our chat will use a Streaming channel. That’s all in our server side, now let’s make an interface for out chat.

Open Red5_BlazeDS_Flex.mxml and add a TextArea and a TextInput inside a form like this:

<s:states>
        <s:State name="login"/>
        <s:State name="main"/>
    </s:states>
    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>
    <s:Group verticalCenter="0" horizontalCenter="0" includeIn="login">
        <s:Form>
            <s:FormItem label="Username">
                <s:HGroup>
                    <s:TextInput id="txtUsername"/>
                    <s:Button id="btnConnect" label="Login" click="btnConnect_clickHandler(event)"/>
                </s:HGroup>
            </s:FormItem>
        </s:Form>
    </s:Group>
    <s:HGroup width="100%" height="100%" includeIn="main">
        <s:VGroup width="30%" height="100%" paddingBottom="10" paddingLeft="10" paddingRight="10"
                  paddingTop="10">
            <s:Form width="100%">
                <s:FormItem label="Broadcast">
                    <s:HGroup>
                        <s:TextInput id="txtBroadcast"/>
                        <s:Button id="btnBroadcast" label="Broadcast" click="btnBroadcast_clickHandler(event)"/>
                    </s:HGroup>
                </s:FormItem>
            </s:Form>
            <mx:UIComponent id="outVideoWrapper" width="300" height="200"/>
            <s:Form>
                <s:FormItem label="Subscribe">
                    <s:HGroup>
                        <s:TextInput id="txtSubscribe"/>
                        <s:Button id="btnSubscribe" label="Subscribe" click="btnSubscribe_clickHandler(event)"/>
                    </s:HGroup>
                </s:FormItem>
            </s:Form>
            <mx:UIComponent id="inVideoWrapper" width="300" height="200"/>
        </s:VGroup>
        <s:VGroup width="100%" height="80%" paddingBottom="10" paddingLeft="10" paddingTop="10" paddingRight="10">
            <mx:Form width="100%" height="100%">
                <mx:FormItem width="100%" height="100%">
                    <s:TextArea id="txtConversation" width="100%" height="100%" editable="false"/>
                </mx:FormItem>
                <mx:FormItem  width="100%">
                    <s:TextInput id="txtChat" width="100%" enter="txtChat_enterHandler(event)"/>
                    <s:Button id="btnSend" label="Send" click="btnSend_clickHandler(event)"/>
                </mx:FormItem>
            </mx:Form>
        </s:VGroup>
    </s:HGroup>
    <s:TextArea id="txtLog" width="100%" height="100" color="red" bottom="0"
                editable="false" includeIn="main"/>

 

Now we must add the chat logic as follows:

  • Add a Producer and Consumer in the declarations tags:

   <fx:Declarations>
        <s:Producer id="producer" destination="chat"/>
        <s:Consumer id="consumer" destination="chat" message="consumer_messageHandler(event)" fault="consumer_faultHandler(event)"/>
        <mx:DateFormatter id="hourFormatter" formatString="KK:NN:SS"/>
    </fx:Declarations>

 

  • Create the events handlers for txtChat enter event and for btnSend click event:

           protected function btnSend_clickHandler(event:MouseEvent):void
            {
                var message:AsyncMessage = new AsyncMessage();
                message.body = txtChat.text;
                message.headers.user = txtUsername.text;
                producer.send(message);
                txtChat.text = "";
            }


            protected function consumer_messageHandler(event:MessageEvent):void
            {
                var hora:Date = new Date();
                var message:String = event.message.body as String;
                var usuario:String = event.message.headers.user as String;
                txtConversation.text += "[" + hourFormatter.format(hora) + "]" + usuario + " says: " + message + "\n";
            }


            protected function txtChat_enterHandler(event:FlexEvent):void
            {
                var message:AsyncMessage = new AsyncMessage();
                message.headers.user = txtUsername.text;
                message.body = txtChat.text;
                producer.send(message);
                txtChat.text = "";   
            }

            protected function consumer_faultHandler(event:MessageFaultEvent):void
            {
                txtLog.text += event.faultString + "\n";
            }

Now test your application and your application should look like this:

Here is the complete Source code:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/mx"
               creationComplete="initApp()" width="100%" height="100%">
    <fx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
            import mx.controls.Alert;
            import mx.events.FlexEvent;
            import mx.managers.PopUpManager;
            import mx.messaging.events.MessageEvent;
            import mx.messaging.events.MessageFaultEvent;
            import mx.messaging.messages.AsyncMessage;
            import mx.rpc.events.FaultEvent;
           
            private var connection:NetConnection;
            private var userWindow:UsersWindow;
            private var timer:Timer;
            //Streams
            private var inStream:NetStream;
            private var outStream:NetStream;
            //Devices
            private var camera:Camera;
            private var microphone:Microphone;
            //Video
            private var inVideo:Video;
            private var outVideo:Video;
           
            private function initApp():void {
                this.systemManager.stage.scaleMode = StageScaleMode.NO_SCALE;
               
            }
            protected function btnConnect_clickHandler(event:MouseEvent):void
            {
                if(txtUsername.text.length >= 3){
                    producer.connect();
                    consumer.subscribe();
                    userWindow = new UsersWindow();
                    timer = new Timer(2000);
                    timer.start();
                    timer.addEventListener(TimerEvent.TIMER, onTimerEvent);
                    currentState = "main";
                    connection = new NetConnection();
                    connection.connect("rtmp://localhost/Red5_BlazeDS_Java", txtUsername.text);
                    connection.addEventListener(NetStatusEvent.NET_STATUS, onConnectionStatus);
                    connection.client = this;
                }else{
                    txtUsername.errorString = "Enter a valid name";
                }
            }
            protected function onTimerEvent(event:TimerEvent):void {
                connection.call("getConnectedClients", new Responder(onResult, onFault));
            }
            protected function onResult(obj:Object):void {
                userWindow.setUsers(new ArrayCollection(obj as Array));
            }
            protected function onFault(obj:Object):void {
                txtLog.text += "Error " + obj.fault.message + "\n";
             }
            protected function onConnectionStatus(event:NetStatusEvent):void {
                if(event.info.code == "NetConnection.Connect.Success"){
                    txtLog.text += "Connection to RTMP successfully established\n";
                    connection.call("getConnectedClients", new Responder(onResult, onFault));
                    userWindow = UsersWindow(PopUpManager.createPopUp(this, UsersWindow, false));
                    PopUpManager.centerPopUp(userWindow);
                    userWindow.usuarioActual = txtUsername.text;
                }else{
                    txtLog.text += "Connection to RTMP fail\n";
                }
            }

            protected function btnBroadcast_clickHandler(event:MouseEvent):void
            {
                if(txtBroadcast.text.length > 3){
                    txtBroadcast.errorString = "";
                    //setup devices
                    camera = Camera.getCamera();
                    microphone = Microphone.getMicrophone();
                    //setup the streams
                    outStream = new NetStream(connection);
                    outStream.attachAudio(microphone);
                    outStream.attachCamera(camera);
                    outStream.publish(txtBroadcast.text);
                    //setup out video
                    outVideo = new Video(300,200);
                    outVideo.attachCamera(camera);
                    outVideoWrapper.addChild(outVideo)
                }else{
                    txtBroadcast.errorString = "Put a valid broadcast name";
                }
            }


            protected function btnSubscribe_clickHandler(event:MouseEvent):void
            {
                if(txtSubscribe.text.length > 3){
                    inStream = new NetStream(connection);
                    inStream.play(txtSubscribe.text);
                    inVideo = new Video(300,200);
                    inVideo.attachNetStream(inStream);
                    inVideoWrapper.addChild(inVideo);
                }
            }


            protected function btnSend_clickHandler(event:MouseEvent):void
            {
                var message:AsyncMessage = new AsyncMessage();
                message.body = txtChat.text;
                message.headers.user = txtUsername.text;
                producer.send(message);
                txtChat.text = "";
            }


            protected function consumer_messageHandler(event:MessageEvent):void
            {
                var hora:Date = new Date();
                var message:String = event.message.body as String;
                var usuario:String = event.message.headers.user as String;
                txtConversation.text += "[" + hourFormatter.format(hora) + "]" + usuario + " says: " + message + "\n";
            }


            protected function txtChat_enterHandler(event:FlexEvent):void
            {
                var message:AsyncMessage = new AsyncMessage();
                message.headers.user = txtUsername.text;
                message.body = txtChat.text;
                producer.send(message);
                txtChat.text = "";   
            }

            protected function consumer_faultHandler(event:MessageFaultEvent):void
            {
                txtLog.text += event.faultString + "\n";
            }

        ]]>
    </fx:Script>
    <s:states>
        <s:State name="login"/>
        <s:State name="main"/>
    </s:states>
    <fx:Declarations>
        <s:Producer id="producer" destination="chat"/>
        <s:Consumer id="consumer" destination="chat" message="consumer_messageHandler(event)" fault="consumer_faultHandler(event)"/>
        <mx:DateFormatter id="hourFormatter" formatString="KK:NN:SS"/>
    </fx:Declarations>
    <s:Group verticalCenter="0" horizontalCenter="0" includeIn="login">
        <s:Form>
            <s:FormItem label="Username">
                <s:HGroup>
                    <s:TextInput id="txtUsername"/>
                    <s:Button id="btnConnect" label="Login" click="btnConnect_clickHandler(event)"/>
                </s:HGroup>
            </s:FormItem>
        </s:Form>
    </s:Group>
    <s:HGroup width="100%" height="100%" includeIn="main">
        <s:VGroup width="30%" height="100%" paddingBottom="10" paddingLeft="10" paddingRight="10"
                  paddingTop="10">
            <s:Form width="100%">
                <s:FormItem label="Broadcast">
                    <s:HGroup>
                        <s:TextInput id="txtBroadcast"/>
                        <s:Button id="btnBroadcast" label="Broadcast" click="btnBroadcast_clickHandler(event)"/>
                    </s:HGroup>
                </s:FormItem>
            </s:Form>
            <mx:UIComponent id="outVideoWrapper" width="300" height="200"/>
            <s:Form>
                <s:FormItem label="Subscribe">
                    <s:HGroup>
                        <s:TextInput id="txtSubscribe"/>
                        <s:Button id="btnSubscribe" label="Subscribe" click="btnSubscribe_clickHandler(event)"/>
                    </s:HGroup>
                </s:FormItem>
            </s:Form>
            <mx:UIComponent id="inVideoWrapper" width="300" height="200"/>
        </s:VGroup>
        <s:VGroup width="100%" height="80%" paddingBottom="10" paddingLeft="10" paddingTop="10" paddingRight="10">
            <mx:Form width="100%" height="100%">
                <mx:FormItem width="100%" height="100%">
                    <s:TextArea id="txtConversation" width="100%" height="100%" editable="false"/>
                </mx:FormItem>
                <mx:FormItem  width="100%" direction="horizontal">
                    <s:TextInput id="txtChat" width="100%" enter="txtChat_enterHandler(event)" />
                    <s:Button id="btnSend" label="Send" click="btnSend_clickHandler(event)"/>
                </mx:FormItem>
            </mx:Form>
        </s:VGroup>
    </s:HGroup>
    <s:TextArea id="txtLog" width="100%" height="100" color="red" bottom="0"
                editable="false" includeIn="main"/>
</s:Application>


Here is the complete project and the other project that I show in the video demo.

So that’s all, this is my first series and I don’t want to be the last. If you found any error or have any suggestion, please let me know. Thanks

Red5 + BlazeDS = Realtime Video Chat Tutorial Part 3: Red5 video streaming

Hi, today i will show you how to enhance the application that we build in Tutorial part 1 and part 2, let add some video and voice to make things a little bit interesting. This tutorial continues part 1 and part 2 so take this parts first before reading this part.

So let's continue...

First we need to know a little about NetConnection and how to attach video and audio to the RTMP connection that we made in the last part of this tutorial. NetConnection comunicates with the server establishing a full duplex open connection in both the server and the client so it's perfect for use with the RTMP protocol.

Let's make some changes in the UI so we can add our camera, open Red5_BlazeDS_Flex.mxml and change the following (some update are made so we can use Flex 4.5 new components)

Red5_BlazeDS_Flex.mxml

<s:states>
        <s:State name="login"/>
        <s:State name="main"/>
    </s:states>
    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>
    <s:Group verticalCenter="0" horizontalCenter="0" includeIn="login">
        <s:Form>
            <s:FormItem label="Username">
                <s:HGroup>
                    <s:TextInput id="txtUsername"/>
                    <s:Button id="btnConnect" label="Login" click="btnConnect_clickHandler(event)"/>
                </s:HGroup>
            </s:FormItem>
        </s:Form>
    </s:Group>
    <s:HGroup width="100%" height="100%" includeIn="main">
        <s:VGroup width="30%" height="100%" paddingBottom="10" paddingLeft="10" paddingRight="10"
                  paddingTop="10">
            <s:Form width="100%">
                <s:FormItem label="Broadcast" >
                    <s:HGroup>
                        <s:TextInput id="txtBroadcast"/>
                        <s:Button id="btnBroadcast" label="Broadcast" click="btnBroadcast_clickHandler(event)"/>
                    </s:HGroup>
                </s:FormItem>
            </s:Form>
            <mx:UIComponent id="outVideoWrapper" width="300" height="200"/>
            <s:Form>
                <s:FormItem label="Subscribe">
                    <s:HGroup>
                        <s:TextInput id="txtSubscribe"/>
                        <s:Button id="btnSubscribe" label="Subscribe"/>
                    </s:HGroup>
                </s:FormItem>
            </s:Form>
            <mx:UIComponent id="inVideoWrapper" width="300" height="200"/>
        </s:VGroup>
    </s:HGroup>
    <s:TextArea id="txtLog" width="100%" height="100" color="red" bottom="0"
                editable="false" includeIn="main"/>

This code add to our user interface 2 UIComponent this components will be the video wrappers in our application.

Now let’s attach the video, for make this possible we must do some steps:
  1. Make the  connection (done in the last step)
  2. Create the streams in/out
  3. Setup  the devices
  4. Create the video.
First we declare the variables:

In our Red5_BlazeDS_Flex.mxml in after the <s:Script>:

            import mx.collections.ArrayCollection;
            import mx.controls.Alert;
            import mx.managers.PopUpManager;
            private var connection:NetConnection;          
            private var userWindow:UsersWindow;
            private var timer:Timer;
           //Streams             
           private var inStream:NetStream;             
           private var outStream:NetStream;             
           //Devices             
           private var camera:Camera;             
           private var microphone:Microphone;             
           //Video             
           private var inVideo:Video;             
           private var outVideo:Video;

Then we need to add click event to our Broadcast button and then write a click handler function has follow:


           protected function btnBroadcast_clickHandler(event:MouseEvent):void {
                if(txtBroadcast.text.length > 3){
                    txtBroadcast.errorString = "";
                    //setup devices
                    camera = Camera.getCamera(); 
                    microphone = Microphone.getMicrophone();
                    //setup the streams
                    outStream = new NetStream(connection);
                    outStream.attachAudio(microphone);
                    outStream.attachCamera(camera);
                    outStream.publish(txtBroadcast.text);
                    //setup out video
                    outVideo = new Video(300,200);
                    outVideo.attachCamera(camera);
                    outVideoWrapper.addChild(outVideo)
                }else{
                    txtBroadcast.errorString = "Put a valid broadcast name";
                }
            }

Now add click event to our Subscribe button and then write a click handler function has follow:

           protected function btnSubscribe_clickHandler(event:MouseEvent):void
            {                 
                    if(txtSubscribe.text.length > 3){
                          inStream = new NetStream(connection);
                          inStream.play(txtSubscribe.text);
                          inVideo = new Video(300,200);
                          inVideo.attachNetStream(inStream);
                          inVideoWrapper.addChild(inVideo);
                }
            }

Now run your application, write a text to Broadcast and then test this in a different browser client open the same application put in the subscribe textinput the name of your broadcast and voila!! you will have the following:


That's all and of course here is the complete code, If you found any error or have any suggestion, please let me know.