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
Reproducir audio con MediaPlayer: usa la clase integrada
MediaPlayer
para reproducir audio, incluidos los archivos de audio locales y los transmitidos con la claseAudioTrack
.Grabación de audio: uso de la clase integrada
MediaRecorder
para grabar audio.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.
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 claseAudioRecord
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:
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:
Cree una instancia de un nuevo objeto MediaPlayer.
Configure el archivo para reproducirlo mediante el método SetDataSource.
Llame al método Prepare para inicializar el reproductor.
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:
Cree una instancia de un nuevo objeto MediaRecorder.
Especifique qué dispositivo de hardware se va a usar para capturar la entrada de audio a través del método SetAudioSource.
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.
Llame al método SetAudioEncoder para establecer el tipo de codificación de audio.
Llame al método SetOutputFile para especificar el nombre del archivo de salida en el que se escriben los datos de audio.
Llame al método Prepare para inicializar la grabadora.
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:
Obtenga un identificador para el servicio del sistema
AudioManager
.Cree una instancia de la clase de devolución de llamada.
Solicite los recursos de audio del dispositivo llamando al método
RequestAudioFocus
enAudioManager
. 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).Si se concede la solicitud, el método
playMusic
se invoca inmediatamente y el audio comienza a reproducirse.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:
Al reproducir desde archivos de audio cifrados.
Al reproducir una sucesión de clips cortos.
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:
Tipo de transmisión: voz, tono de llamada, música, sistema o alarma.
Frecuencia: frecuencia de muestreo expresada en Hz.
Configuración del canal: mono o estéreo.
Formato de audio: codificación en 8 o 16 bits.
Tamaño del búfer: en bytes.
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:
Origen de entrada de audio de hardware (como micrófono).
Tipo de transmisión: voz, tono de llamada, música, sistema o alarma.
Frecuencia: frecuencia de muestreo expresada en Hz.
Configuración del canal: mono o estéreo.
Formato de audio: codificación en 8 o 16 bits.
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.