Projeto webcam1

Este projeto irá publicar a webcam do usuário no servidor e deixará a mesma disponível para visualização pela internet, isto é possível com o uso do serviço live do red5. O primeiro arquivo faz tudo isso junto, depois usando este mesmo arquivo, podemos dividí-lo em dois, cria-se um arquivo de video para publicação no servidor e outro para visualização deste arquivo de video pelo cliente.
Apesar de chamar de projeto, este exemplo não irá configurar os arquivos web.xml, red5-web.xml e 
red5-web.properties nem criar a estrutura de pasta do projeto.

Lembrando que a estrutura de pastas de um projeto em Java é:
src - código fonte Java (.java)
build - onde o Eclipse compila as classes (.class)
WebContent - content directory (páginas, imagens, css etc vão aqui)
WebContent/WEB-INF/ - pasta oculta com configurações e recursos do projeto
WebContent/WEB-INF/lib/ - bibliotecas .jar
WebContent/WEB-INF/classes/ - arquivos compilados são copiados para cá
META-INF

Projeto webcam1
Crie uma pasta com a seguinte estrutura C:\projetoFlex\webcam1
Dentro da pasta webcam1 será criado dos demais arquivos.

1) Abra o FlashDevelop
2) Crie o arquivo MXML
Nenu Fle > New > MXML Document > webcam1
3) Recorte e cole o código fonte baixo:

Arquivo: webcam1.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    layout="vertical"
    horizontalAlign="left"
    backgroundColor="#f6f6f6"
 
    viewSourceURL="index.html" >
   
    <mx:Script>
        <![CDATA[
            import mx.controls.Alert;
           
            private var nc:NetConnection;
            private var nsCli:NetStream;
            private var nsPub:NetStream;
           
            [Bindable]
            private var statusConnection:Boolean = false
           
            /**
            * Inicia a aplicação e faz a conexão
            */
            private function init():void
            {
                if(nc != null)
                    nc = null;
                nc = new NetConnection();
                nc.addEventListener( NetStatusEvent.NET_STATUS, netStatus );
                nc.connect(hostRTMP.text);
                nc.client = this;
            }
            /**
            * Método necessário para que não haja erro na chamada.
            * Ele será invocado e retornará o ID da conexão
            */
            public function setId(id:Object):void{}
           
            /**
            * Método que recebe o Status da conexão
            */
            private function netStatus( e:NetStatusEvent ):void
            {
                RED5Status.text = e.info.code;
                switch( e.info.code )
                {
                    case "NetConnection.Connect.Success":
                        statusConnection = true;
                        break;
                    case "NetConnection.Connect.Closed":
                        statusConnection = false
                        break;
                    case "NetConnection.Connect.Rejected":
                        statusConnection = false
                        break;                   
                }
            }
           
            private function publicar():void
            {
                if(nsPub != null)
                {
                    btPublicar.label = "Publicar no servidor RTMP!"
                   
                    nsPub.close()
                    nsPub = null
                }
                else
                {
                    btPublicar.label = "Parar publicação!"
                   
                    nsPub = new NetStream ( nc );
                    nsPub.attachCamera(Camera.getCamera());
                   
                    // nome que será publicado
                    nsPub.publish("teste","record");
                    vdMinhaWebCam.attachCamera(Camera.getCamera());
                 }
            }
           
            private function visualizar():void
            {
                if(!statusConnection)
                {
                    Alert.show("Não conectado ao servidor!")
                    return;
                }
               
                if(nsCli != null)
                {
                    btVisualizar.label="Visualizar do servidor de RTMP!";
                   
                    nsCli.close();
                    nsCli = null
                }
                else
                {
                    btVisualizar.label="Parar Visualização!";
                   
                    nsCli = new NetStream ( nc )
                   
                    var vid:Video = new Video();
                    vid.height = uiCaixaDoVideo.height;
                    vid.width  = uiCaixaDoVideo.width;
                    vid.attachNetStream( nsCli );
                   
                    uiCaixaDoVideo.addChild( vid );
                   
                    // nome que foi publicado
                    nsCli.play("teste");
                }
            }
       
        ]]>
    </mx:Script>
    <mx:HBox>
        <mx:TextInput id="hostRTMP" text="rtmp://localhost/live"/>
        <mx:Button label="Conectar ao servidor" click="init()"/>
        <mx:Label id="RED5Status" left="178" top="12"/>
    </mx:HBox>
    <mx:VBox enabled="{statusConnection}">
        <mx:HBox>
            <mx:Button id="btPublicar"
                label="Publicar no servidor RTMP!" click="publicar()" left="7" top="40" width="320"/>
            <mx:Button id="btVisualizar"
                label="Visualizar do servidor RTMP!" click="visualizar()" left="7" top="40" width="320"/>
        </mx:HBox>
        <mx:HBox>
            <mx:VBox>
                <mx:VideoDisplay width="550" height="550" id="vdMinhaWebCam" left="10" top="85"/>
            </mx:VBox>
            <mx:VBox>
                <mx:VBox width="320" height="240"
                     backgroundColor="#000000" left="10" top="334">
                     <mx:UIComponent toolTip="Captura de vídeo" id="uiCaixaDoVideo" width="100%" height="100%"  x="10" y="353"/>
                </mx:VBox>
            </mx:VBox>
        </mx:HBox>
    </mx:VBox>
</mx:Application>

4) Menu Tools > Flash Tools > Build Current File


Análise:
1) Foi utilizado o serviço live do Red5 para a reprodução em tempo real e gravação de audio e vídeo.
2) No método .publish("teste","record")
O primeiro parâmetro, teste,  é o nome do arquivo de vídeo ou áudio, poder ser qualquer um, desde que seja válido.
O segundo parâmetro, record, configura a publicação para reprodução em tempo real e gravação do arquivo de nome teste em C:\Red5java\webapps\live\streams.
3) A figura acima mostra a filmagem pela webcam do próprio monitor no momento da execução do exemplo.

Incorporação do arquivo webcam1.swf em uma página HTML

Arquivo: index.html
<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="content-type">
<title></title>
</head>
<body>
<object data="webcam1.swf" type="application/x-shockwave-flash" height="100%" width="100%">
  <param value="webcam1.swf" name="movie">
  <param value="transparent" name="wmode">
</object>
</body>
</html>


Projeto webcam2
Dividindo o arquivo anterior em dois, uma arquivo para publicar (webcam2.mxml) e outro arquivo para visualizar (webcam3.mxml):

1) Abra o FlashDevelop
2) Crie o arquivo MXML
Nenu Fle > New > MXML Document > webcam2
3) Recorte e cole o código fonte baixo:

Arquivo: webcam2.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    layout="vertical"
    horizontalAlign="left"
    backgroundColor="#f6f6f6"
  
   
    viewSourceURL="index.html"
    >
   
    <mx:Script>
        <![CDATA[
            import mx.controls.Alert;
           
            private var nc:NetConnection;
            private var nsCli:NetStream;
            private var nsPub:NetStream;
           
            [Bindable]
            private var statusConnection:Boolean = false
           
            /**
            * Inicia a aplicação e faz a conexão
            */
            private function init():void
            {
                if(nc != null)
                    nc = null;
                nc = new NetConnection();
                nc.addEventListener( NetStatusEvent.NET_STATUS, netStatus );
                nc.connect(hostRTMP.text);
                nc.client = this;
            }
            /**
            * Método necessário para que não haja erro na chamada.
            * Ele será invocado e retornará o ID da conexão
            */
            public function setId(id:Object):void{}
           
            /**
            * Método que recebe o Status da conexão
            */
            private function netStatus( e:NetStatusEvent ):void
            {
                RED5Status.text = e.info.code;
                switch( e.info.code )
                {
                    case "NetConnection.Connect.Success":
                        statusConnection = true;
                        break;
                    case "NetConnection.Connect.Closed":
                        statusConnection = false
                        break;
                    case "NetConnection.Connect.Rejected":
                        statusConnection = false
                        break;                   
                }
            }
           
            private function publicar():void
            {
                if(nsPub != null)
                {
                    btPublicar.label = "Publicar no servidor RTMP!"
                   
                    nsPub.close()
                    nsPub = null
                }
                else
                {
                    btPublicar.label = "Parar publicação!"
                   
                    nsPub = new NetStream ( nc );
                    nsPub.attachCamera(Camera.getCamera());
                   
                    // nome que será publicado
                    nsPub.publish("teste2","record");
                    vdMinhaWebCam.attachCamera(Camera.getCamera());
                 }
            }
       
        ]]>
    </mx:Script>
    <mx:HBox>
        <mx:TextInput id="hostRTMP" text="rtmp://localhost/live"/>
        <mx:Button label="Conectar ao servidor" click="init()"/>
        <mx:Label id="RED5Status" left="178" top="12"/>
    </mx:HBox>
    <mx:VBox enabled="{statusConnection}">
        <mx:HBox>
            <mx:Button id="btPublicar"
                label="Publicar no servidor RTMP!" click="publicar()" left="7" top="40" width="320"/>
        </mx:HBox>
        <mx:HBox>
            <mx:VBox>
                <mx:VideoDisplay width="320" height="240" id="vdMinhaWebCam" left="10" top="85"/>
            </mx:VBox>
            <mx:VBox>
              
            </mx:VBox>
        </mx:HBox>
    </mx:VBox>
</mx:Application>

4) Menu Tools > Flash Tools > Build Current File
Será crriado o arquivo webcam2.swf em C:\projetoFlex\webcam1, local de criação do arquivo webcam2 .mxml

Arquivo: webcam3.mxml
1) Abra o FlashDevelop
2) Crie o arquivo MXML
Nenu Fle > New > MXML Document > webcam3
3) Recorte e cole o código fonte baixo:

Arquivo: webcam3.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    layout="vertical"
    horizontalAlign="left"
    backgroundColor="#f6f6f6"
  
   
    viewSourceURL="index.html"
    >
   
    <mx:Script>
        <![CDATA[
            import mx.controls.Alert;
           
            private var nc:NetConnection;
            private var nsCli:NetStream;
            private var nsPub:NetStream;
           
            [Bindable]
            private var statusConnection:Boolean = false
           
            /**
            * Inicia a aplicação e faz a conexão
            */
            private function init():void
            {
                if(nc != null)
                    nc = null;
                nc = new NetConnection();
                nc.addEventListener( NetStatusEvent.NET_STATUS, netStatus );
                nc.connect(hostRTMP.text);
                nc.client = this;
            }
            /**
            * Método necessário para que não haja erro na chamada.
            * Ele será invocado e retornará o ID da conexão
            */
            public function setId(id:Object):void{}
           
            /**
            * Método que recebe o Status da conexão
            */
            private function netStatus( e:NetStatusEvent ):void
            {
                RED5Status.text = e.info.code;
                switch( e.info.code )
                {
                    case "NetConnection.Connect.Success":
                        statusConnection = true;
                        break;
                    case "NetConnection.Connect.Closed":
                        statusConnection = false
                        break;
                    case "NetConnection.Connect.Rejected":
                        statusConnection = false
                        break;                   
                }
            }
           
            private function visualizar():void
            {
                if(!statusConnection)
                {
                    Alert.show("Não conectado ao servidor!")
                    return;
                }
               
                if(nsCli != null)
                {
                    btVisualizar.label="Visualizar do servidor de RTMP!";
                   
                    nsCli.close();
                    nsCli = null
                }
                else
                {
                    btVisualizar.label="Parar Visualização!";
                   
                    nsCli = new NetStream ( nc )
                   
                    var vid:Video = new Video();
                    vid.height = uiCaixaDoVideo.height;
                    vid.width  = uiCaixaDoVideo.width;
                    vid.attachNetStream( nsCli );
                   
                    uiCaixaDoVideo.addChild( vid );
                   
                    // nome que foi publicado
                    nsCli.play("teste2");
                }
            }
       
        ]]>
    </mx:Script>
    <mx:HBox>
        <mx:TextInput id="hostRTMP" text="rtmp://localhost/live"/>
        <mx:Button label="Conectar ao servidor" click="init()"/>
        <mx:Label id="RED5Status" left="178" top="12"/>
    </mx:HBox>
    <mx:VBox enabled="{statusConnection}">
        <mx:HBox>
            <mx:Button id="btVisualizar"
                label="Visualizar do servidor RTMP!" click="visualizar()" left="7" top="40" width="320"/>
        </mx:HBox>
        <mx:HBox>

            <mx:VBox>
                <mx:VBox width="320" height="240"
                     backgroundColor="#000000" left="10" top="334">
                     <mx:UIComponent toolTip="Captura de vídeo" id="uiCaixaDoVideo" width="100%" height="100%"  x="10" y="353"/>
                </mx:VBox>
            </mx:VBox>
        </mx:HBox>
    </mx:VBox>
</mx:Application>

4) Menu Tools > Flash Tools > Build Current File
Será crriado o arquivo webcam3.swf em C:\projetoFlex\webcam1, local de criação do arquivo webcam3 .mxml

5) Abra os arquivos webcam2.swf e webcam3.swf em páginas diferetes:
Dê um clique com o botão direito do mouse no arquivo webcam2.swf e selecione abrir com > Google Chrome
C:\projetoFlex\webcam1\webcam2.swf

Clique em Conectar ao servidor e depois em Publicar no servidor:



Dê um clique com o botão direito do mouse no arquivo webcam.swf e selecione abrir com > Google Chrome
C:\projetoFlex\webcam1\webcam2.swf

Clique em Conectar ao servidor e depois em Visializar do servidor:


Observações:
Navegue entre as duas abas e verifique a publicão e visualizaação em tempo real.
Ao clicar em parar publicação, é interrompido a publicação e o arquivo teste2.flv é finalizado.
Cada Browser tem um forma de permissão de acesso da webcam.
Quanto ao uso Red5 e do Adobe Flash Player já foi explicado na apostila Red5.