Tutorial sonidos en Android: MediaPlayer y SoundPool

¡Bienvenidos a un nuevo tutorial de Geeky Theory! Hoy vamos a enseñar cómo usar dos clases para reproducir sonidos.

Antes de nada, decir que este tutorial está hecho sobre el SDK de Android instalado en Eclipse.

Para empezar, introduciremos lo que es y para qué sirve cada una de las clases que son necesarias para reproducir sonidos en Android.

- MediaPlayer: Esta clase será usada para reproducir archivos de audio largos, es decir, para reproducir, por ejemplo, música de fondo.

El diagrama que gestiona todo el flujo de música con la clase MediaPlayer es el siguiente. No asustaros, el ejemplo que hagamos hoy será muy básico y no usaremos todos los estados de la clase.

- SoundPool: Esta clase es usada para reproducir archivos de audio muy cortos, tales como efectos de botones. Hay que tener en cuenta que el archivo de audio que reproduzca esta clase tiene que tener un tamaño máximo de 1 Mb.

Realización Del Tutorial:

Creando Proyecto.

En primer lugar, nos creamos un nuevo proyecto Android:

Llamamos a nuestro proyecto TutorialSonidos y ponemos una versión mínima baja, con Android 2.1 será suficiente.

- Layout activity_main

Una vez creado nuestro proyecto, vamos al layout activity_main y copiamos el siguiente código:

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:gravity="center"><Buttonandroid:id="@+id/playMp"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Play MediaPlayer"/><Buttonandroid:id="@+id/stopMp"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Stop MediaPlayer"/><Buttonandroid:id="@+id/playSp"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="SoundPool"/></LinearLayout> Nos debería de quedar algo como esto:

- Recursos de Audio

Los recursos de audio deben incluirse en una carpeta que tenemos que crear dentro del directorio “res” .Esta carpeta debe llamarse “raw”. Incluimos allí nuestros archivos de audio.

En este caso incluiremos el archivo main_theme.ogg y el archivo sonido_acierto.ogg, el primero lo usaremos con la clase MediaPlayer, ya que será un archivo grande, el segundo será usado con la clase SoundPool.

Por último decir que los archivos de audio soportados son muchos, yo he usado archivos .mp3, .ogg y no he tenido ningún problema, para ver un listado completo, véase la referencia bibliográfica.

- Código de la aplicación:

Nos vamos a nuestra clase predefinida MainActivity.java para escribir el código de nuestra aplicación.

En primer lugar debemos referenciar cada botón a un objeto de la clase “Button”, a la vez nos creamos un objeto de la clase MediaPlayer y otro objeto de la clase SoundPool y un entero al que llamaremos flujodemusica.

package com.example.tutorialsonidos; import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.widget.Button; public class MainActivity extends Activity { public Button bplay,bstop,bsoundPool; public MediaPlayer mp; public SoundPool sp; public int flujodemusica=0; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bplay = (Button)findViewById(R.id.playMp); bstop = (Button)findViewById(R.id.stopMp); bsoundPool = (Button)findViewById(R.id.playSp); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; } } Implementamos la interfaz OnClickListener: public class MainActivity extends Activity implements OnClickListener { Tened cuidado a la hora de importar la clase OnclickListener, ya que hay que importar lo siguiente: import android.view.View; import android.view.View.OnClickListener;

Para que una interfaz funcione tenemos que implementar sus métodos dentro de nuestra clase, para ello implementamos el único método que tiene esta interfaz:

@Override public void onClick(View v) { // TODO Auto-generated method stub }Indicamos qué objetos son escuchados en el método onCreate:public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bplay = (Button)findViewById(R.id.playMp); bstop = (Button)findViewById(R.id.stopMp); bsoundPool = (Button)findViewById(R.id.playSp); bplay.setOnClickListener(this); bstop.setOnClickListener(this); bsoundPool.setOnClickListener(this); }Escuchamos los eventos de los botones, y creamos tres métodos para cada uno de nuestros casos: @Override public void onClick(View v) { // TODO Auto-generated method stub if(v.getId()==R.id.playMp){ play_mp(); } if(v.getId()==R.id.stopMp){ stop_mp(); } if(v.getId()==R.id.playSp){ play_sp(); } } private void play_sp() { // TODO Auto-generated method stub } private void stop_mp() { // TODO Auto-generated method stub } private void play_mp() { // TODO Auto-generated method stub }

En primer lugar, crearemos un objeto SoundPool, para ello nos vamos al onCreate de nuestra clase y escribimos lo siguiente:

@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bplay = (Button)findViewById(R.id.playMp); bstop = (Button)findViewById(R.id.stopMp); bsoundPool = (Button)findViewById(R.id.playSp); sp = new SoundPool(8, AudioManager.STREAM_MUSIC, 0); this.setVolumeControlStream(AudioManager.STREAM_MUSIC); flujodemusica= sp.load(this,R.raw.sonido_acierto,1); } La estructura del objeto SoundPool es la siguiente: SoundPool(int maxStreams , int streamType , int srcQuality)

  • int maxStreams: indica el número de veces que podemos reproducir el sonido a la vez.
  • int streamType: indica el tipo de flujo que usaremos .
  • int srcQuality: indica la calidad. Este atributo actualmente no esta en uso.

La orden siguiente, es usada para poder utilizar los botones de audio físicos: this.setVolumeControlStream(AudioManager.STREAM_MUSIC);

Por último, decir que para poder usar un objeto SoundPool, primero debemos cargar el archivo, esta carga es un número entero con un flujo de información.

La estructura para general el flujo de información es la siguiente:

[objeto_Spoundpool].load (Context context, int resId, int priority); Donde int resIdes la Id de nuestro archivo de música. Para terminar debemos introducir lo siguiente dentro de los métodos creados anteriormente: private void play_mp() { // TODO Auto-generated method stub mp= MediaPlayer.create(this, R.raw.main_theme); mp.start(); } private void stop_mp() { // TODO Auto-generated method stub mp.stop(); } private void play_sp() { // TODO Auto-generated method stub sp.play(flujodemusica, 1, 1, 0, 0, 1); } La estructura del objeto mediaplayer viene dada por: Mediaplayer.create( Context , int Id_Sound); La estructura de la función sp.play() tendrá la siguiente forma: sp.play(soundID, leftVolume, rightVolume, priority, loop, rate); Os muestro el código completo de la clase MainActivity.java:package com.example.tutorialsonidos; import android.app.Activity; import android.media.AudioManager; import android.media.MediaPlayer; import android.media.SoundPool; import android.os.Bundle; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class MainActivity extends Activity implements OnClickListener { public Button bplay,bstop,bsoundPool; public MediaPlayer mp; public SoundPool sp; public int flujodemusica; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bplay = (Button)findViewById(R.id.playMp); bstop = (Button)findViewById(R.id.stopMp); bsoundPool = (Button)findViewById(R.id.playSp); bplay.setOnClickListener(this); bstop.setOnClickListener(this); bsoundPool.setOnClickListener(this); sp = new SoundPool(8, AudioManager.STREAM_MUSIC, 0); this.setVolumeControlStream(AudioManager.STREAM_MUSIC); flujodemusica= sp.load(this,R.raw.sonido_acierto,1); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; } @Override public void onClick(View v) { // TODO Auto-generated method stub if(v.getId()==R.id.playMp){ play_mp(); } if(v.getId()==R.id.stopMp){ stop_mp(); } if(v.getId()==R.id.playSp){ play_sp(); } } private void play_mp() { // TODO Auto-generated method stub mp= MediaPlayer.create(this, R.raw.main_theme); mp.start(); } private void stop_mp() { // TODO Auto-generated method stub mp.stop(); } private void play_sp() { // TODO Auto-generated method stub sp.play(flujodemusica, 1, 1, 0, 0, 1); } } ¡Y esto es todo! Espero que os guste este tutorial, es el primero que hago, siento haber extendido el tutorial tanto. Si tenéis alguna duda, dejad un comentario e intentaré resolverla. ¡Gracias! El proyecto completo lo tenéis en el siguientes enlace: TutorialSonidos.zip Bibliografía: http://developer.android.com/intl/es/reference/android/media/SoundPool.htmlhttp://developer.android.com/intl/es/reference/android/media/MediaPlayer.html