Captura de entrada do som
Flash Player 9 e posterior, Adobe AIR 1.0 e posterior
A classe Microphone permite que o aplicativo se conecte a um microfone ou a outro dispositivo de entrada de som no sistema do usuário e transmita o áudio de entrada para os alto-falantes daquele sistema ou envie os dados de áudio a um servidor remoto, como o Flash Media Server. Você pode acessar os dados de áudio brutos a partir do microfone e gravá-los ou processá-los. Também pode enviar o áudio diretamente para os alto-falantes do sistema ou enviar dados de áudio compactados para um servidor remoto. É possível usar o codec Speex ou Nellymoser para os dados enviados a um servidor remoto. (O suporte para o codec Speex foi disponibilizado a partir do Flash Player 10 e do Adobe AIR 1.5.)
Acesso a um microfone
A classe Microphone não tem um método construtor. Em vez disso, você usa o método estático
Microphone.getMicrophone()
para obter uma nova ocorrência de Microphone, conforme mostrado a seguir:
var mic:Microphone = Microphone.getMicrophone();
A chamada do método
Microphone.getMicrophone()
sem um parâmetro retorna o primeiro dispositivo de entrada de som descoberto no sistema do usuário.
Um sistema pode ter mais de um dispositivo de entrada de som conectado a ele. O aplicativo pode usar a propriedade
Microphone.names
para obter uma matriz dos nomes de todos os dispositivos de entrada de som disponíveis. Em seguida, ele pode chamar o método
Microphone.getMicrophone()
com um parâmetro
index
que corresponde ao valor de índice de um nome de dispositivo na matriz.
Um sistema talvez não tenha um microfone ou outro dispositivo de entrada de som conectado a ele. É possível usar a propriedade
Microphone.names
ou o método
Microphone.getMicrophone()
para verificar se o usuário tem um dispositivo de entrada de som instalado. Se o usuário não tiver um dispositivo de entrada de som instalado, a matriz
names
terá um comprimento de zero e o método
getMicrophone()
retornará um valor
null
.
Quando o aplicativo chama o método
Microphone.getMicrophone()
, o Flash Player exibe a caixa de diálogo Configurações do Flash Player que solicita que o usuário permita ou negue acesso do Flash Player à câmara e ao microfone no sistema. Depois que o usuário clicar no botão Permitir ou Negar neste diálogo, um StatusEvent será despachado. A propriedade
code
dessa ocorrência de StatusEvent indica se o acesso ao microfone foi permitido ou negado, conforme mostrado neste exemplo:
import flash.media.Microphone;
var mic:Microphone = Microphone.getMicrophone();
mic.addEventListener(StatusEvent.STATUS, this.onMicStatus);
function onMicStatus(event:StatusEvent):void
{
if (event.code == "Microphone.Unmuted")
{
trace("Microphone access was allowed.");
}
else if (event.code == "Microphone.Muted")
{
trace("Microphone access was denied.");
}
}
A propriedade
StatusEvent.code
conterá “Microphone.Unmuted”, se o acesso for permitido, ou “Microphone.Muted”, se o acesso for negado.
A propriedade
Microphone.muted
é definida como
true
ou
false
quando o usuário permite ou nega acesso ao microfone, respectivamente. No entanto, a propriedade
muted
não é definida na ocorrência de Microphone até que StatusEvent tenha sido despachado, de modo que seu aplicativo também deve esperar até o evento
StatusEvent.STATUS
ser despachado antes de verificar a propriedade
Microphone.muted
.
Para que o Flash Player exiba a caixa de diálogo de configurações, a janela de aplicativo precisa ser grande o suficiente para exibi-la (pelo menos 215 x 138 pixels). Caso contrário, o acesso é negado automaticamente.
O conteúdo em execução na caixa de proteção do aplicativo do AIR não precisa da permissão do usuário para acessar o microfone. Assim, eventos de status para ligar e desligar o som do microfone nunca são despachados. O conteúdo em execução no AIR fora da caixa de proteção do aplicativo requer a permissão do usuário, de modo que esses eventos de status podem ser despachados.
Roteamento de áudio do microfone para alto-falantes locais
A entrada de áudio de um microfone pode ser roteada para os alto-falantes do sistema local chamando o método
Microphone.setLoopback()
com um valor de parâmetro de
true
.
Quando o som de um microfone local é roteado para alto-falantes locais, há um risco de criar um loop de feedback de áudio, o que pode provocar sons estridentes e danificar o hardware de som. A chamada do método
Microphone.setUseEchoSuppression()
com um valor de parâmetro
true
reduz, mas não elimina completamente, o risco de ocorrência de feedback de áudio. A Adobe recomenda sempre chamar
Microphone.setUseEchoSuppression(true)
antes de chamar
Microphone.setLoopback(true)
, a menos que você tenha certeza de que o usuário esteja reproduzindo o som usando fones de ouvido ou outra coisa que não seja um alto-falante.
O código a seguir mostra como rotear o áudio de um microfone local para os alto-falantes do sistema local:
var mic:Microphone = Microphone.getMicrophone();
mic.setUseEchoSuppression(true);
mic.setLoopBack(true);
Alteração do áudio do microfone
O aplicativo pode alterar os dados de áudio de um microfone de duas maneiras. Primeiro, ele pode alterar o ganho do som de entrada, o que efetivamente multiplica os valores de entrada por um valor especificado para criar um som mais baixo ou mais silencioso. A propriedade
Microphone.gain
aceita valores numéricos entre 0 e 100 inclusive. Um valor de 50 funciona como um multiplicador de um e especifica o volume normal. Um valor de zero funciona como um multiplicador de zero e silencia efetivamente o áudio de entrada. Valores acima de 50 especificam um volume mais alto do que o normal.
O aplicativo também pode alterar a taxa de amostragem do áudio de entrada. Taxas de amostragem mais altas aumentam a qualidade do som, mas elas também criam fluxos de dados mais densos que usam mais recursos para transmissão e armazenamento. A propriedade
Microphone.rate
representa a taxa de amostragem de áudio medida em quilohertz (kHz). A taxa de amostragem padrão é de 8 kHz. É possível definir a propriedade
Microphone.rate
como um valor mais alto do que 8 kHz se o microfone oferecer suporte à taxa mais alta. Por exemplo, configurar a propriedade
Microphone.rate
com um valor de 11 define a taxa de amostragem como 11 kHz. Configurá-la como 22 define a taxa de amostragem como 22 kHz e assim por diante. As taxas de amostra disponíveis dependem do codec selecionado. Quando você usa o codec Nellymoser, pode especificar 5, 8, 11, 16, 22 e 44 kHz como taxa de amostra. Quando você usa o codec Speex (disponível a partir do Flash Player 10 e do Adobe AIR 1.5), só pode usar 16 kHz.
Detecção de atividade do microfone
Para conservar a largura de banda e os recursos de processamento, o Flash Player tenta detectar quando nenhum som está sendo transmitido por um microfone. Quando o nível de atividade do microfone permanece abaixo do limite do nível de silêncio por um certo período, o Flash Player para de transmitir a entrada de áudio e despacha um simples ActivityEvent. Se você usar o codec Speex (disponível no Flash Player 10 ou em versões posteriores e no Adobe AIR 1.5 ou em versões posteriores), defina o nível de silêncio como 0 para assegurar que o aplicativo transmitirá dados de áudio continuamente. A detecção da atividade de voz do Speex automaticamente reduz a largura de banda.
Nota:
Um objeto Microphone despacha eventos Activity somente quando o aplicativo estiver monitorando o microfone. Assim, se você não chamar
setLoopBack( true )
, adicione um ouvinte para eventos de amostra de dados, ou anexe o microfone a um objeto NetStream e, em seguida, nenhum evento activity será despachado.
Três propriedades da classe Microphone monitoram e controlam a detecção de atividade:
-
A propriedade somente leitura
activityLevel
indica a quantidade de som que o microfone está detectando em uma escala de 0 a 100.
-
A propriedade
silenceLevel
especifica a quantidade de som necessária para ativar o microfone e despachar um evento
ActivityEvent.ACTIVITY
. A propriedade
silenceLevel
também usa uma escala de 0 a 100, e o valor padrão é 10.
-
A propriedade
silenceTimeout
descreve o número de milissegundos que o nível de atividade deve permanecer abaixo do nível de silêncio, até que um evento
ActivityEvent.ACTIVITY
seja despachado para indicar que o microfone está silencioso. O valor padrão de
silenceTimeout
é 2000.
As propriedades
Microphone.silenceLevel
e
Microphone.silenceTimeout
são somente leitura, mas seus valores podem ser alterados usando o método
Microphone.setSilenceLevel()
.
Em alguns casos, o processo de ativação do microfone quando nova atividade é detectada pode provocar um pequeno atraso. Manter o microfone ativo durante todo o tempo pode remover esses atrasos na ativação. O aplicativo pode chamar o método
Microphone.setSilenceLevel()
com o parâmetro
silenceLevel
definido como zero para indicar ao Flash Player para manter o microfone ativo e continuar a coletar dados de áudio, mesmo quando nenhum som está sendo detectado. De modo oposto, a configuração do parâmetro
silenceLevel
como 100 impede que o microfone seja ativado de qualquer modo.
O exemplo a seguir exibe informações sobre o microfone e relata eventos de atividade e eventos de status despachados por um objeto Microphone:
import flash.events.ActivityEvent;
import flash.events.StatusEvent;
import flash.media.Microphone;
var deviceArray:Array = Microphone.names;
trace("Available sound input devices:");
for (var i:int = 0; i < deviceArray.length; i++)
{
trace(" " + deviceArray[i]);
}
var mic:Microphone = Microphone.getMicrophone();
mic.gain = 60;
mic.rate = 11;
mic.setUseEchoSuppression(true);
mic.setLoopBack(true);
mic.setSilenceLevel(5, 1000);
mic.addEventListener(ActivityEvent.ACTIVITY, this.onMicActivity);
mic.addEventListener(StatusEvent.STATUS, this.onMicStatus);
var micDetails:String = "Sound input device name: " + mic.name + '\n';
micDetails += "Gain: " + mic.gain + '\n';
micDetails += "Rate: " + mic.rate + " kHz" + '\n';
micDetails += "Muted: " + mic.muted + '\n';
micDetails += "Silence level: " + mic.silenceLevel + '\n';
micDetails += "Silence timeout: " + mic.silenceTimeout + '\n';
micDetails += "Echo suppression: " + mic.useEchoSuppression + '\n';
trace(micDetails);
function onMicActivity(event:ActivityEvent):void
{
trace("activating=" + event.activating + ", activityLevel=" +
mic.activityLevel);
}
function onMicStatus(event:StatusEvent):void
{
trace("status: level=" + event.level + ", code=" + event.code);
}
Ao executar o exemplo acima, fale ou faça ruídos no microfone do sistema e observe as instruções de rastreamento resultantes serem exibidas em um console ou janela de depuração.
Envio e recebimento de áudio de um servidor de mídia
Recursos adicionais de áudio também estão disponíveis ao usar o ActionScript com um servidor de mídia de fluxo contínuo, como o Flash Media Server.
Em particular, seu aplicativo pode conectar um objeto Microphone a um objeto NetStream e transmitir dados diretamente do microfone do usuário para o servidor. Os dados de áudio também podem ser transmitidos do servidor para um aplicativo e reproduzidos como parte de um MovieClip ou usando um objeto Video.
O suporte para o codec Speex foi disponibilizado a partir do Flash Player 10 e do Adobe AIR 1.5. Para definir o codec usado para áudio compactado enviado ao servidor de mídia, defina a propriedade
codec
do objeto Microphone. Esta propriedade pode ter dois valores, que são enumerados na classe SoundCodec. Definir a propriedade do codec como
SoundCodec.SPEEX
seleciona o codec Speex para compactação de áudio. Definir a propriedade como
SoundCodec.NELLYMOSER
(o padrão) seleciona o codec Nellymoser para compactação de áudio.
Para obter mais informações, consulte a documentação on-line do Flash Media Server em
www.adobe.com/go/learn_fms_docs_br
.
Captura dos dados de som do microfone
No Flash Player 10.1 e no AIR 2 ou posteriores, você pode capturar os dados de um microfone, como uma matriz de bytes dos valores de ponto flutuantes. Cada valor representa uma amostragem dos dados de áudio monofônicos.
Para obter dados de microfone, defina um ouvinte de evento para o evento
sampleData
do objeto Microphone. O objeto Microphone despacha os eventos
sampleData
periodicamente à medida que o buffer do microfone é preenchido com amostragens de som. O objeto SampleDataEvent tem uma propriedade
data
que é uma matriz de bytes das amostragens de som. As amostras são representadas como valores de ponto flutuantes, cada uma representando uma amostragem de som monofônico.
O código a seguir captura os dados de som do microfone em um objeto ByteArray chamado
soundBytes
:
var mic:Microphone = Microphone.getMicrophone();
mic.setSilenceLevel(0, DELAY_LENGTH);
mic.addEventListener(SampleDataEvent.SAMPLE_DATA, micSampleDataHandler);
function micSampleDataHandler(event:SampleDataEvent):void {
while(event.data.bytesAvailable) {
var sample:Number = event.data.readFloat();
soundBytes.writeFloat(sample);
}
}
Você pode reutilizar os bytes de amostra como áudio de reprodução para um objeto Sound. Se fizer isso, defina a propriedade
rate
do objeto Microphone como 44, que é a taxa de amostragem usada pelos objetos Sound. (Você também pode converter as amostragens de microfone capturadas a uma taxa inferior a 44 kHz que é exigida pelo objeto Sound.) Além disso, tenha em mente que o objeto Microphone captura as as amostragens monofônicas, ao passo que o objeto Sound usa som estéreo. Por isso, escreva cada um dos bytes capturados pelo objeto Microphone no objeto Sound duas vezes. O exemplo a seguir captura quatro segundos de dados do microfone e o reproduz novamente usando um objeto Sound:
const DELAY_LENGTH:int = 4000;
var mic:Microphone = Microphone.getMicrophone();
mic.setSilenceLevel(0, DELAY_LENGTH);
mic.gain = 100;
mic.rate = 44;
mic.addEventListener(SampleDataEvent.SAMPLE_DATA, micSampleDataHandler);
var timer:Timer = new Timer(DELAY_LENGTH);
timer.addEventListener(TimerEvent.TIMER, timerHandler);
timer.start();
function micSampleDataHandler(event:SampleDataEvent):void
{
while(event.data.bytesAvailable)
{
var sample:Number = event.data.readFloat();
soundBytes.writeFloat(sample);
}
}
var sound:Sound = new Sound();
var channel:SoundChannel;
function timerHandler(event:TimerEvent):void
{
mic.removeEventListener(SampleDataEvent.SAMPLE_DATA, micSampleDataHandler);
timer.stop();
soundBytes.position = 0;
sound.addEventListener(SampleDataEvent.SAMPLE_DATA, playbackSampleHandler);
channel.addEventListener( Event.SOUND_COMPLETE, playbackComplete );
channel = sound.play();
}
function playbackSampleHandler(event:SampleDataEvent):void
{
for (var i:int = 0; i < 8192 && soundBytes.bytesAvailable > 0; i++)
{
trace(sample);
var sample:Number = soundBytes.readFloat();
event.data.writeFloat(sample);
event.data.writeFloat(sample);
}
}
function playbackComplete( event:Event ):void
{
trace( "Playback finished.");
}
Para obter mais informações sobre os sons de reprodução dos dados de amostragem do som, consulte
Trabalho com áudio gerado dinamicamente
.
|
|
|
|
|