Introducción a MediaPlayer en Android

Índice de contenidos

Introducción

En este pequeño tutorial de introducción a la API de MediaPlayer, veremos cómo reproducir música desde nuestra aplicación de Android, de esta forma podremos crearnos desde un botón que reproduzca un sonido, hasta un reproductor de música offline y online. Este tutorial va dirigido a personas que tengan nociones básicas sobre Android Studio y Kotlin.

¿Qué es MediaPlayer?

MediaPlayer es una API de Android que nos permite reproducir contenido multimedia, ya sea video o audio. Podemos reproducir, tanto archivos almacenados en el dispositivo como desde un flujo de datos que llega a través de Internet.

Como conceptos básicos tenemos:

La clase MediaPlayer que es la API principal para reproducir sonido y vídeo.

La clase AudioManager que administra fuentes y salidas de audio en el dispositivo.

Diagrama de estados

Para poder conocer y aprovechar al máximo esta API debemos conocer su flujo de estados, como podemos ver en la siguiente imagen, tenemos varios estados y acciones para llegar a cada uno de ellos, en este tutorial nos centraremos en los principales para reproducir un archivo de audio. Como apunte, las flechas simples representan llamadas a métodos síncronos y las flechas dobles a métodos asíncronos. A continuación vamos a explicar el diagrama.





Al principio, al crear un nuevo objeto MediaPlayer se llama al método reset() y pasa al estado Idle (Inactivo), en este momento si llamáramos a los métodos play(), stop(), pause(), etc... se generaría un error.

A continuación se llama al método setDataSource(), aquí vamos a proporcionarle los datos al objeto MediaPlayer, estos datos pueden ser tanto un archivo local como un flujo continuo de datos que llega a través de la red.

Ahora estamos en el estado Initialized (Inicializado), ahora antes de reproducir cualquier cosa, debemos llamar al método prepare() o prepareAsync(), el primero de todos lo que hace es capturar, almacenar y decodificar el archivo multimedia, sin embargo cuando leemos datos desde la red este método puede ser demasiado lento, sobretodo cuando hay mala conexión, por ello es más recomendable el segundo, el prepareAsync(), que está preparado para eso.

Una vez está en el estado Prepared (Preparado), podemos empezar a controlar la reproducción del archivo mediante los métodos start(), stop(), seekTo(), etc.

Si invocamos el método start(), habremos pasado al método Started (Reproduciendo), ahora podemos pausar la reproducción con pause() o finalizarla cuando queramos con stop(). Si la reproducción llega al final y no se ha establecido que reproduzca en bucle, el objeto pasa al estado PlaybackCompleted (Reproducción completada), desde aquí se puede volver a llamar al método start() y volver a reproducir el archivo, o llamar al método stop() y desde aquí, se puede ir al estado End (Fin), llamando al método release() y liberar el objeto, pero, si queremos volver a reproducir el archivo tendremos que volver a crearlo y prepararlo.

Bien, ahora que hemos visto de manera resumida lo básico de los estados de MediaPlayer, podemos ver un ejemplo en Android y Kotlin.

Ejemplo en Android y Kotlin

Bien, ahora vamos a crear un proyecto en Android, con una actividad en blanco, llamada MainActivity, y con lenguaje Kotlin.

Y en dicha pantalla, es decir, en el archivo activity_main.xml vamos a colocar 3 botones (Play, Pause y Stop), La vista sería tal que así:





El código XML sería el siguiente:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
tools:context=".MainActivity">

<Button
    android:id="@+id/buttonPlay"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_weight="0.3"
    android:layout_gravity="center_vertical"
    android:text="Play"
    tools:layout_editor_absoluteX="63dp"
    tools:layout_editor_absoluteY="272dp" />

<Button
    android:id="@+id/buttonPause"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_weight="0.3"
    android:layout_gravity="center_vertical"
    android:text="Pause"
    tools:layout_editor_absoluteX="176dp"
    tools:layout_editor_absoluteY="275dp" />

<Button
    android:id="@+id/buttonStop"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_weight="0.3"
    android:layout_gravity="center_vertical"
    android:text="Stop"
    tools:layout_editor_absoluteX="286dp"
    tools:layout_editor_absoluteY="275dp" />
</LinearLayout>

Ahora vamos a añadir un archivo de audio al proyecto, para ello creamos en resources, un nuevo resource directory llamado raw, ahí guardaremos todos nuestros archivos de audio. El nombre de raw es porque así lo especifica Android.





Bien, una vez tenemos nuestra vista, y nuestro archivo de audio para reproducir, vamos al archivo MainActivity.kt y vamos a darle funcionalidad a nuestros botones.

Primero enlazaremos los botones con la vista, luego inicializaremos nuestro objeto MediaPlayer y por último le daremos lógica a los botones cuando alguien haga clic en ellos. El código quedaría así:

class MainActivity : AppCompatActivity() {

    private lateinit var buttonPlay: Button
    private lateinit var buttonPause: Button
    private lateinit var buttonStop: Button

    private lateinit var mediaPlayer: MediaPlayer

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        buttonPlay = findViewById(R.id.buttonPlay)
        buttonPause = findViewById(R.id.buttonPause)
        buttonStop = findViewById(R.id.buttonStop)

        mediaPlayer = MediaPlayer.create(this, R.raw.audio1)

        setOnClickListeners(this)
    }

    private fun setOnClickListeners(context: Context) {
        buttonPlay.setOnClickListener {
            mediaPlayer.start()
            Toast.makeText(context, "Reproduciendo...", Toast.LENGTH_SHORT).show()
        }

        buttonPause.setOnClickListener {
            mediaPlayer.pause()
            Toast.makeText(context, "En pausa...", Toast.LENGTH_SHORT).show()
        }

        buttonStop.setOnClickListener {
            mediaPlayer.stop()
            mediaPlayer = MediaPlayer.create(context, R.raw.audio1)
            Toast.makeText(context, "Parando...", Toast.LENGTH_SHORT).show()
        }
    }
}

De esta forma cuando pulsemos el botón play, se iniciará el audio, cuando pausemos se parara, y cuando pulsemos stop se reiniciará desde el principio, lo ideal sería que cuando el audio se esté reproduciendo el botón play estuviera deshabilitado y cuando no se estuviera reproduciendo estuvieran tanto pause como stop deshabilitados, pero eso te lo dejo como tarea ;)

Si quisiéramos usar el reproductor para audio en Streaming, no tendríamos necesidad de crearnos nuestra carpeta raw. Con un código como el siguiente sería suficiente:

String url = "http://www.url.com/audio.mp3";

mediaPlayer = MediaPlayer();
mediaPlayer.setDataSource(url);
mediaPlayer.prepareAsync();

mediaPlayer.setOnPreparedListener {
    buttonPlay?.isEnabled = true
}

mediaPlayer.start();

Aquí es importante el uso de un método llamado setOnPreparedListener, esto nos indicará en que momento MediaPlayer está listo para reproducir el audio descargado, es una buena ocasión, para por ejemplo, habilitar el botón Play, que deberíamos tener deshabilitado hasta que la canción estuviera cargada, dado que de no ser así generaremos errores.

Conclusiones

Como veis, con muy poco se puede reproducir audio en Android, si le añadís una SeekBar, y un listado de canciones ya tenéis un reproductor de música al completo, espero que os haya gustado esta pequeña introducción al mundo musical de Android, nos vemos en la próxima :)

19 vistas

©2020 por Juanma Perez.