Eventos baseados no tempo de vídeo do Youtube
Já teve a necessidade de incorporar um vídeo do Youtube em seu site e lançar algum evento em um determinado tempo da execução do mesmo? Se sim, este post é pra você.
Recentemente tive uma demanda com um cliente onde existia a necessidade de abrir uma modal alguns segundos antes do vídeo finalizar. Apesar de a documentação da API do Youtube disponibilizar a informação de como obter o tempo atual do vídeo, ela não mostra um exemplo prático. E é isso que venho te mostrar.
Pegue o seguinte código como exemplo:
HTML
<div id="player" data-video-id="ZZ5LpwO-An4"></div>
Javascript
Primeiramente adicione o jquery, só pra ficar fácil de trabalhar daqui pra frente.
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
Depois inicie a configuração do player do Youtube.
<script> // Adicionando o script do youtube iframe var tag = document.createElement('script'); var firstScriptTag = document.getElementsByTagName('script')[0]; tag.src = 'https://www.youtube.com/iframe_api'; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); // inicializando player var playerDiv = $('#player'); var player = null; // método chamado automaticamente pela API do Youtube function onYouTubeIframeAPIReady() { player = new YT.Player('player', { height: 450, // qualquer altura desejada width: 800, // qualquer largura desejada videoId: $(playerDiv).attr('data-vide-id'), playerVars: { // adicionando algumas variáveis rel: 0, // não exibir videos relacionados ao final showinfo: 0, // ocultar informações do video autoplay: 1 // play automático } }); } </script>
Feito isso já temos o seguinte resultado.
OnReady
A API do Youtube possui alguns eventos como o onReady que é lançado assim que o vídeo está pronto para a execução. Basta que adicionemos o evento vinculando à uma função que criaremos mais à frente.
// Nas inicializações das variáveis, adicione mais estas: videoDuration, videoTime e interval var videoDuration = 0; var videoTime = 0; var interval = null; // nas configurações do player adicione a configuração de eventos // playersVars: {...}, events: { 'onReady': onPlayerReady }
Em seguida temos de criar nossa funcão onPlayerReady. Nele descobriremos qual é o tempo atual do vídeo e lançaremos uma ação em um determinado momento.
function onPlayerReady(event) { // obtendo o tempo atual do vídeo videoDuration = parseInt(player.getDuration()); // aplicando um loop de 1 em 1s interval = setInterval(discoverTime, 1000); }
Mas de onde o discoverTime? Esta função ainda criaremos e é nela a grande jogada para executar qualquer ação baseada no tempo do video.
E a mágica
Agora criaremos a função discoverTime.
// adicionando um tempo em específico para que uma ação seja executada. var fireAt = 15; function discoverTime() { // obtendo o tempo atual do video if (player && player.getCurrentTime) { videoTime = parseInt(player.getCurrentTime()); } if (videoTime < videoDuration && videoTime === fireAt) { console.log('Aos ' + fireAt + 's, coloque aqui a sua mágica!'); } // quando o video terminar, resetamos o interval if (videoTime > videoDuration) { clearInterval(interval); } }
Pronto! Agora só lançar o que for preciso, a qualquer momento do vídeo.
É recomendado para saber quando o vídeo chegou ao fim?
Não. Para isso existe outro evento, o onStateChange. O que foi feito acima é um listener que roda a cada segundo, recomendado somente para situações em que você precise lançar algum evento durante a execução do video ou a alguns poucos segundos de sua finalização, como foi o caso que tive com um cliente recentemente. Veja abaixo um exemplo de como identificar diversos estados do vídeo, inclusive o momento em que ele chega ao fim.
// nas configurações de eventos events: { 'onReady': onPlayerready, 'onStateChange': onPlayerStateChange }... function onPlayerStateChange(event) { switch (event.data) { case YT.PlayerState.ENDED: console.log('Finalizou execução do video'); break; case YT.PlayerState.PLAYING: console.log('Assistindo'); break; case YT.PlayerState.PAUSED: console.log('Pause'); break; case YT.PlayerState.BUFFERING: console.log('carregando'); break; } }
That’s it!
Quer ver na prática? Então pega este gist que criei no dia em que implementei esta solução para meu cliente.