Trabalhando com câmeras

Flash Player 9 e posterior, Adobe AIR 1.0 e posterior

Uma câmera conectada ao computador de um usuário pode funcionar como fonte de dados de vídeo, que você pode exibir e manipular usando o ActionScript. A classe Camera é o mecanismo criado no ActionScript para trabalhar com um computador ou dispositivo de câmera.

Nos dispositivos móveis, você também pode usar a classe CameraUI . A classe CameraUI ativa um aplicativo de câmera para permitir que o usuário capture uma tomada de imagem ou de vídeo. Quando o usuário terminar, seu aplicativo poderá acessar a imagem ou o vídeo por meio de um objeto MediaPromise .

Noções básicas sobre a classe Camera

O objeto Camera permite que você se conecte à câmera local do usuário e transmita o vídeo localmente (para o usuário) ou remotamente para um servidor (como o Flash Media Server).

Usando a classe Camera, é possível acessar os seguintes tipos de informações sobre a câmera do usuário:

  • Quais câmeras instaladas no computador ou dispositivo do usuário estão disponíveis.

  • Se há uma câmera instalada

  • Se o Flash Player tem acesso à câmera do usuário ou não

  • Qual câmera está ativa

  • A largura e a altura do vídeo que está sendo capturado

A classe Camera inclui vários métodos e propriedades úteis para trabalhar com objetos Camera. Por exemplo, a propriedade estática Camera.names contém uma matriz de nomes de câmeras que estão instaladas no computador do usuário. Você também pode usar a propriedade name para exibir o nome da câmera que está ativa.

Nota: Ao transmitir fluxo de vídeo da câmera pela rede, trate sempre das interrupções da rede. Interrupções de rede podem ocorrer por muitos motivos, especialmente em dispositivos móveis.

Exibição do conteúdo da câmera na tela

A conexão a uma câmera pode exigir menos código do que usar as classes NetConnection e NetStream para carregar um vídeo. A classe Camera também pode rapidamente se tornar complicada porque, com o Flash Player, você precisa da permissão do usuário para se conectar à câmera dele antes de acessá-la.

Este código demonstra como usar a classe Camera para se conectar à câmera local de um usuário:

var cam:Camera = Camera.getCamera(); 
var vid:Video = new Video(); 
vid.attachCamera(cam); 
addChild(vid);
Nota: A classe Camera não tem um método construtor. Para criar uma nova ocorrência de Camera, use o método estático Camera.getCamera() .

Desenvolvimento do aplicativo de câmera

Ao criar um aplicativo que se conecta à câmera de um usuário, considere os seguintes aspectos no seu código:

  • Verifique se o usuário tem uma câmera instalada. Trate o caso em que não há nenhuma câmera disponível.

  • Somente no Flash Player, verifique se o usuário permitiu acesso à câmera explicitamente. Por motivo de segurança, o player exibe a caixa de diálogo Configurações do Flash Player, onde o usuário pode conceder ou negar acesso à sua câmera. Isso impede que o Flash Player se conecte à câmera de um usuário e transmita um fluxo de vídeo sem a devida permissão. Se um usuário clicar em permitir, o aplicativo poderá se conectar à câmera. Se ele clicar em negar, o aplicativo não conseguirá ter acesso à câmera do usuário. Seus aplicativos sempre devem manipular os dois casos normalmente.

  • Somente para o AIR, verifique se a classe Camera conta com o suporte dos perfis de dispositivo compatíveis com seu aplicativo.

  • A classe Camera não conta com suporte em navegadores móveis.

  • A classe Camera não conta com suporte em aplicativos AIR móveis que usam o modo de renderização pela GPU.

  • Em dispositivos móveis, somente uma câmera pode ficar ativa de cada vez.

Conexão à câmera de um usuário

A primeira etapa para se conectar à câmera de um usuário é criar uma nova ocorrência de Camera criando uma variável do tipo Camera e a inicializando com o valor de retorno do método estático Camera.getCamera() .

A próxima etapa é criar um novo objeto de vídeo e conectar o objeto Camera a ele.

A terceira etapa é adicionar o objeto de vídeo à lista de exibição. Você precisa executar as etapas 2 e 3 porque a classe Camera não estende a classe DisplayObject, por isso não é possível adicioná-la diretamente à lista de exibição. Para exibir o vídeo capturado da câmera, crie um novo objeto de vídeo e chame o método attachCamera() .

O seguinte código mostra estas três etapas:

var cam:Camera = Camera.getCamera(); 
var vid:Video = new Video(); 
vid.attachCamera(cam); 
addChild(vid);

Observe que, se o usuário não tiver uma câmera instalada, o aplicativo não exibirá nada.

Na prática, você precisa executar outras etapas que envolvem o seu aplicativo. Para obter mais informações, consulte Verificação da instalação das câmeras e Detecção de permissões de acesso à câmera .

Verificação da instalação das câmeras

Antes de tentar usar qualquer um dos métodos ou propriedades em uma ocorrência de Camera, é recomendável verificar se o usuário tem uma câmera instalada. Há duas maneiras de fazer essa verificação:

  • Verifique a propriedade estática Camera.names que contém uma matriz de nomes de câmeras que estão disponíveis. Normalmente, essa matriz terá no máximo uma string, porque é provável que a maioria dos usuários não tenha mais de uma câmera instalada. Este código demonstra como verificar a propriedade Camera.names para saber se o usuário tem alguma câmera disponível:

    if (Camera.names.length > 0) 
    { 
        trace("User has at least one camera installed."); 
        var cam:Camera = Camera.getCamera(); // Get default camera. 
    } 
    else 
    { 
        trace("User has no cameras installed."); 
    }
  • Verifique o valor de retorno do método estático Camera.getCamera() . Se não houver nenhuma câmera disponível ou instalada, o método retornará null ; caso contrário, ele retornará uma referência a um objeto Camera. Este código demonstra como verificar o método Camera.getCamera() para saber se o usuário tem alguma câmera disponível:

    var cam:Camera = Camera.getCamera(); 
    if (cam == null) 
    { 
        trace("User has no cameras installed."); 
    } 
    else 
    { 
        trace("User has at least 1 camera installed."); 
    }

Como a classe Camera não estende a classe DisplayObject, não pode ser adicionada diretamente à lista de exibição usando o método addChild() . Para exibir o vídeo capturado da câmera, é preciso criar um novo objeto Video e chamar o método attachCamera() na ocorrência de Video.

Este snippet mostra como conectar a câmera, se disponível; se não houver uma câmera, o aplicativo não exibirá nada:

var cam:Camera = Camera.getCamera(); 
if (cam != null) 
{ 
    var vid:Video = new Video(); 
    vid.attachCamera(cam); 
    addChild(vid); 
}

Câmeras de dispositivos móveis

A classe Camera não é suportada no tempo de execução do Flash Player em navegadores móveis.

Nos aplicativos AIR em dispositivos móveis você pode acessar a câmera ou câmeras no dispositivo. Em dispositivos móveis, você pode usar tanto a câmera frontal quanto a câmera traseira, mas somente uma saída de câmera pode ser exibida em um determinado momento. (Conectar uma segunda câmera desconecta a primeira.) A câmera frontal está refletida horizontalmente no iOS; no Android, não está.

Detecção de permissões de acesso à câmera

Na caixa de proteção do aplicativo do AIR, o aplicativo pode acessar qualquer câmera sem a permissão do usuário. No Android, no entanto, um aplicativo deve especificar a permissão CAMERA do Android no descritor do aplicativo.

Para que o Flash Player possa exibir a saída de uma câmera, o usuário deve permitir o acesso do Flash Player à câmera explicitamente. Quando o método attachCamera() é chamado, o Flash Player exibe a caixa de diálogo Configurações do Flash Player, que pede para o usuário conceder ou negar acesso à câmera e ao microfone para o Flash Player. Se o usuário clicar no botão Permitir, o Flash Player exibirá a saída da câmera na ocorrência de Video no Palco. Se o usuário clicar no botão Negar, o Flash Player não conseguirá se conectar à câmera, e o objeto Video não exibirá nada.

Para detectar se o usuário concedeu acesso à câmera para o Flash Player, você pode monitorar o evento status da câmera ( StatusEvent.STATUS ), como visto neste código:

var cam:Camera = Camera.getCamera(); 
if (cam != null) 
{ 
    cam.addEventListener(StatusEvent.STATUS, statusHandler); 
    var vid:Video = new Video(); 
    vid.attachCamera(cam); 
    addChild(vid); 
} 
function statusHandler(event:StatusEvent):void 
{ 
    // This event gets dispatched when the user clicks the "Allow" or "Deny" 
    // button in the Flash Player Settings dialog box. 
    trace(event.code); // "Camera.Muted" or "Camera.Unmuted" 
}

A função statusHandler() é chamada assim que o usuário clica em Permitir ou Negar. Você pode detectar em qual botão o usuário clicou usando um destes dois métodos:

  • O parâmetro event da função statusHandler() contém uma propriedade de código que inclui a string “Camera.Muted” ou “Camera.Unmuted”. Se o valor é “Camera.Muted”, isso significa que o usuário clicou no botão Negar e o Flash Player não pode acessar a câmera. Este snippet mostra um exemplo disso:

    function statusHandler(event:StatusEvent):void 
    { 
        switch (event.code) 
        { 
            case "Camera.Muted": 
                trace("User clicked Deny."); 
                break; 
            case "Camera.Unmuted": 
                trace("User clicked Accept."); 
                break; 
        } 
    }
  • A classe Camera contém uma propriedade somente leitura chamada muted que especifica se o usuário negou acesso à câmera ( true ) ou se permitiu acesso a ela ( false ) no painel Privacidade do Flash Player. Este snippet mostra um exemplo disso:

    function statusHandler(event:StatusEvent):void 
    { 
        if (cam.muted) 
        { 
            trace("User clicked Deny."); 
        } 
        else 
        { 
            trace("User clicked Accept."); 
        } 
    }

Verificando o eventos de status a ser despachado, você pode criar um código que lide com a aceitação ou a negação do acesso à câmera pelo usuário e fazer as devidas exclusões. Por exemplo, se o usuário clicar no botão Negar, você poderá exibir uma mensagem informando que ele deve clicar em Permitir se deseja participar de um bate-papo com vídeo, ou você poderá verificar se o objeto Video da lista de exibição foi excluído para liberar recursos do sistema.

No AIR, um objeto Camera não despacha eventos de status, visto que a permissão para usar a câmera não é dinâmica.

Maximizando a qualidade de vídeo da câmera

Por padrão, as novas ocorrências da classe Video têm 320 pixels de largura por 240 pixels de altura. Para maximizar a qualidade dos vídeos, sempre verifique se o objeto de vídeo tem as mesmas dimensões do vídeo retornado pelo objeto de câmera. Para obter a largura e a altura do objeto de câmera, use as propriedades width e height da classe Camera; em seguida, você pode definir as propriedades width e height do objeto de vídeo de modo que correspondam às dimensões dos objetos de câmera, ou pode passar a largura e a altura da câmera para o método construtor da classe Video, como visto neste snippet:

var cam:Camera = Camera.getCamera(); 
if (cam != null) 
{ 
    var vid:Video = new Video(cam.width, cam.height); 
    vid.attachCamera(cam); 
    addChild(vid); 
}

Uma vez que o método getCamera() retorna uma referência a um objeto de câmera (ou null se não houver câmeras disponíveis), você poderá acessar os métodos e as propriedades da câmera mesmo que o usuário negue acesso a ela. Isso permite que você defina o tamanho da ocorrência de vídeo usando a altura e a largura nativas da câmera.

var vid:Video; 
var cam:Camera = Camera.getCamera(); 
 
if (cam == null) 
{ 
    trace("Unable to locate available cameras."); 
} 
else 
{ 
    trace("Found camera: " + cam.name); 
    cam.addEventListener(StatusEvent.STATUS, statusHandler); 
    vid = new Video(); 
    vid.attachCamera(cam); 
} 
function statusHandler(event:StatusEvent):void 
{ 
    if (cam.muted) 
    { 
        trace("Unable to connect to active camera."); 
    } 
    else 
    { 
        // Resize Video object to match camera settings and  
        // add the video to the display list. 
        vid.width = cam.width; 
        vid.height = cam.height; 
        addChild(vid); 
    } 
    // Remove the status event listener. 
    cam.removeEventListener(StatusEvent.STATUS, statusHandler); 
}

Para obter informações sobre o modo de tela cheia, consulte a seção Modo de tela cheia em Configuração de propriedades do palco .

Monitorando o status da câmera

A classe Camera contém várias propriedades que permitem monitorar o status atual do objeto Camera. Por exemplo, este código exibe diversas propriedades da câmera usando um objeto Timer e uma ocorrência de campo de texto na lista de exibição:

var vid:Video; 
var cam:Camera = Camera.getCamera(); 
var tf:TextField = new TextField(); 
tf.x = 300; 
tf.autoSize = TextFieldAutoSize.LEFT; 
addChild(tf); 
 
if (cam != null) 
{ 
    cam.addEventListener(StatusEvent.STATUS, statusHandler); 
    vid = new Video(); 
    vid.attachCamera(cam); 
} 
function statusHandler(event:StatusEvent):void 
{ 
    if (!cam.muted) 
    { 
        vid.width = cam.width; 
        vid.height = cam.height; 
        addChild(vid); 
        t.start(); 
    } 
    cam.removeEventListener(StatusEvent.STATUS, statusHandler); 
} 
 
var t:Timer = new Timer(100); 
t.addEventListener(TimerEvent.TIMER, timerHandler); 
function timerHandler(event:TimerEvent):void 
{ 
    tf.text = ""; 
    tf.appendText("activityLevel: " + cam.activityLevel + "\n"); 
    tf.appendText("bandwidth: " + cam.bandwidth + "\n"); 
    tf.appendText("currentFPS: " + cam.currentFPS + "\n"); 
    tf.appendText("fps: " + cam.fps + "\n"); 
    tf.appendText("keyFrameInterval: " + cam.keyFrameInterval + "\n"); 
    tf.appendText("loopback: " + cam.loopback + "\n"); 
    tf.appendText("motionLevel: " + cam.motionLevel + "\n"); 
    tf.appendText("motionTimeout: " + cam.motionTimeout + "\n"); 
    tf.appendText("quality: " + cam.quality + "\n"); 
}

A cada 1/10 de segundo (100 milissegundos) o evento timer do objeto Timer é despachado, e a função timerHandler() atualiza o campo de texto na lista de exibição.