Á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

  1. Reproduzir áudio com o MediaPlayer – Usando a classe integrada para reproduzir áudio, incluindo arquivos de MediaPlayer áudio locais e arquivos de áudio transmitidos com a AudioTrack classe.

  2. Gravação de MediaRecorder áudio – Usando a classe integrada para gravar áudio.

  3. 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.

  4. 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 a AudioRecord 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:

Seção de permissões necessárias do Manifesto do Android com RECORD_AUDIO ativado

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:

  1. Instancie um novo objeto MediaPlayer .

  2. Configure o arquivo para ser reproduzido por meio do método SetDataSource .

  3. Chame o método Prepare para inicializar o player.

  4. 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:

  1. Instancie um novo objeto MediaRecorder .

  2. Especifique qual dispositivo de hardware usar para capturar a entrada de áudio por meio do método SetAudioSource .

  3. 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.

  4. Chame o método SetAudioEncoder para definir o tipo de codificação de áudio.

  5. Chame o método SetOutputFile para especificar o nome do arquivo de saída no qual os dados de áudio são gravados.

  6. Chame o método Prepare para inicializar o gravador.

  7. 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 MediaRecordero 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 AudioManagerchamada. 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 AudioManagerchamada. 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:

  1. Obtenha um identificador para o serviço do AudioManager sistema.

  2. Crie uma instância da classe de retorno de chamada.

  3. Solicite os recursos de áudio do dispositivo chamando o RequestAudioFocusAudioManager 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).

  4. Se a solicitação for concedida, o playMusic método será chamado imediatamente e o áudio começará a ser reproduzido.

  5. 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 AbandonFocusAudioManager 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:

  1. Ao reproduzir a partir de arquivos de áudio criptografados.

  2. Ao reproduzir uma sucessão de clipes curtos.

  3. 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:

  1. Tipo de fluxo – Voz, toque, música, sistema ou alarme.

  2. Frequência – A taxa de amostragem expressa em Hz.

  3. Configuração de canal – Mono ou estéreo.

  4. Formato de áudio – codificação de 8 bits ou 16 bits.

  5. Tamanho do buffer – em bytes.

  6. 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 , AudioTrackonde os argumentos são em grande parte enumerações, os argumentos equivalentes em AudioRecord são inteiros. Estão incluídos:

  1. Fonte de entrada de áudio de hardware, como microfone.

  2. Tipo de fluxo – Voz, toque, música, sistema ou alarme.

  3. Frequência – A taxa de amostragem expressa em Hz.

  4. Configuração de canal – Mono ou estéreo.

  5. Formato de áudio – codificação de 8 bits ou 16 bits.

  6. 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.