Boteco Digital

Controlando o elemento audio do HTML5 com Javascript

Se você está por fora, o HTML5 trouxe elementos para exibição de áudio e video sem ter que utilizar um player em flash, basta que você coloque o elemento audio ou video que o navegador irá reproduzir exibindo os controles se quisermos. Vamos a um exemplo.

<audio controls>
	<source src="i_am_the_doctor.ogg" type="audio/ogg">
	<source src="i_am_the_doctor.mp3" type="audio/mpeg">
	Seu navegador não possui suporte ao elemento audio
</audio>

Utilizamos o elemento audio e colocamos o atributo controls que irá exibir os controles play/pause, dentro deste elemento inserimos elementos source para fornecer os arquivos de áudio para serem tocados, o elemento source recebe como atributo src o arquivo de áudio e o atributo type onde informamos o codec do arquivo. É recomendável colocar dois elementos source pois alguns navegadores suportam um tipo de arquivo e outros não, então para segurança colocamos os dois principais MP3 e OGG.

Se você quiser pode converter um arquivo MP3 em OGG através do seguinte comando no linux.

ffmpeg -i audio.mp3  -acodec libvorbis  audio.ogg

Também podemos utilizar um conversor online.

Para a tag audio ainda temos os seguintes atributos:

  • controls: Especifica que os controles de áudio(botões de play/pause barra de progresso, etc.) deve ser exibido
  • autoplay: Especifica que o áudio deve ser tocado assim que for carregado
  • loop: Especifica que ao terminar o áudio deve voltar para o início
  • muted: Especifica que áudio deve ser mutado(?!?)

Veja um exemplo de áudio com player padrão(pode mudar de navegador para navgador)

Isso já deve resolver a maior parte de nossas necessidades. No entanto se quisermos customizar mais podemos até criar nosso próprio player controlando a reprodução através de javascript.

<audio id="audio">
	<source src="i_am_the_doctor.ogg" type="audio/ogg">
	<source src="i_am_the_doctor.mp3" type="audio/mpeg">
	Seu navegador não possui suporte ao elemento audio
</audio>

<div>
	<a href="#" onclick="play()">Play</a>
	<a href="#" onclick="pause()">Pause</a>
	<a href="#" onclick="stop()">Stop</a>
</div>

<div>
	<a href="#" onclick="aumentar_volume()"> + volume</a>
	<a href="#" onclick="diminuir_volume()"> - volume</a>
	<a href="#" onclick="mute()"> Mute</a>
</div>

<script>
	audio = document.getElementById('audio');

	function play(){
		audio.play();
	}

	function pause(){
		audio.pause();
	}

	function stop(){
		audio.pause();
		audio.currentTime = 0;
	}

	function aumentar_volume(){
		if( audio.volume < 1)  audio.volume += 0.1;
	}

	function diminuir_volume(){
		if( audio.volume > 0)  audio.volume -= 0.1;
	}
		
	function mute(){
		if( audio.muted ){
			audio.muted = false;
		}else{
			audio.muted = true;
		}
	}
</script>

Veja um exemplo de áudio controlado por javascript

Da linha 1 até a 5 é simples inserirmos o elemento audio , nas linha 8, 9 e 10 inserimos links para os controles de play, pause e stop, que chamam os devidos métodos Javascript. Nas linhas 14, 15 e 16 temos links para aumentar o volume, diminuir o volume e mutar também chamando seus respectivos métodos Javascript.

No Javascript(linha 20) pegamos o elemento audio pelo id e guardamos em uma variável para manipularmos nas funções, na linha 22 temos o a função play que basicamente chama o método play() do elemento de áudio. Na liha 26 temos a função pause que chama a função pause() do elemento audio. Já na linha 30 temos a função stop() que o elemento não tem, mas podemos parar a reprodução e voltar para o inicio do tempo, o que pode ser feito atribuindo o valor “0” ao atributo currentTime que armazena a posição em que o áudio está sendo executado.

Na linha 35 temos a função aumentar_volume() que irá incrementar o atributo volume do elemento, ele aceita um valor em ponto flutuante entre “0” (sem volume nenhum) e “1” (o volume máximo), no nosso caso vamos incrementar em “0.1” para cada fez que for clicado. Na linha 39 temos o método diminuir_volume() que vamos decrementar o atributo volume “0.1” também.

Na linha 43 vemos a função mute() que irá alterar a propriedade muted que recebe true para não emitir som e false para o emitir.

Eventos de áudio

Ao reproduzir um áudio existem eventos que são disparados e que podemos configurar funções que sejam executadas quando estes ocorrerem, vamos a um exemplo.

<audio id="audio">
	<source src="i_am_the_doctor.ogg" type="audio/ogg">
	<source src="i_am_the_doctor.mp3" type="audio/mpeg">
	Seu navegador não possui suporte ao elemento audio
</audio>
<progress id="barra_progresso" max="0" value="0"></progress>
<div>
	<a href="#" onclick="play()">Play</a>
	<a href="#" onclick="pause()">Pause</a>
	<a href="#" onclick="stop()">Stop</a>
</div>
<span id="tempo_atual">00:00:00</span> /
<span id="tempo_total">00:00:00</span>

<script>
	audio = document.getElementById('audio');
	
	audio.addEventListener('play', play_evento , false);
	audio.addEventListener('timeupdate', atualizar , false);

	function play(){
		audio.play();
	}

	function pause(){
		audio.pause();
	}

	function stop(){
		audio.pause();
		audio.currentTime = 0;
	}

	function play_evento(){
		document.getElementById('tempo_atual').innerHTML = secToStr( audio.currentTime) ;
		document.getElementById('tempo_total').innerHTML = secToStr( audio.duration );

		document.getElementById('barra_progresso').max = audio.duration;
		document.getElementById('barra_progresso').value = audio.currentTime;
	}

	function atualizar(){
		document.getElementById('tempo_atual').innerHTML = secToStr( audio.currentTime);
		document.getElementById('barra_progresso').value = audio.currentTime;
	}

	function secToStr( sec_num ) {
		sec_num = Math.floor( sec_num );
	    var horas   = Math.floor(sec_num / 3600);
	    var minutos = Math.floor((sec_num - (horas * 3600)) / 60);
	    var segundos = sec_num - (horas * 3600) - (minutos * 60);
	    
	    if (horas   < 10)  horas    = "0"+horas;
	    if (minutos < 10)  minutos  = "0"+minutos;
	    if (segundos < 10) segundos = "0"+segundos;
	    
	    var tempo    = horas+':'+minutos+':'+segundos;
	    
	    return tempo;
	}
</script>

Veja um exemplo de audio com eventos

O exemplo acima é semelhante aos anteriores mas agora colocamos uma barra de progresso(elemento progress) na linha 6, que será atualizada conforme o áudio for tocando, também temos na linhas 12 e 13 dois elementos span que serão atualizados com o tempo decorrido e o tempo total respectivamente.

Na linha 18 adicionamos um “listener” ou seja configuramos para que quando um certo evento ocorra no elemento ao qual ele foi adicionado o listener irá chamar uma função definida por nós, no caso estamos adicionando um listener para o evento play ou seja, quando o áudio é executado seja pela primeira vez ou após ter sido pausado, para este evento definimos que deve ser chamada a função play_evento que foi definida na linha 34 que seleciona o elemento span com o id tempo_atual e insere dentro dele o valor contido no atributo currentTime que contem tempo atual do áudio e no span tempo_total insere a duração total do áudio que é pego do atributo duration do elemento. Nestes dois spans antes de inserimos os valores de currentTime e duration devemos fazer uma formatação, já que eles estão em segundo com casas decimais. Para fazer a formatar utilizamos a função secToStr que formata recebe um valor double e o formata como uma string no padrão hh:mm:ss, explicamos a função mais adiante.

Na própria função play_evento também atualizamos a barra de progresso(progress) com o valor da duração do áudio colocando este valor no atributo max e no atributo value colocamos o tempo atual.

Na linha 19 adicionamos um listener para o evento de timeupdate ou seja quando o tempo corrente do áudio for atualizado, ou seja quando o currentTime for alterado e definimos para quando este evento ocorrer ele chamar a função atualizar na linha 42 que basicamente pega o tempo atual de reprodução e atualiza o span tempo_atual e o atributo value do elemento pregress. Este evento ocorrerá pelo menos uma vez por segundo, então coloque somente o essencial aqui.

A função secToStr na linha 47, retira a parte fracionaria do segundos recebidos por parâmetro e depois divide estes segundo em hora, minuto e segundo. Primeiro temos que descobrir quantas horas tem o parâmetro sec_num para isso dividimos a quantidade de segundos por 3600(numero de segundos em uma hora) ai teremos o número de horas. Agora temos que descobrir quantos minutos, primeiro subtraímos dosec_num a quantidade de segundo que couberam em horas(horas * 3600) e depois dividimos este valor por 60( número de segundos em um minuto) obtendo a quantidade de minutos. E por último subtraímos do total de segundo o total que já couberam em horas(horas*3600) e também os que couberam em minutos(minutos *60) e o valor resultante vai ser o segundos. Após isso verificamos se os valores de horas, minutos e segundo tem menos de um digito, se sim, acrescentamos um digito “0”. Por último concatenamos tudo e retornamos.

Criando uma playlist

Muita vezes precisamos tocar um sequência de áudios, para isso ao terminar um áudio devemos trocar o arquivo para o próximo da lista. Veja o exemplo;

<audio id="audio">
	Seu navegador não possui suporte ao elemento audio
</audio>
<progress id="barra_progresso" max="0" value="0"></progress>
<div>
	<a href="#" onclick="play()">Play</a>
	<a href="#" onclick="pause()">Pause</a>
	<a href="#" onclick="stop()">Stop</a>
</div>
<div id="nome_musica"></div>
<span id="tempo_atual">00:00:00</span> /
<span id="tempo_total">00:00:00</span>

<script>
	var i = 0;
	var musicas = 	[
			{ mp3:'the_godfather_main_title.mp3' , ogg:'the_godfather_main_title.ogg' , titulo:'The Godfather Main Title Sample'},
			{ mp3:'game_of_thornes_main_title.mp3', mp3:'game_of_thornes_main_title.ogg' , titulo:'Game of Thrones Main Title Sample'},
			{ mp3:'battlestargalatica_main_tite.mp3' ,mp3:'battlestargalatica_main_tite.ogg' , titulo:'Battlestar Galactica Main Title Sample'},
			]; 
	audio = document.getElementById('audio');
			
	audio.addEventListener('canplay', play_evento , false);
	audio.addEventListener('timeupdate', atualizar , false);
	audio.addEventListener('ended', proxima , false);

	function play(){
		proxima();
	}

	function pause(){
		audio.pause();
	}

	function stop(){
		audio.pause();
		audio.currentTime = 0;
	}

	function play_evento(){
		document.getElementById('tempo_atual').innerHTML = secToStr( audio.currentTime) ;
		document.getElementById('tempo_total').innerHTML = secToStr( audio.duration );
		document.getElementById('barra_progresso').max = audio.duration;
		document.getElementById('barra_progresso').value = audio.currentTime;
	}

	function atualizar(){
		document.getElementById('tempo_atual').innerHTML = secToStr( audio.currentTime);
		document.getElementById('barra_progresso').value = audio.currentTime;
	}

	function proxima(){
		if(audio.canPlayType("audio/mp3") != ''){
			audio.src = musicas[i].mp3;
		}else{
			audio.src = musicas[i].ogg;
		}
		document.getElementById('nome_musica').innerHTML = musicas[i].titulo;
		audio.play();

		i++;
		if( i >= musicas.length ) i = 0;
	}

	function secToStr( sec_num ) {
		sec_num = Math.floor( sec_num );
		var horas   = Math.floor(sec_num / 3600);
		var minutos = Math.floor((sec_num - (horas * 3600)) / 60);
		var segundos = sec_num - (horas * 3600) - (minutos * 60);

		if (horas   < 10) {horas   = "0"+horas;}
		if (minutos < 10) {minutos = "0"+minutos;}
		if (segundos < 10) {segundos = "0"+segundos;}
		var tempo    = horas+':'+minutos+':'+segundos;
		return tempo;
	}
</script>

Veja um exemplo de um playlist

Neste exemplo criamos um array que irá conter todos os arquivos a serem reproduzidos(linha 16), este é um array de objetos onde temos um atributo para o arquivo no formato MP3, um para o arquivo no formato OGG e um atributo para o titulo do áudio que deverá ser exibido no player. Na linha 15 criamos uma variável para controlar em qual dos áudios estamos reproduzindo.

Na função play() não chamamos mais o método play do elemento audio mas agora chamamos outra função a próxima(linha 52) que é responsável por reproduzir o arquivo corrente indicado pelo contador na variável i. Na função proxima() primeiramente testamos se o navegador pode reproduzir o tipo de arquivo MP3 através do método canPlayType que retornará a string “probably” se o navegador tem suporte, “maybe” se o ele talvez tenha suporte e uma string vazia se não tem suporte. Se tiver suporte(retornar qualquer coisa diferente de vazio) pegamos o endereço do arquivo de MP3 do nosso array e atribuímos ao atributo src do elemento audio, se não tiver suporte pegamos o arquivo OGG. Em seguida pegamos do array o titulo do áudio e atribuímos ao div que irá exibi-lo. Por fim incrementamos o contador(variável i) para apontar para a próxima música a ser tocada,se o o contador já está na última música voltamos a apontar para a primeira(linha 62).

Agora falta configurarmos para que quando um áudio termine outro comece e fazemos isso adicionando um listener para o evento ended que é disparado quando a reprodução chega ao fim, e adicionaremos para executar a função proxima() fazendo que toque o próximo arquivo de nosso array de áudios.

Bom era isso e por favor não coloquem música tocando quando um site abre, reproduzir um áudio deve ser uma decisão do usuário. T++

Categorias Javascript Web
comments powered by Disqus