Reproduzindo áudio no Android com MediaPlayer
A classe MediaPlayer é utilizada para tocar uma boa variedade de formatos de áudio e vídeo, podendo reproduzir áudio armazenados nos recursos da aplicação (raw resources), no sdcard do dispositivo ou no formato de stream vindo de uma conexão de internet.
O modo mais fácil é armazenando o conteúdo a ser reproduzido dentro da pasta de recursos da aplicação, para isso crie a pasta raw
dentro do seu projeto e coloque seu conteúdo lá, no nosso exemplo foi “musica.mp3
“.
MediaPlayer musica = MediaPlayer.create(this, R.raw.musica);
musica.play();
Algo que vale lembrar é que o MediaPlayer
funciona como uma máquina de estados conforme o diagrama abaixo e os métodos que podemos chamar para trocar os estados(mais detalhes). Ao criar o MediaPlayer
através do método create ele já o deixa no estado prepared
.
Também podemos reproduzir áudio armazenado no cartão de memória(sdcard) e não podemos nos esquecer de adicionar a permissão de leitura no sdcard dentro do arquivo AndroidManifest.xml
.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Vamos ao código:
try {
Uri uri = Uri.parse( Environment.getExternalStorageDirectory().getAbsolutePath()+"/Music/zumbis_do_espaco__cemiterio_maldito.mp3" ) ;
musica = new MediaPlayer();
musica.setAudioStreamType(AudioManager.STREAM_MUSIC);
musica.setDataSource( getApplicationContext() , uri);
musica.prepare();
musica.start();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Na linha 2 criamos um objeto Uri para identificar nosso arquivo que queremos reproduzir, lembrando que utilizamos o Environment.getExternalStorageDirectory().getAbsolutePath()
para pegar o caminho absoluto da raiz do sdcard. Na lina 3 criamos um objeto MediaPlayer()
.
Na linha 4 configuramos o MediaPlayer
para stream de áudio.
Na linha 5 configuramos a fonte de dados, passando o contexto da aplicação e a uri que identifica o recurso a ser reproduzido.
Na linha 6 chamamos prepare()
que deixa o objeto pronto para reprodução(isso pode levar algum tempo). E na linha 7 ele é iniciado.
Para reproduzir através da internet não é muito diferente, apenas criamos uma nova uri e não podemos esquecer de dar permissão para o aplicativo acessar a internet.
<uses-permission android:name="android.permission.INTERNET" />
Segue o código para reprodução pela internet.
try {
Uri uri = Uri.parse( "http://www.botecodigital.info/exemplos/audio/battlestargalatica_main_tite.mp3" ) ;
musica = MediaPlayer.create(this, uri);
musica.setAudioStreamType(AudioManager.STREAM_MUSIC);
musica.setDataSource( getApplicationContext() , uri );
musica.prepare();
musica.start();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Segue alguns métodos importantes de MediaPlayer
:
- isPlaying(): Verifica se existe um áudio/vídeo tocando.
- getDuration(): Retorna a duração do arquivo em milissegundos.
- getCurrentPosition(): Retorna a posição atual da reprodução em milissegundos.
- stop(): Para a reprodução.
- release() : libera o recurso associado ao
MediaPlayer
- seekTo(int): Posiciona a reprodução na posição passada por parâmetro.
Uma funcionalidade associada a um player de música muito utilizada é acompanhar o tempo de duração em uma barra de progresso e para isso devemos criar um processo separado que verifique o quanto da música já foi reproduzida e atualizar o processo da tela(UI Thread), para isso utilizamos o objeto Handler
para entregar as thread de atualização para o processo de tela já que nenhum processo externo pode atualizar a UI thread.
private Handler handler = new Handler();
public void play(View v){
if( !musica.isPlaying() ){
musica.start();
progress.setMax( musica.getDuration() );
tvPlay.setText("PAUSE");
update = new Runnable() {
@Override
public void run() {
SimpleDateFormat sdf = new SimpleDateFormat("mm:ss");
Date d = new Date( musica.getCurrentPosition() );
tvTempo.setText( sdf.format( d ) );
progress.setProgress( musica.getCurrentPosition() );
handler.postDelayed( this , 1000);
}
};
handler.postDelayed(update, 100);
}else{
musica.pause();
tvPlay.setText("PLAY");
}
}
Na linha 1 criamos nosso objeto Handler
, na linha 3 temos o método que será chamado quando o botão play do nosso aplicativo for acionado. Na linha 4 testamos se o áudio não está tocando !musica.isPlaying()
então chamamos o método start()
para iniciar o áudio(linha 5), configuramos o objeto SeekBar
, que é a nossa barra de progresso do áudio, para que seu máximo seja a duração total do áudio que esta sendo reproduzido(linha 6), e mudamos o texto do botão de play para pause(linha 7).
Na linha 8 é onde realmente fazemos a parte importante, criamos uma classe interna anônima que implementa a interface Runnable
declarando o método run
. Este método é o que irá atualizar os componentes de interface para modificar a barra de progresso(SeekBar
) e TextView
com o tempo decorrido da música, pego através da chamado do método getCurrentPosition()
. Dentro do próprio método run
realizamos a chamada do método postDelayed
do objeto Handler
, este método faz uma entrega “atrasada” de uma thread para a UI Thread executar recebendo como parâmetros um Runnable
que irá ser executado e o tempo de “atraso” desta execução em milissegundos. Como estamos chamando o método postDelayed
dentro do método que ele mesmo irá executar criamos uma “espécie de loop” ou recursão que irá atualizar constantemente a interface em intervalos constantes.
Na linha 22 fazemos a primeira chamada ao método postDelayed
para iniciar o nosso ciclo.
Para baixar um exemplo “meia boca” clique aqui.
Espero que tenha ajudado. 🙂