Grabación de audio

Las APIs de Android disponen de facilidades para capturar audio y video, permitiendo su codificación en diferentes formatos. La clase MediaRecorder te permitirá de forma sencilla integrar esta funcionalidad en tu aplicación.

La mayoría de dispositivos disponen de micrófono para capturar audio, sin embargo esta facilidad no ha sido integrada en el emulador. Por lo tanto, has de probar los ejercicios de este apartado en un dispositivo real.

La clase MediaRecorder dispone de una serie de métodos que podrás utilizar para configurar la grabación:

setAudioSource(int audio_source) – Dispositivo que se utilizará como fuente del sonido. Normalmente MediaRecorder.AudioSource.MIC. También se pueden utilizar otras constantes como DEFULT, CAMCORDER, VOICE_CALL, VOICE_COMUNICATION, …

setOutputFile (String fichero) – Nombre del fichero de salida.

setOutputFormat(int output_forma) – Formato del fichero de salida. Se pueden utilizar constantes de la clase MediaRecorder.OutputFormat: DEFAULT, AMR_NB, AMR_WB, RAW_AMR (ARM), MPEG_4(MP4) y THREE_GPP (3GPP).

setAudioEncoder(int audio_encoder) – Codificación del audio. Cuatro posibles constantes de la clase MediaRecorder.AudioEncoder: AAC, AMR_NB, AMR_WB y DEFAULT.

setAudioChannels(int numeroCanales) – Especificamos el número de canales 1: mono y 2: estéreo.

setAudioEncodingBitRate (int bitRate) (desde nivel de API 8) – Especificamos los bits por segundo (bps) a utilizar en la codificación.

setAudioSamplingRate (int samplingRate)  (desde nivel de API 8) – Especificamos el número de muetras por segundo a utilizar en la codificación.

setMaxDuration (int max_duration_ms) (desde nivel de API 3) – Indicamos una duración máxima para la grabación. Tras este tiempo se detendrá.

setMaxFileSize (long max_filesize_bytes) (desde nivel de API 3) – Indicamos un tamaño máximo para el fichero. Al alcanzar el tamaño se detendrá.

prepare() – Prepara la grabación para la captura de datos. Antes de llamarlo hay que configurar la grabación y después ya podemos invocar al método start().

start() – Comienza la captura

stop() – Finaliza la captura

reset() – Reinicia el objeto como si lo acabáramos de crear. Hay que volver a configurarlo.

release() – Libera todos los recursos utilizados de forma inmediata. Si no llamas al método se liberarán cuando el objeto sea destruido.

La clase MediaRecorder también dispone de métodos que podrás utilizar para configurar la grabación de video. Más información en: http://developer.android.com/reference/android/media/MediaRecorder.html

La siguiente tabla muestra los diferentes métodos que pueden ser ejecutados en cada estado y el estado que alcanzaremos tras la llamada:

 

Estado salida

 

 

Estado entrada

 

Initial

Initialized

DataSource Configured

Prepared

Recording

Error

 

Initial

 

reset

reset

reset

reset
stop

reset

 

Initialized

setAudioSource
setVideoSource

setAudioSource
setVideoSource

 

 

 

 

 

DataSource Configured

 

setOutputFormat

setAudioEncoder
setVideoEncoder
setOutputFile
setVideoSize
setVideoFrameRate
setPreviewDisplay

 

 

 

 

Prepared

 

 

prepare

     

 

Recording

 

 

 

start

   

 

Released

releas

 

 

     

 

Error

llamada incorrecta

llamada incorrecta

llamada 
incorrecta

llamada incorrecta

llamada incorrecta

   

   Tabla 7: Transiciones entre estados de la clase MediaRecorder

 

   Ejercicio paso a paso: Grabación de audio utilizando MediaRecoder

1. Crea un nuevo proyecto con nombre Grabadora. El nombre del paquete ha de ser org.example.grabadora y como actividad principal GrabadoraActivity.

2. Reemplaza el layout activity_main.xml por el siguiente código:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:orientation="horizontal">

    <Button

        android:id="@+id/bGrabar"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:text="Grabar"

        android:onClick="grabar"/>

    <Button

        android:id="@+id/bDetener"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:text="Detener Grabacion"

        android:onClick="detenerGrabacion"/>

    <Button

        android:id="@+id/bReproducir"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:text="Reproducir"

        android:onClick="reproducir"/>

</LinearLayout>

3. Reemplaza el código de la actividad por:

public class GrabadoraActivity extends Activity { 

private static final String LOG_TAG = "Grabadora";         
private MediaRecorder mediaRecorder;
private MediaPlayer mediaPlayer;

private static String fichero = Environment.                 
getExternalStorageDirectory().getAbsolutePath()+
"/audio.3gp";

   
@Override public void onCreate(Bundle savedInstanceState) {

   super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

 }

 

 public void grabar(View view) {

    mediaRecorder = new MediaRecorder();

    mediaRecorder.setOutputFile(fichero);

    mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);

    mediaRecorder.setOutputFormat(MediaRecorder.
                                          OutputFormat.
THREE_GPP);

    mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.
                                                     AMR_NB); 

    try {

        mediaRecorder.prepare();

    } catch (IOException e) {

        Log.e(LOG_TAG, "Fallo en grabación");

    }

    mediaRecorder.start();

  }

 

  public void detenerGrabacion(View view) {

     mediaRecorder.stop();

     mediaRecorder.release();

  }

 
 
public void reproducir(View view) {

     mediaPlayer = new MediaPlayer();

     try {

         mediaPlayer.setDataSource(fichero);

         mediaPlayer.prepare();

         mediaPlayer.start();

     } catch (IOException e) {

         Log.e(LOG_TAG, "Fallo en reproducción");

     }

   }

}

Comenzamos declarando dos objetos de las clase MediaRecorder y MediaPlayer que serán usados para la grabación y reproducción respectivamente. También se declaran dos String: La constante LOG_TAG será utilizada como etiqueta para identificar nuestra aplicación en el fichero de Log. La  variable ficheroidentifica en nombre del fichero donde se guardará la grabación. Este fichero se almacenará en una carpeta especialmente creada para nuestra aplicación. NOTA: En la unidad 8 se introducirá la gestión de ficheros. En el método onCreate() no se realiza ninguna acción especial.

A continuación se han introducido tres métodos que serán ejecutados al pulsar los botones de nuestro Layout. El significado de cada uno de los métodos que se invocan acaba de ser explicado.

4.  Abre AndroidManifest.xml y en la pestaña Permissions pulsa el botón Add… selecciona Uses Permissions. En el desplegable Name indica RECORD_AUDIO.  Repite este proceso para usar el permiso WRITE_EXTERNAL_STORAGE.

5.  Ejecuta de nuevo la aplicación y verifica el resultado.

Ejercicio paso a paso: Grabación de audio utilizando MediaRecoder (II)

La aplicación anterior resulta algo confusa de utilizar. Sería más sencillo si los botones que no pudiéramos utilizar en un determinado momento estuvieran deshabilitados. Para conseguirlo vamos a utilizar el método Button.setEnabled(boolean). Veamos como conseguirlo:

1. Declara las siguientes tres variables al principio de la Actividad:

private Button bGrabar, bDetener, bReproducir;

2. En el método onCreate() inicializa estos tres botones. Además comenzaremos deshabilitando dos de los botones que al principio de la aplicación no deben ser pulsados:

bGrabar = (Button) findViewById(R.id.bGrabar);

bDetener = (Button) findViewById(R.id.bDetener);

bReproducir = (Button) findViewById(R.id.bReproducir);

bDetener.setEnabled(false);

bReproducir.setEnabled(false);

3.  En el método grabar() añade el siguiente código:

bGrabar.setEnabled(false);

bDetener.setEnabled(true);

bReproducir.setEnabled(false);

4.  En el método detenerGrabacion() añade el siguiente código:

bGrabar.setEnabled(true);

bDetener.setEnabled(false);

bReproducir.setEnabled(true);

5. Ejecuta de nuevo la aplicación y verifica el resultado.

Preguntas de repaso y reflexión:

Multimedia