Compartir a través de


Android Audio

El sistema operativo Android proporciona una amplia compatibilidad con multimedia, 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 cómo trabajar con eventos de audio transmitidos por otras aplicaciones, de modo que los desarrolladores puedan crear aplicaciones de buen comportamiento.

Información general

Los dispositivos móviles modernos han adoptado las funcionalidades que anteriormente habría requerido piezas dedicadas de equipo: cámaras, reproductores de música y grabadoras de vídeo. Debido a ello, 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 analiza el trabajo con audio en Android y se tratan los siguientes temas

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

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

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

  4. Trabajar con audio de bajo nivel: reproducción de audio mediante la clase AudioTrack escribiendo directamente en búferes de memoria. Grabación de audio mediante la clase AudioRecord y leyendo 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 permisos RECORD_AUDIO en AndroidManifest.XML:

Sección de 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 el 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

Reproducir audio con MediaPlayer requiere la siguiente secuencia:

  1. Cree una instancia de un nuevo objeto MediaPlayer.

  2. Configure el archivo para reproducirlo mediante el 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 siguiente ejemplo de código 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. Se reanudará desde la ubicación de la 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 deben liberarse llamando al método Release:

player.Release();

Uso de la clase MediaRecorder para grabar audio

El resultado de MediaPlayer para grabar audio en Android es la clase MediaRecorder. Al igual que MediaPlayer, es sensible al estado y realiza transiciones a través de varios estados para llegar al punto en el que puede empezar a grabar. Para grabar audio, se debe establecer el permiso RECORD_AUDIO. Si desea 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 estos pasos:

  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 a través del método SetAudioSource.

  3. Establezca el formato de audio del archivo de salida mediante el método SetOutputFormat. Si desea 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 siguiente ejemplo de código se muestra la siguiente 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 método Stop en MediaRecorder:

recorder.Stop();

Limpieza

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

recorder.Reset();

Cuando MediaRecorder ya no sea necesario, sus recursos deben liberarse llamando al método Release:

recorder.Release();

Administración de notificaciones de audio

La clase AudioManager

La clase AudioManager proporciona acceso a las notificaciones de audio que permiten a las aplicaciones saber cuándo se producen 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 manipule 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 integrado y la grabadora) se comparten mediante todas las aplicaciones en ejecución.

Esto es similar conceptualmente 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, la entrada del teclado va solamente a esa aplicación.

El foco de audio es una idea similar e impide que más de una aplicación reproduzca 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 foco de audio y reproducir independientemente, y porque se pueden solicitar diferentes tipos de foco de audio. Por ejemplo, si solo se espera que el solicitante reproduzca audio de manera breve, puede solicitar el foco transitorio.

El foco de audio se puede conceder inmediatamente o denegarlo inicialmente y concederlo más adelante. Por ejemplo, si una aplicación solicita el foco de audio durante una llamada telefónica, se denegará, pero el foco puede concederse una vez finalizada la llamada telefónica. En ese caso, se registra un agente de escucha para responder adecuadamente si se quita el foco de audio. La solicitud de foco de audio se usa para determinar si es correcto o no reproducir o grabar audio.

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

Registro de devolución de llamadas para el foco de audio

Registrar la devolución de llamada FocusChangeListener 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 de foco de audio se puede aplazar para más adelante. Por ejemplo, una aplicación puede solicitar reproducir música durante una llamada telefónica en curso. El foco de audio no se concederá hasta que finalice esa llamada telefónica.

Por este motivo, el objeto de devolución de llamada se pasa como un parámetro al método GetAudioFocus de AudioManager y es esta llamada la que registra la devolución. 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 método AbandonFocus de AudioManager y vuelve a pasar 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 del foco de audio

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

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

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

  3. Solicite los recursos de audio del dispositivo llamando al método RequestAudioFocus en AudioManager. Los parámetros son el objeto de devolución de llamada, el tipo de secuencia (música, llamada de voz, tono, 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 método playMusic 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);
}

Liberar el foco de audio

Una vez completada la reproducción de la pista, se invoca el método AbandonFocus 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 identificadores URI de archivo. Hay algunos escenarios en los que este enfoque es preferible. Entre los escenarios se incluyen los siguientes:

  1. Al reproducir desde archivos de audio cifrados.

  2. Al reproducir 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 clase MediaPlayer.

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 transmisión: voz, tono de llamada, música, sistema o alarma.

  2. Frecuencia: frecuencia de muestreo expresada en Hz.

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

  4. Formato de audio: codificación en 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 y empezar a reproducirse. Escribir el búfer de audio en 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

Cuando AudioTrack 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 AudioTrack de la grabación. Al igual que AudioTrack, usa búferes de memoria directamente, en lugar de archivos e identificadores URI. Requiere que el permiso RECORD_AUDIO 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 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 transmisión: voz, tono de llamada, música, sistema o alarma.

  3. Frecuencia: frecuencia de muestreo expresada en Hz.

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

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

  6. Tamaño del búfer en bytes

Una vez construido AudioRecord, se invoca su método StartRecording. Ahora está listo para comenzar la grabación. AudioRecord lee 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

Llamar al método Stop finaliza la grabación:

audRecorder.Stop();

Limpieza

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

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 de alto nivel MediaPlayer y MediaRecorder. A continuación, explora 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 los búferes de memoria.