Hoje aprenderemos algo muito simples: como fazer um dispositivo Android tocar uma música ou fazer algum som. Iremos utilizar 2 classes nativas do Android: MediaPlayer e SoundPool. Basicamente falando, MediaPlayer é utilizado para tocar músicas (videos também, mas não será tratado aqui), ou seja, arquivos de "grande" duração que não serão manipulados constantemente, enquanto que SoundPool é utilizado para tocar pequenos sons, de maneira mais ativa, como os sons de jogos, por exemplo.
Para utilizar o MediaPlayer basta fazer uma chamada ao método estático create, passando como parâmetros o Context e o id do recurso de som ou a Uri do arquivo de som. Por exemplo:
MediaPlayer musica = MediaPlayer.create(this, R.raw.minha_musica);
musica.start();
Pronto, sua música será tocada. Simples não? E com a referência ao objeto musica você pode manipula-la como quiser, pausando-a, parando-a, definindo loop, volume, pulando para um dado tempo, etc. Mas fique atento pois o MediaPlayer trabalha como uma máquina de estados, assim ele não está sempre pronto para qualquer operação. Veja aqui mais informações sobre isso.
Já o SoundPool funciona como uma mesa de som. Primeiro se cria a "mesa" através do construtor passando como parâmetros: a quantidade máxima de sons que pode ser tocados ao mesmo tempo, o tipo de audio, e a qualidade (atualmente sem efeito). Por exemplo:
SoundPool sound = new SoundPool(4, AudioManager.STREAM_MUSIC, 0);
Com a "mesa" criada, vamos carregar os sons que serão utilizados através do comando load que recebe como parâmetros o arquivo de som (pode ser recurso, AssetFileDescriptor, um path, etc..) e a prioridade (que atualmente não tem efeito), e retorna um inteiro que é o id daquele som. Por exemplo:
int soundIDtiro = sound.load(this, R.raw.som_tiro, 1);
Importante: SoundPool não carrega arquivos com mais de 1 MB, apesar desta limitação não ser mencionada nas referencias, empiricamente nunca consegui carregar sons maiores que 1 MB. Talvez em versões posteriores isso seja possível.
Você pode carregar quantos sons quiser, desde que guarde o soundID associado, e eles estarão carregados na memória prontos para uso. Se em algum momento no futuro você não for mais utilizar um som, descarregue-o através do unload, passando o soundID como parâmetro.
Para tocar os sons basta executar o método play, passando como parâmetros: o soundID, o volume esquerdo e direito (float variando de 0.0 a 1.0), a prioridade (int, 0 = menor prioridade, usada caso o número de sons exceda o especificado na criação do SoundPool, e caso aconteça o de menor prioridade é parado), o loop (int, -1 = loop infinito, 0 = sem loop, 1 >= numéro de repetições), e o rate (float, entre 0.5 e 2.0, indica a velocidade, 1.0 = velocidade normal). Como retorno temos um int que é um streamID associado ao som tocado agora. Por exemplo:
int streamIDtiro = sound.play(soundIDtiro, 1f, 1f, 0, 0, 1f);
Com o streamID é possível manipular o som que está sendo tocado, parando-o, mudando o loop, o rate e/ou a prioridade. Entretanto, no caso geral, você não precisará se preocupar com o streamID, e nem ao menos precisará guarda-lo quando der um play.
Quando não precisar mais usar os sons você deve fazer a chamada do método release() que irá liberar todos os sons carregados da memória, e em seguida setar a referência do SoundPool para null. Por exemplo:
sound.release();sound = null;
Se precisar usar sons novamente crie um novo SoundPool.
Por hoje é só. Lembrando que qualquer dúvida é só perguntar, cometários e e-mail estão aí para isso. =]
12 comentários:
Boa Noite Gustavo, descobri seu blog baixando suas apps para meu Tablet, está show parabéns. Em relação a minha duvida é o seguinte: Estou tentando desenvolver uma APP que transmita minha WEB RÁDIO, busquei alternativas na internet, consegui montar uma app para inserir a URL da rádio ou do arquivo MP3 e tocar. Porem, o Mp3 toca, mas a web rádio não. Como será que montamos uma app assim? Tem ideia?
Bom Dia Felipe, obrigado por estar usando e gostar do blog. Quanto a sua duvida eu não tenho certeza mas talvez usando o AudioTrack (http://developer.android.com/reference/android/media/AudioTrack.html) se consiga fazer isso.
Beleza, vou dar uma olhada aqui, se conseguir algo volto para passar os passos de como consegui fazer.
Amigo, como faço para parar a aplicação enquanto ela está tocando o som?
@Henrique: Parar a aplicação geralmente se utiliza o finish() se estiver numa Activity. Mas acho que você quis dizer para a música, certo? Se estiver usando MediaPlayer é só dar o comando myMediaPlayerIntance.stop() e myMediaPlayerIntance.release() se não for mais utilizar. Para parar um SoundPool use soundPoolIntance.stop(streamId).
Ola amigo. O meu som está tocando somente em modo debug, passando linha-a-linha. Já passou por esta situação? Estou usando o SoundPool.
Obrigado pela atenção e parabéns pelo artigo.
@Diego: Muito estranho... Será que o código não está parando a música logo depois de mandar executar? Assim quando usa o debug para ir passo a passo é possível ouvir a música.
Desculpem a demora em voltar. Eu estava fazendo os testes com o Emulador. Quando coloquei a aplicação em vários celulares diferentes funcionou perfeitamente. Acredito ser alguma limitação do próprio emulador. Obrigado.
Cara, show de bola, execelente tutorial. Esse aqui também me ajudou http://blog.glaucocustodio.com/2013/03/29/usando-media-player-do-android-evitando-sobrecarga-de-recursos-do-sistema/
Abraços.
Olá, parabéns pelo tutorial, ajudou muito!
Mas lá vai a minha dúvida,
como faço para o som que parou devido a prioridade menor, voltar a tocar logo após o som principal parar?
SoundPool sound = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
int sound1 = sound.load(this, R.raw.a, 1);
int sound2 = sound.load(this, R.raw.b, 2);
sound.play(sound1, 1f, 1f, 0, 0, 1f);
quando um botão é selecionado{
sound.play(sound2, 1f, 1f, 1, 0, 1f);
}
Bem, o som 1 vai parar quando o botão for selecionado, mas como faço para ele voltar a tocar quando o som 2 parar?
Como eu posso fazer gerar um som? A aplicação que estou manipulando calcula a média RGB da imagem em tempo real, e gostaria de que a app falasse essa média e não só mostrasse na tela.
Boa tarde. Parabéns pelo tutorial. Estou desenvolvendo um app que transforma texto em som em tempo real, o problema é que gostaria de mudar a voz de default do android para uma voz infantil, sem usar sintetizadores de voz. Será que você poderia me dar uma luz de como fazer isso? Desde já agradeço.
Postar um comentário