Android Audio

El sistema operativo Android proporciona una amplia compatibilidad con multimedia, que abarca tanto audio como vídeo. Esta guía se centra en el audio en Android y cubre la reproducción y grabación de audio mediante las clases integradas de reproductor de audio y grabadora, así como la API de audio de bajo nivel. También trata sobre cómo trabajar con eventos de audio transmitidos por otras aplicaciones, de modo que los desarrolladores puedan compilar aplicaciones de buen comportamiento.

Información general

Los dispositivos móviles modernos han adoptado la funcionalidad que anteriormente habría requerido piezas dedicadas de equipo: cámaras, reproductores de música y grabadoras de vídeo. Por este motivo, los marcos multimedia se han convertido en una característica de primera clase en las API móviles.

Android proporciona una amplia compatibilidad con multimedia. En este artículo se examina cómo trabajar con audio en Android y se tratan los temas siguientes.

  1. Reproducir audio con MediaPlayer : usa la clase integrada MediaPlayer para reproducir audio, incluidos los archivos de audio locales y los archivos de audio transmitidos con la AudioTrack clase .

  2. Grabación de audio : usa la clase integrada MediaRecorder para grabar audio.

  3. Trabajar con notificaciones de audio : el uso de notificaciones de audio para crear aplicaciones con buen comportamiento que respondan correctamente a eventos (como llamadas telefónicas entrantes) suspendiendo o cancelando sus salidas de audio.

  4. Trabajar con Low-Level Audio : reproducir audio mediante la AudioTrack clase escribiendo directamente en búferes de memoria. Grabación de audio mediante la AudioRecord clase y lectura directamente desde búferes de memoria.

Requisitos

Esta guía requiere Android 2.0 (nivel de API 5) o superior. Tenga en cuenta que la depuración de audio en Android debe realizarse en un dispositivo.

Es necesario solicitar los RECORD_AUDIO permisos en AndroidManifest.XML:

Sección permisos necesarios del manifiesto de Android con RECORD_AUDIO habilitado

Reproducir audio con la clase MediaPlayer

La manera más sencilla de reproducir audio en Android es con la clase MediaPlayer integrada. MediaPlayer puede reproducir archivos locales o remotos pasando la ruta de acceso del archivo. Sin embargo, MediaPlayer es muy sensible al estado y llamar a uno de sus métodos en estado incorrecto hará que se produzca una excepción. Es importante interactuar con MediaPlayer en el orden descrito a continuación para evitar errores.

Inicialización y reproducción

La reproducción de audio con MediaPlayer requiere la siguiente secuencia:

  1. Cree una instancia de un nuevo objeto MediaPlayer .

  2. Configure el archivo para que se reproduzca a través del método SetDataSource .

  3. Llame al método Prepare para inicializar el reproductor.

  4. Llame al método Start para iniciar la reproducción de audio.

En el ejemplo de código siguiente se muestra este 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();
  }
}

Suspender y reanudar la reproducción

La reproducción se puede suspender llamando al método Pause :

player.Pause();

Para reanudar la reproducción en pausa, llame al método Start . Esto se reanudará desde la ubicación en pausa en la reproducción:

player.Start();

Llamar al método Stop en el reproductor finaliza una reproducción en curso:

player.Stop();

Cuando el reproductor ya no es necesario, los recursos se deben liberar llamando al método Release :

player.Release();

Usar la clase MediaRecorder para grabar audio

La corolario a MediaPlayer para grabar audio en Android es la clase MediaRecorder . MediaPlayerAl igual que , es sensible al estado y pasa a través de varios estados para llegar al punto donde puede empezar a grabar. Para grabar audio, se debe establecer el RECORD_AUDIO permiso. Para obtener instrucciones sobre cómo establecer permisos de aplicación, consulte Trabajar con AndroidManifest.xml.

Inicialización y grabación

La grabación de audio con MediaRecorder requiere los pasos siguientes:

  1. Cree una instancia de un nuevo objeto MediaRecorder .

  2. Especifique qué dispositivo de hardware se va a usar para capturar la entrada de audio mediante el método SetAudioSource .

  3. Establezca el formato de audio del archivo de salida mediante el método SetOutputFormat . Para obtener una lista de los tipos de audio admitidos, consulte Formatos multimedia compatibles con Android.

  4. Llame al método SetAudioEncoder para establecer el tipo de codificación de audio.

  5. Llame al método SetOutputFile para especificar el nombre del archivo de salida en el que se escriben los datos de audio.

  6. Llame al método Prepare para inicializar la grabadora.

  7. Llame al método Start para iniciar la grabación.

En el ejemplo de código siguiente se muestra esta secuencia:

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);
  }
}

Detener la grabación

Para detener la grabación, llame al Stop método en :MediaRecorder

recorder.Stop();

Limpiar

MediaRecorder Una vez detenido, llame al método Reset para volver a colocarlo en su estado inactivo:

recorder.Reset();

MediaRecorder Cuando ya no se necesita , sus recursos se deben liberar llamando al método Release:

recorder.Release();

Administración de notificaciones de audio

Clase AudioManager

La clase AudioManager proporciona acceso a las notificaciones de audio que permiten a las aplicaciones saber cuándo se producen los eventos de audio. Este servicio también proporciona acceso a otras características de audio, como el control de modo de volumen y timbre. AudioManager Permite que una aplicación controle las notificaciones de audio para controlar la reproducción de audio.

Administración del foco de audio

Todos los recursos de audio del dispositivo (el reproductor y la grabadora integrados) se comparten mediante todas las aplicaciones en ejecución.

Conceptualmente, esto es similar a las aplicaciones de un equipo de escritorio donde solo una aplicación tiene el foco de teclado: después de seleccionar una de las aplicaciones en ejecución haciendo clic con el mouse en ella, la entrada del teclado solo va a esa aplicación.

El foco de audio es una idea similar y evita que más de una aplicación se reenfoque o grabe audio al mismo tiempo. Es más complicado que el foco del teclado porque es voluntario: la aplicación puede ignorar ese hecho de que actualmente no tiene el foco de audio y se reproduce independientemente, y porque hay diferentes tipos de foco de audio que se pueden solicitar. Por ejemplo, si solo se espera que el solicitante reproduzca audio durante un tiempo muy corto, puede solicitar el foco transitorio.

El foco de audio se puede conceder inmediatamente, o inicialmente denegado y concedido posteriormente. Por ejemplo, si una aplicación solicita el foco de audio durante una llamada telefónica, se denegará, pero el foco puede concederse bien una vez finalizada la llamada telefónica. En este caso, se registra un agente de escucha para responder en consecuencia si se quita el foco de audio. La solicitud de foco de audio se usa para determinar si es correcto reproducir o grabar audio.

Para obtener más información sobre el foco de audio, consulte Administración del foco de audio.

Registro de la devolución de llamada para el foco de audio

Registrar la FocusChangeListener devolución de llamada desde IOnAudioChangeListener es una parte importante de la obtención y liberación del foco de audio. Esto se debe a que la concesión del foco de audio se puede aplazar hasta un momento posterior. Por ejemplo, una aplicación puede solicitar reproducir música mientras hay una llamada telefónica en curso. El foco de audio no se concederá hasta que finalice la llamada telefónica.

Por este motivo, el objeto de devolución de llamada se pasa como un parámetro al GetAudioFocus método de AudioManagery es esta llamada que registra la devolución de llamada. Si el foco de audio se deniega inicialmente pero se concede más adelante, se informa a la aplicación invocando OnAudioFocusChange en la devolución de llamada. El mismo método se usa para indicar a la aplicación que se está quitando el foco de audio.

Cuando la aplicación ha terminado de usar los recursos de audio, llama al AbandonFocus método de AudioManagery vuelve a pasar en la devolución de llamada. Esto anula el registro de la devolución de llamada y libera los recursos de audio para que otras aplicaciones puedan obtener el foco de audio.

Solicitud de foco de audio

Los pasos necesarios para solicitar los recursos de audio del dispositivo son los siguientes:

  1. Obtenga un identificador para el servicio del AudioManager sistema.

  2. Cree una instancia de la clase de devolución de llamada.

  3. Solicite los recursos de audio del dispositivo mediante una llamada al RequestAudioFocus método en .AudioManager Los parámetros son el objeto de devolución de llamada, el tipo de secuencia (música, llamada de voz, anillo, etc.) y el tipo del derecho de acceso que se solicita (los recursos de audio se pueden solicitar momentáneamente o durante un período indefinido, por ejemplo).

  4. Si se concede la solicitud, el playMusic método se invoca inmediatamente y el audio comienza a reproducirse.

  5. Si se deniega la solicitud, no se realiza ninguna otra acción. En este caso, el audio solo se reproducirá si la solicitud se concede más adelante.

En el ejemplo de código siguiente se muestran estos pasos:

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);
}

Liberación del foco de audio

Una vez completada la reproducción de la pista, se invoca el AbandonFocus método en AudioManager . Esto permite que otra aplicación obtenga los recursos de audio del dispositivo. Otras aplicaciones recibirán una notificación de este cambio de foco de audio si han registrado sus propios agentes de escucha.

API de audio de bajo nivel

Las API de audio de bajo nivel proporcionan un mayor control sobre la reproducción y grabación de audio porque interactúan directamente con búferes de memoria en lugar de usar URI de archivo. Hay algunos escenarios en los que este enfoque es preferible. Entre los escenarios se incluyen los siguientes:

  1. Al reproducir archivos de audio cifrados.

  2. Cuando se reproduce una sucesión de clips cortos.

  3. Streaming de audio.

Clase AudioTrack

La clase AudioTrack usa las API de audio de bajo nivel para la grabación y es el equivalente de bajo nivel de la MediaPlayer clase .

Inicialización y reproducción

Para reproducir audio, se debe crear una nueva instancia de AudioTrack . La lista de argumentos pasada al constructor especifica cómo reproducir la muestra de audio contenida en el búfer. Los argumentos son:

  1. Tipo de secuencia: voz, tono, música, sistema o alarma.

  2. Frecuencia: la frecuencia de muestreo expresada en Hz.

  3. Configuración del canal: Mono o estéreo.

  4. Formato de audio: codificación de 8 o 16 bits.

  5. Tamaño del búfer: en bytes.

  6. Modo de búfer: streaming o estático.

Después de la construcción, se invoca el método Play de AudioTrack para configurarlo para empezar a reproducirse. Al escribir el búfer de audio en se AudioTrack inicia la reproducción:

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);
}

Pausar y detener la reproducción

Llame al método Pause para pausar la reproducción:

audioTrack.Pause();

Llamar al método Stop finalizará la reproducción de forma permanente:

audioTrack.Stop();

Limpieza

AudioTrack Cuando ya no es necesario, sus recursos deben liberarse llamando a Release:

audioTrack.Release();

Clase AudioRecord

La clase AudioRecord es el equivalente de en el lado de AudioTrack grabación. Al igual AudioTrackque , usa búferes de memoria directamente, en lugar de archivos y URI. Requiere que el RECORD_AUDIO permiso se establezca en el manifiesto.

Inicialización y grabación

El primer paso es construir un nuevo objeto AudioRecord . La lista de argumentos pasada al constructor proporciona toda la información necesaria para la grabación. A diferencia de en AudioTrack, donde los argumentos son en gran medida enumeraciones, los argumentos equivalentes de AudioRecord son enteros. Entre ellas se incluyen las siguientes:

  1. Origen de entrada de audio de hardware, como micrófono.

  2. Tipo de secuencia: voz, tono, música, sistema o alarma.

  3. Frecuencia: la frecuencia de muestreo expresada en Hz.

  4. Configuración del canal: Mono o estéreo.

  5. Formato de audio: codificación de 8 o 16 bits.

  6. Bytes de tamaño de búfer

Una vez construido , AudioRecord se invoca su método StartRecording . Ahora está listo para comenzar la grabación. Lee AudioRecord continuamente el búfer de audio para la entrada y escribe esta entrada en un archivo de audio.

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;
    }
  }
}

Detener la grabación

Al llamar al método Stop , finaliza la grabación:

audRecorder.Stop();

Limpieza

Cuando el AudioRecord objeto ya no es necesario, al llamar a su método Release se liberan todos los recursos asociados:

audRecorder.Release();

Resumen

El sistema operativo Android proporciona un marco eficaz para reproducir, grabar y administrar audio. En este artículo se explica cómo reproducir y grabar audio mediante las clases y MediaRecorder de alto nivelMediaPlayer. A continuación, ha explorado cómo usar notificaciones de audio para compartir los recursos de audio del dispositivo entre diferentes aplicaciones. Por último, se ha tratado cómo reproducir y grabar audio mediante las API de bajo nivel, que interactúan directamente con búferes de memoria.