Áudio Android
O sistema operacional Android fornece amplo suporte para multimídia, abrangendo áudio e vídeo. Este guia se concentra no áudio no Android e abrange a reprodução e gravação de áudio usando as classes de reprodutor e gravador de áudio integrados, bem como a API de áudio de baixo nível. Ele também abrange o trabalho com eventos de áudio transmitidos por outros aplicativos, para que os desenvolvedores possam criar aplicativos bem comportados.
Visão geral
Os dispositivos móveis modernos adotaram funcionalidades que anteriormente exigiam equipamentos dedicados – câmeras, tocadores de música e gravadores de vídeo. Por causa disso, as estruturas multimídia se tornaram um recurso de primeira classe em APIs móveis.
O Android fornece suporte extensivo para multimídia. Este artigo examina o trabalho com áudio no Android e aborda os seguintes tópicos
Reproduzir áudio com o MediaPlayer – Usando a classe integrada para reproduzir áudio, incluindo arquivos de
MediaPlayer
áudio locais e arquivos de áudio transmitidos com aAudioTrack
classe.Gravação de
MediaRecorder
áudio – Usando a classe integrada para gravar áudio.Trabalhando com notificações de áudio – Usando notificações de áudio para criar aplicativos bem comportados que respondem corretamente a eventos (como chamadas telefônicas recebidas) suspendendo ou cancelando suas saídas de áudio.
Trabalhando com áudio de baixo nível – Reproduzir áudio usando a
AudioTrack
classe gravando diretamente em buffers de memória. Gravação de áudio usando aAudioRecord
classe e leitura diretamente de buffers de memória.
Requisitos
Este guia requer o Android 2.0 (API nível 5) ou superior. Observe que a depuração de áudio no Android deve ser feita em um dispositivo.
É necessário solicitar as RECORD_AUDIO
permissões em AndroidManifest.XML:
Reproduzir áudio com a classe MediaPlayer
A maneira mais simples de reproduzir áudio no Android é com a classe MediaPlayer integrada.
MediaPlayer
pode reproduzir arquivos locais ou remotos passando o caminho do arquivo. No entanto, MediaPlayer
é muito sensível ao estado e chamar um de seus métodos no estado errado fará com que uma exceção seja lançada. É importante interagir com MediaPlayer
na ordem descrita abaixo para evitar erros.
Inicializando e reproduzindo
A reprodução de áudio com MediaPlayer
requer a seguinte sequência:
Instancie um novo objeto MediaPlayer .
Configure o arquivo para ser reproduzido por meio do método SetDataSource .
Chame o método Prepare para inicializar o player.
Chame o método Start para iniciar a reprodução de áudio.
O exemplo de código abaixo ilustra esse uso:
protected MediaPlayer player;
public void StartPlayer(String filePath)
{
if (player == null) {
player = new MediaPlayer();
} else {
player.Reset();
player.SetDataSource(filePath);
player.Prepare();
player.Start();
}
}
Suspendendo e retomando a reprodução
A reprodução pode ser suspensa chamando o método Pause :
player.Pause();
Para retomar a reprodução pausada, chame o método Start . Isso será retomado a partir do local pausado na reprodução:
player.Start();
Chamar o método Stop no player encerra uma reprodução contínua:
player.Stop();
Quando o player não for mais necessário, os recursos devem ser liberados chamando o método Release :
player.Release();
Usando a classe MediaRecorder para gravar áudio
O corolário para MediaPlayer
a gravação de áudio no Android é a classe MediaRecorder . Como o MediaPlayer
, ele é sensível ao estado e faz transições por vários estados para chegar ao ponto em que pode começar a gravar. Para gravar áudio, a RECORD_AUDIO
permissão deve ser definida. Para obter instruções sobre como definir permissões de aplicativo, consulte Trabalhando com AndroidManifest.xml.
Inicializando e gravando
A gravação de áudio com o MediaRecorder
requer os seguintes passos:
Instancie um novo objeto MediaRecorder .
Especifique qual dispositivo de hardware usar para capturar a entrada de áudio por meio do método SetAudioSource .
Defina o formato de áudio do arquivo de saída usando o método SetOutputFormat . Para obter uma lista dos tipos de áudio suportados, consulte Formatos de mídia suportados pelo Android.
Chame o método SetAudioEncoder para definir o tipo de codificação de áudio.
Chame o método SetOutputFile para especificar o nome do arquivo de saída no qual os dados de áudio são gravados.
Chame o método Prepare para inicializar o gravador.
Chame o método Start para iniciar a gravação.
O exemplo de código a seguir ilustra essa sequência:
protected MediaRecorder recorder;
void RecordAudio (String filePath)
{
try {
if (File.Exists (filePath)) {
File.Delete (filePath);
}
if (recorder == null) {
recorder = new MediaRecorder (); // Initial state.
} else {
recorder.Reset ();
recorder.SetAudioSource (AudioSource.Mic);
recorder.SetOutputFormat (OutputFormat.ThreeGpp);
recorder.SetAudioEncoder (AudioEncoder.AmrNb);
// Initialized state.
recorder.SetOutputFile (filePath);
// DataSourceConfigured state.
recorder.Prepare (); // Prepared state
recorder.Start (); // Recording state.
}
} catch (Exception ex) {
Console.Out.WriteLine( ex.StackTrace);
}
}
Interrompendo a gravação
Para interromper a gravação, chame MediaRecorder
o Stop
método no :
recorder.Stop();
Limpeza
Depois que o MediaRecorder
tiver sido interrompido, chame o método Reset para colocá-lo novamente em seu estado ocioso:
recorder.Reset();
Quando o MediaRecorder
não é mais necessário, seus recursos devem ser liberados chamando o método Release :
recorder.Release();
Gerenciando notificações de áudio
A classe AudioManager
A classe AudioManager fornece acesso a notificações de áudio que permitem que os aplicativos saibam quando eventos de áudio ocorrem. Esse serviço também fornece acesso a outros recursos de áudio, como controle de volume e modo de campainha. O AudioManager
permite que um aplicativo manipule notificações de áudio para controlar a reprodução de áudio.
Gerenciando o foco de áudio
Os recursos de áudio do dispositivo (o player e gravador integrados) são compartilhados por todos os aplicativos em execução.
Conceitualmente, isso é semelhante aos aplicativos em um computador desktop onde apenas um aplicativo tem o foco do teclado: depois de selecionar um dos aplicativos em execução clicando nele com o mouse, a entrada do teclado vai apenas para esse aplicativo.
O foco de áudio é uma ideia semelhante e impede que mais de um aplicativo reproduza ou grave áudio ao mesmo tempo. É mais complicado do que o foco do teclado porque é voluntário – o aplicativo pode ignorar o fato de que atualmente não tem foco de áudio e reprodução independentemente – e porque existem diferentes tipos de foco de áudio que podem ser solicitados. Por exemplo, se for esperado que o solicitante reproduza apenas áudio por um tempo muito curto, ele poderá solicitar foco transitório.
O foco de áudio pode ser concedido imediatamente ou inicialmente negado e concedido posteriormente. Por exemplo, se um aplicativo solicitar foco de áudio durante uma chamada telefônica, ele será negado, mas o foco pode ser concedido assim que a chamada telefônica for concluída. Nesse caso, um ouvinte é registrado para responder de acordo se o foco do áudio for retirado. A solicitação de foco de áudio é usada para determinar se não há problema em reproduzir ou gravar áudio.
Para obter mais informações sobre foco de áudio, consulte Gerenciando foco de áudio.
Registrando o retorno de chamada para foco de áudio
Registrar o FocusChangeListener
retorno de chamada do IOnAudioChangeListener
é uma parte importante da obtenção e liberação do foco de áudio. Isso porque a concessão do foco de áudio pode ser adiada para um momento posterior. Por exemplo, um aplicativo pode solicitar a reprodução de música enquanto há uma chamada telefônica em andamento. O foco de áudio não será concedido até que a chamada telefônica seja concluída.
Por esse motivo, o objeto de retorno de chamada é passado como um parâmetro para o GetAudioFocus
método do , e é essa chamada que registra o retorno de AudioManager
chamada. Se o foco de áudio for inicialmente negado, mas posteriormente concedido, o aplicativo será informado invocando o retorno de OnAudioFocusChange
chamada. O mesmo método é usado para dizer ao aplicativo que o foco de áudio está sendo retirado.
Quando o aplicativo terminar de usar os recursos de áudio, ele chama o AbandonFocus
método do , e passa novamente no retorno de AudioManager
chamada. Isso cancela o registro do retorno de chamada e libera os recursos de áudio, para que outros aplicativos possam obter o foco de áudio.
Solicitando foco de áudio
As etapas necessárias para solicitar os recursos de áudio do dispositivo são as seguintes:
Obtenha um identificador para o serviço do
AudioManager
sistema.Crie uma instância da classe de retorno de chamada.
Solicite os recursos de áudio do dispositivo chamando o
RequestAudioFocus
AudioManager
método no . Os parâmetros são o objeto de retorno de chamada, o tipo de fluxo (música, chamada de voz, toque etc.) e o tipo de direito de acesso que está sendo solicitado (os recursos de áudio podem ser solicitados momentaneamente ou por tempo indeterminado, por exemplo).Se a solicitação for concedida, o
playMusic
método será chamado imediatamente e o áudio começará a ser reproduzido.Se a solicitação for negada, nenhuma outra ação será tomada. Nesse caso, o áudio só será reproduzido se a solicitação for concedida posteriormente.
O exemplo de código abaixo mostra estas etapas:
Boolean RequestAudioResources(INotificationReceiver parent)
{
AudioManager audioMan = (AudioManager) GetSystemService(Context.AudioService);
AudioManager.IOnAudioFocusChangeListener listener = new MyAudioListener(this);
var ret = audioMan.RequestAudioFocus (listener, Stream.Music, AudioFocus.Gain );
if (ret == AudioFocusRequest.Granted) {
playMusic();
return (true);
} else if (ret == AudioFocusRequest.Failed) {
return (false);
}
return (false);
}
Liberando o foco de áudio
Quando a reprodução da faixa estiver concluída, o método ativado AbandonFocus
AudioManager
será chamado. Isso permite que outro aplicativo ganhe os recursos de áudio do dispositivo. Outros aplicativos receberão uma notificação dessa mudança de foco de áudio se tiverem registrado seus próprios ouvintes.
API de áudio de baixo nível
As APIs de áudio de baixo nível fornecem um maior controle sobre a reprodução e gravação de áudio porque interagem diretamente com buffers de memória em vez de usar URIs de arquivo. Existem alguns cenários em que essa abordagem é preferível. Esses cenários incluem:
Ao reproduzir a partir de arquivos de áudio criptografados.
Ao reproduzir uma sucessão de clipes curtos.
Streaming de áudio.
AudioTrack Classe
A classe AudioTrack usa as APIs de áudio de baixo nível para gravação e é o equivalente de baixo nível da MediaPlayer
classe.
Inicializando e reproduzindo
Para reproduzir áudio, uma nova instância de AudioTrack
deve ser instanciada. A lista de argumentos passada para o construtor especifica como reproduzir a amostra de áudio contida no buffer. Os argumentos são:
Tipo de fluxo – Voz, toque, música, sistema ou alarme.
Frequência – A taxa de amostragem expressa em Hz.
Configuração de canal – Mono ou estéreo.
Formato de áudio – codificação de 8 bits ou 16 bits.
Tamanho do buffer – em bytes.
Modo buffer – streaming ou estático.
Após a construção, o método Play de AudioTrack
é invocado, para configurá-lo para começar a jogar. Gravando o buffer de áudio no AudioTrack
inicia a reprodução:
void PlayAudioTrack(byte[] audioBuffer)
{
AudioTrack audioTrack = new AudioTrack(
// Stream type
Stream.Music,
// Frequency
11025,
// Mono or stereo
ChannelOut.Mono,
// Audio encoding
Android.Media.Encoding.Pcm16bit,
// Length of the audio clip.
audioBuffer.Length,
// Mode. Stream or static.
AudioTrackMode.Stream);
audioTrack.Play();
audioTrack.Write(audioBuffer, 0, audioBuffer.Length);
}
Pausando e interrompendo a reprodução
Chame o método Pause para pausar a reprodução:
audioTrack.Pause();
Chamar o método Stop encerrará a reprodução permanentemente:
audioTrack.Stop();
Limpeza
Quando o AudioTrack
não é mais necessário, seus recursos devem ser liberados chamando Release:
audioTrack.Release();
A classe AudioRecord
A classe AudioRecord é o equivalente de no lado da AudioTrack
gravação. Como AudioTrack
, ele usa buffers de memória diretamente, no lugar de arquivos e URIs. Ele requer que a RECORD_AUDIO
permissão seja definida no manifesto.
Inicializando e gravando
A primeira etapa é construir um novo objeto AudioRecord . A lista de argumentos passada para o construtor fornece todas as informações necessárias para a gravação. Ao contrário do , AudioTrack
onde os argumentos são em grande parte enumerações, os argumentos equivalentes em AudioRecord
são inteiros. Estão incluídos:
Fonte de entrada de áudio de hardware, como microfone.
Tipo de fluxo – Voz, toque, música, sistema ou alarme.
Frequência – A taxa de amostragem expressa em Hz.
Configuração de canal – Mono ou estéreo.
Formato de áudio – codificação de 8 bits ou 16 bits.
Tamanho do buffer em bytes
Depois que o AudioRecord
é construído, seu método StartRecording é chamado. Agora está pronto para começar a gravar. O AudioRecord
lê continuamente o buffer de áudio para entrada e grava essa entrada em um arquivo de áudio.
void RecordAudio()
{
byte[] audioBuffer = new byte[100000];
var audRecorder = new AudioRecord(
// Hardware source of recording.
AudioSource.Mic,
// Frequency
11025,
// Mono or stereo
ChannelIn.Mono,
// Audio encoding
Android.Media.Encoding.Pcm16bit,
// Length of the audio clip.
audioBuffer.Length
);
audRecorder.StartRecording();
while (true) {
try
{
// Keep reading the buffer while there is audio input.
audRecorder.Read(audioBuffer, 0, audioBuffer.Length);
// Write out the audio file.
} catch (Exception ex) {
Console.Out.WriteLine(ex.Message);
break;
}
}
}
Parando a gravação
Chamar o método Stop encerra a gravação:
audRecorder.Stop();
Limpeza
Quando o AudioRecord
objeto não é mais necessário, chamar seu método Release libera todos os recursos associados a ele:
audRecorder.Release();
Resumo
O sistema operacional Android fornece uma estrutura poderosa para reproduzir, gravar e gerenciar áudio. Este artigo abordou como reproduzir e gravar áudio usando o alto nível MediaPlayer
e MediaRecorder
classes. Em seguida, explorou como usar notificações de áudio para compartilhar os recursos de áudio do dispositivo entre diferentes aplicativos. Finalmente, tratou de como reproduzir e gravar áudio usando as APIs de baixo nível, que fazem interface diretamente com buffers de memória.