Aug 21, 2013

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!

About the Author

Object Partners profile.

One thought on “Triggering a Youtube Video from Clicking a Button Image and Replacing when Ended

  1. JP says:

    Have you had any luck getting this to work on the iphone?

  2. TW says:

    This was a great help to me.

  3. Silviu says:

    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.

  4. zezen says:

    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 …

  5. Larry says:

    How would you do this with 2 instances on the page?

  6. Sadik Sheikh says:

    Thank for this
    one issue in this code on click play video not working in the mobile
    pls check

Leave a Reply to zezen Cancel reply

Your email address will not be published.

Related Blog Posts
Natively Compiled Java on Google App Engine
Google App Engine is a platform-as-a-service product that is marketed as a way to get your applications into the cloud without necessarily knowing all of the infrastructure bits and pieces to do so. Google App […]
Building Better Data Visualization Experiences: Part 2 of 2
If you don't have a Ph.D. in data science, the raw data might be difficult to comprehend. This is where data visualization comes in.
Unleashing Feature Flags onto Kafka Consumers
Feature flags are a tool to strategically enable or disable functionality at runtime. They are often used to drive different user experiences but can also be useful in real-time data systems. In this post, we’ll […]
A security model for developers
Software security is more important than ever, but developing secure applications is more confusing than ever. TLS, mTLS, RBAC, SAML, OAUTH, OWASP, GDPR, SASL, RSA, JWT, cookie, attack vector, DDoS, firewall, VPN, security groups, exploit, […]