28 - Captura de audio mediante la clase MediaRecorder


Otra forma de grabar audio en Android es el empleo de la clase MediaRecorder. Esta clase nos da más libertades a la hora de construir una aplicación que requiere grabar audio.

Problema:

Disponer tres objetos de la clase Button con las etiquetas "Grabar", "Detener Grabación" y "Reproducir Grabación". Disponer además un TextView para informar del estado actual.

Cuando se presione el botón "Grabar" permitir registrar todos los sonidos hasta que se presione el botón "Detener Grabación". Cuando se presione el botón "Reproducir Grabación" emitir el archivo de audio previamente generado.

La interfaz visual a implementar es la siguiente:

grabar audio android MediaRecorder

Tener en cuenta de no olvidar definir los tres métodos para los tres botones: grabar, detener y reproducir.

También debemos modificar el archivo AndroidManifest.xml donde debemos indicar que nuestra aplicación accederá a la grabadora de sonido y a la tarjeta SD donde se almacenará el archivo de sonido.

Esto lo hacemos seleccionando el archivo AndroidManifest.xml y en la pestaña Permissions registramos los dos permisos:

grabar audio android MediaRecorder

El código fuente es:


package com.androidya.proyecto026;

import java.io.File;
import java.io.IOException;

import android.app.Activity;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity implements OnCompletionListener {
    TextView tv1;
    MediaRecorder recorder;
    MediaPlayer player;
    File archivo;
    Button b1, b2, b3;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tv1 = (TextView) this.findViewById(R.id.textView1);
        b1 = (Button) findViewById(R.id.button1);
        b2 = (Button) findViewById(R.id.button2);
        b3 = (Button) findViewById(R.id.button3);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

    public void grabar(View v) {
        recorder = new MediaRecorder();
        recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        File path = new File(Environment.getExternalStorageDirectory()
                .getPath());
        try {
            archivo = File.createTempFile("temporal", ".3gp", path);
        } catch (IOException e) {
        }
        recorder.setOutputFile(archivo.getAbsolutePath());
        try {
            recorder.prepare();
        } catch (IOException e) {
        }
        recorder.start();
        tv1.setText("Grabando");
        b1.setEnabled(false);
        b2.setEnabled(true);
    }

    public void detener(View v) {
        recorder.stop();
        recorder.release();
        player = new MediaPlayer();
        player.setOnCompletionListener(this);
        try {
            player.setDataSource(archivo.getAbsolutePath());
        } catch (IOException e) {
        }
        try {
            player.prepare();
        } catch (IOException e) {
        }
        b1.setEnabled(true);
        b2.setEnabled(false);
        b3.setEnabled(true);
        tv1.setText("Listo para reproducir");
    }

    public void reproducir(View v) {
        player.start();
        b1.setEnabled(false);
        b2.setEnabled(false);
        b3.setEnabled(false);
        tv1.setText("Reproduciendo");
    }

    public void onCompletion(MediaPlayer mp) {
        b1.setEnabled(true);
        b2.setEnabled(true);
        b3.setEnabled(true);
        tv1.setText("Listo");
    }
}

Declaramos un objeto de la clase MediaRecorder para grabar audio:

    MediaRecorder recorder;

Declaramos un objeto de la clase MediaPlayer para reproducir el archivo de sonido generado:

    MediaPlayer player;

Declaramos un objeto de la clase File que hace referencia al archivo que se creará:

    File archivo;

Declaramos las variables que harán referencia a los tres botones y al TextView:

    TextView tv1;
    Button b1,b2,b3;

En el método onCreate obtenemos la referencia de los cuatro objetos creados en el archivo XML:

        tv1 = (TextView) this.findViewById(R.id.tv1);
        b1=(Button)findViewById(R.id.button1);
        b2=(Button)findViewById(R.id.button2);        
        b3=(Button)findViewById(R.id.button3);

El método más importante de este concepto es el grabar:


    public void grabar(View v) {
        recorder = new MediaRecorder();
        recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        File path = new File(Environment.getExternalStorageDirectory().getPath());
        try {
            archivo = File.createTempFile("temporal", ".3gp", path);
        } catch (IOException e) {
        }
        recorder.setOutputFile(archivo.getAbsolutePath());
        try {
            recorder.prepare();
        } catch (IOException e) {
        }
        recorder.start();
        tv1.setText("Grabando");
        b1.setEnabled(false);        
        b2.setEnabled(true);    
    }

Creamos un objeto de la clase MediaRecorder:

        recorder = new MediaRecorder();

Seguidamente definimos el micrófono como fuente de audio:

        recorder.setAudioSource(MediaRecorder.AudioSource.MIC);

Luego llamamos al método setOutputFormat especificando que el archivo será almacenado con la especificación 3GPP y con extensión .3gp

        recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);

Especificamos el codec a emplear llamando al método setAudioEncoder:

        recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

Obtenemos el path de la tarjeta SD y creamos un archivo temporal con extensión 3gp:

        File path = new File(Environment.getExternalStorageDirectory().getPath());
        try {
            archivo = File.createTempFile("temporal", ".3gp", path);
        } catch (IOException e) {
        }

Con el método setOutputFile de la clase MediaRecorder le indicamos el archivo donde debe almacenarse la grabación:

        recorder.setOutputFile(archivo.getAbsolutePath());

Llamamos al método prepare y finalmente al método start para comenzar la grabación:

        try {
            recorder.prepare();
        } catch (IOException e) {
        }
        recorder.start();

El método detener:


    public void detener(View v) {
        recorder.stop();
        recorder.release();    
        player = new MediaPlayer();
        player.setOnCompletionListener(this);
        try {
            player.setDataSource(archivo.getAbsolutePath());
        } catch (IOException e) {
        }
        try {
            player.prepare();
        } catch (IOException e) {
        }            
        b1.setEnabled(true);        
        b2.setEnabled(false);
        b3.setEnabled(true);
        tv1.setText("Listo para reproducir");        
    }

Llamamos primero al método stop de la clase MediaRecorder y liberamos los recursos consumidos llamando a release:

        recorder.stop();
        recorder.release();    

Creamos un objeto de la clase MediaPlayer para poder reproducir el archivo de audio que acabamos de grabar. Indicamos mediante el método setOnCompletionListener la referencia de la clase que será informada cuando el audio finalice:

        player = new MediaPlayer();
        player.setOnCompletionListener(this);

Referenciamos el archivo a que debe reproducir:

        try {
            player.setDataSource(archivo.getAbsolutePath());
        } catch (IOException e) {
        }

Finalmente llamamos al método prepare de la clase MediaPlayer:

        try {
            player.prepare();
        } catch (IOException e) {
        }            

El método reproducir simplemente llama al método start de la clase MediaPlayer para iniciar la reproducción del archivo previamente grabado:

    public void reproducir(View v) {
        player.start();
        b1.setEnabled(false);
        b2.setEnabled(false);        
        b3.setEnabled(false);
        tv1.setText("Reproduciendo");        
    }

El método onCompletion se ejecuta cuando termina de reproducirse el archivo de audio:

    public void onCompletion(MediaPlayer mp) {
        b1.setEnabled(true);        
        b2.setEnabled(true);
        b3.setEnabled(true);
        tv1.setText("Listo");
    }

Este proyecto lo puede descargar en un zip desde este enlace: proyecto026.zip

Retornar