Triggering a Youtube Video from Clicking a Button Image and Replacing when Ended
This post will discuss how to solve the problem of playing a Youtube video from a press from an initial starting image, and then replacing the image when the video has ended playing.
Over the last two years on a few different web projects, I have had occasion to need to trigger a Youtube video to play from a Jquery click event on a PNG image button or HTML5 element. When implementing frontend development For example, a JPG rollover has CSS3 styles simulating button presses, which loads the Youtube Player Javascript API and fires the OnPlayerReady callback.
Recently, it was needed to replace the Jpeg clicked button or Div element when the video finished playing. In this case, it is necessary to detect the Youtube player state and call the player.destroy() method, along with reseting any other DOM elements that may have been effected during the instantiation of the player object. This all needs to be reliable for browser versions at least as old as IE8, as well as, mobile devices, iPhones, iPads, and Android tablets and phones.
Skip to full code
Working JSfiddle
How it works
Basically, this works by downloading the Youtube player API asynchronously, then instantiating a new player object and assigning the appropriate event listeners
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
In this example, I have added a few other pieces that were useful in my particular case, namely a rollover image for a button which is attached as the background-image of a div that holds the player div.
$("#container").mouseenter(function(){
$(this).addClass('hover-state');
}).mouseleave(function(){
$(this).removeClass('hover-state');
});
For the purposes of simplicity I am simply using some image urls that have been converted to data uris
.inactive-state {
background-repeat: no-repeat;
background-size: 100%;
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFUAAAAwCAIAAADvrqHkAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAVxJREFUeNpivD5DnmEEAyaGkQ1G/T/q/1H/j/p/1P+j/h/1/6j/RxpgoZ3RGmn3qWXUjVmKo/E/1OKfKlFHxUQ0iOKfU8xgRJd/0m4zOUR0R67/WbjEZDxmD4YgGLDyj4VLHBQEonojt/4HBYE7MAh0R6j/oRnBbRaHiM7Ibf+xcEuAUsEAlQWDov0DDIKBqhEGS/uPlUdSxn0W/YNgELV/QRnBYzafSsDI7f8BawReJc9h1f4nCXy4vvzt+Skj1P8fb615ebTu/78/IzH9f7y56sWhCjp7frDE/4drS16eaP3/7+9IrP+Aef7Vifb/f34MTIk7wMn+9nr65/nB4n9ggff8YDnD/38DWeMOYJ5/daJtYD0/YPkflOdPdf37833AS5+B8f+bsxP//fo8KFqctLaA1gO4w6r9T3/AOLr+iWHU/6P+H/X/qP9H/T/q/1H/j/p/1P8jBwAEGAAZsV2KaXSD7AAAAABJRU5ErkJggg==');
}
.hover-state {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFUAAAAwCAIAAADvrqHkAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAU1JREFUeNrsmV1qwkAUhVOJ9b8PUZ+UFp+MW+iLuo8uzAW4FhFEBREsWsVSQZO2oM/WGYdB360k3jH33AVM8p0758yd5GHSerEYV8ziXeAHP/jBD37wgx/83MoOb2n39S2opd47bfT/3vofSOsC3EQG9T+VK7DOv1K1nsw6fPntx1TZbZogAVn+nSXI8z3/tQQNWgmIzz8tQT2ZcZjyawnS5VqDKguMmH+UBKUqjQSmzH/xRFpngcOU/2QEt/lUrPC9/6k4zOWfIzX//6u23ux3NWbKv/Pn3qInpeDIr+A3866UMmr334u2/WbqLfu3hzci/5Tn/c+BFAeaxCXe9t+L23veFH7l+fVH17Ik4TvYhJ73lwNaeDL/a88PhfgjTx8a/p+vkTjsjZg4w35A2B9wIzX/R6r/4f20Qf/BD37wgx/84Ac/+MF/ZR0FGAAHJFtR2l1ELgAAAABJRU5ErkJggg==');
}
I have also added an example of some additional embellishment that can be added to the event handler functions, clicking the element and then the onStateChange.
$("#container.click-to-play-video").click(function(){
$('#head').css({"background-color":"black"});
and
$("#container.click-to-play-video").click(function(){
$('#head').css({"background-color":"black"});function onPlayerStateChange(event) {
if(event.data == YT.PlayerState.ENDED) {
player.destroy();
$('#head').css({"background-color":"#aaa"});
}
}
I found that this code will work in a wide range of browsers, tested backward to IE8, as well as mobile devices and phones. As always, testing the code in every platform that your project supports is paramount to success.
The Full Code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Triggering a Youtube Video from Clicking a Button Image and Replacing when Ended</title>
</head>
<body>
<style type="text/css">
#head {
background-color: #aaa;
width:100%;
}
#container {
cursor:pointer;
width:320px;
height:180px;
margin:auto;
position:relative;
}
.inactive-state {
background-repeat: no-repeat;
background-size: 100%;
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFUAAAAwCAIAAADvrqHkAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAVxJREFUeNpivD5DnmEEAyaGkQ1G/T/q/1H/j/p/1P+j/h/1/6j/RxpgoZ3RGmn3qWXUjVmKo/E/1OKfKlFHxUQ0iOKfU8xgRJd/0m4zOUR0R67/WbjEZDxmD4YgGLDyj4VLHBQEonojt/4HBYE7MAh0R6j/oRnBbRaHiM7Ibf+xcEuAUsEAlQWDov0DDIKBqhEGS/uPlUdSxn0W/YNgELV/QRnBYzafSsDI7f8BawReJc9h1f4nCXy4vvzt+Skj1P8fb615ebTu/78/IzH9f7y56sWhCjp7frDE/4drS16eaP3/7+9IrP+Aef7Vifb/f34MTIk7wMn+9nr65/nB4n9ggff8YDnD/38DWeMOYJ5/daJtYD0/YPkflOdPdf37833AS5+B8f+bsxP//fo8KFqctLaA1gO4w6r9T3/AOLr+iWHU/6P+H/X/qP9H/T/q/1H/j/p/1P8jBwAEGAAZsV2KaXSD7AAAAABJRU5ErkJggg==');
}
.hover-state {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFUAAAAwCAIAAADvrqHkAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAU1JREFUeNrsmV1qwkAUhVOJ9b8PUZ+UFp+MW+iLuo8uzAW4FhFEBREsWsVSQZO2oM/WGYdB360k3jH33AVM8p0758yd5GHSerEYV8ziXeAHP/jBD37wgx/83MoOb2n39S2opd47bfT/3vofSOsC3EQG9T+VK7DOv1K1nsw6fPntx1TZbZogAVn+nSXI8z3/tQQNWgmIzz8tQT2ZcZjyawnS5VqDKguMmH+UBKUqjQSmzH/xRFpngcOU/2QEt/lUrPC9/6k4zOWfIzX//6u23ux3NWbKv/Pn3qInpeDIr+A3866UMmr334u2/WbqLfu3hzci/5Tn/c+BFAeaxCXe9t+L23veFH7l+fVH17Ik4TvYhJ73lwNaeDL/a88PhfgjTx8a/p+vkTjsjZg4w35A2B9wIzX/R6r/4f20Qf/BD37wgx/84Ac/+MF/ZR0FGAAHJFtR2l1ELgAAAABJRU5ErkJggg==');
}
</style>
<section id="head">
<div id="container" class="click-to-play-video inactive-state">
<div id="player" class="home-player"></div>
</div>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script type="text/javascript">
$("#container").mouseenter(function(){
$(this).addClass('hover-state');
}).mouseleave(function(){
$(this).removeClass('hover-state');
});
$("#container.click-to-play-video").click(function(){
$('#head').css({"background-color":"black"});
player = new YT.Player('player', {
width : '320',
height : '180',
videoId : 'qlEUrEVqDbo',
playerVars: { 'autoplay': 1 },
events : {
'onReady' : onPlayerReady,
'onStateChange' : onPlayerStateChange
}
});
});
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player;
function onPlayerReady(event) {
//event.target.playVideo();
}
function onPlayerStateChange(event) {
if(event.data == YT.PlayerState.ENDED) {
player.destroy();
$('#head').css({"background-color":"#aaa"});
}
}
</script>
</body>
</html>
Was this content useful? Follow Nate Flink on Twitter!
Have you had any luck getting this to work on the iphone?
This was a great help to me.
Good article, of course, but why didn’t you separate your jQuery in the fiddle example?
That would make things so much easier to understand.
http://jsfiddle.net/eLt4aybd/1/
🙂
and in angularjs in a ng-repeat grid ?? how would you do ?
so that the container clicked fills with a random video and empties the player that ended before …
How would you do this with 2 instances on the page?
Thank for this
one issue in this code on click play video not working in the mobile
pls check