If you have a website with embedded YouTube videos you can track how your visitors interact with the player inside Google Analytics.

This will provide you with an understanding of how people have interacted with your videos, whether they clicked on play, and whether they actually watched it through to the end. We can use this information to gain richer insights into how each of our videos are being used, which videos users actually watch, and which ones they turn off.

In this blog post we will focus on the required setup for new asynchronously loaded YouTube Player API: the IFrame API. This is the latest version of the YouTube embed code. If you’re using an earlier version of the YouTube embed code, the below steps won’t work. You’ll need to either upgrade your embed method, or find an alternative approach.

Required Setup Steps

Below we will run through the steps required to implement YouTube video tracking on your website:

  1. Create a
    element in the body that will hold the YouTube video:


  2. We follow this with the beginning of our script block which loads the YouTube iFrame API:


    var tag = document.createElement('script');
    tag.src = "http://www.youtube.com/player_api";
    var firstScriptTag = document.getElementsByTagName('script')[0];
    firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
  3. Once the API for the player is loaded it calls the onYouTubePlayerAPIReady() function. The next part of our script block listens for this call. You’ll need to add the below code beneath the code you added in step 2. When you do this, you’ll need to change the videoID as well as the video height and width.

    var player;
    var lastAction = '';
    function onYouTubePlayerAPIReady() {
    player = new YT.Player('player', {
    height: '390',
    width: '640',
    videoId: 'u1zgFlCw8Aw',
    events: {
    'onStateChange': onPlayerStateChange
    }
    });
    }
  4. For every video player status change, the function onPlayerStateChange() is called by the YouTube iFrame API. What we do is the below code block is to trigger a Google Analytics event triggered depending on the current status which is included in the data property of the event parameter (event.data). Add the following code beneath the code from step 3 and that will finish up our script block.

    function onPlayerStateChange(event) {
    switch (event.data){
    case YT.PlayerState.PLAYING:
    _gaq.push(['_trackEvent','video', 'Playing', player.getVideoUrl()]);
    break;
    case YT.PlayerState.ENDED:
    _gaq.push(['_trackEvent','video', 'Completed', player.getVideoUrl()]);
    break;
    case YT.PlayerState.PAUSED:
    if (lastAction != 'paused'){
    _gaq.push(['_trackEvent','video', 'Paused', player.getVideoUrl()]);
    lastAction = 'paused';
    }
    break;
    }
    }

The Complete Code

To save you the trouble of pasting all the code together, we’ve got the complete code below. Be sure to follow the instructions and change all the highlighted values!



var tag = document.createElement('script');
tag.src = "http://www.youtube.com/player_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

var player;
var lastAction = '';
function onYouTubePlayerAPIReady() {
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: 'u1zgFlCw8Aw',
events: {
'onStateChange': onPlayerStateChange
}
});
}

function onPlayerStateChange(event) {
switch (event.data){
case YT.PlayerState.PLAYING:
_gaq.push(['_trackEvent','video', 'Playing', player.getVideoUrl()]);
break;
case YT.PlayerState.ENDED:
_gaq.push(['_trackEvent','video', 'Completed', player.getVideoUrl()]);
break;
case YT.PlayerState.PAUSED:
if (lastAction != 'paused'){
_gaq.push(['_trackEvent','video', 'Paused', player.getVideoUrl()]);
}else{
lastAction = 'paused';
}
break;
}
}

It is worth noting the case for YT.PlayerState.PAUSE, that is, when we pause the video. To account for this case we’ve saved the previous action in the variable ‘lastAction’, and if our previous action was ‘paused’, then we don’t register an event. This is to avoid triggering countless GA events when using the scrub option (dragging the play location ball).

In the example above , we use:


_gaq.push(['_trackEvent','video', 'Playing', player.getVideoUrl()]);

For those who need a refresher on event parameters, this represents:

Category > video
Action > Playing
Label > Video URL (taken dynamically from the API)

If you want to customise your javascript tracking setup, you can check the player status using integer values or namespaced ones (like in our example).

The possible values returned according the status are:

Integer values Namespaced
  • -1 : no started yet
  • 0 : ended
  • 1 : playing
  • 2 : paused
  • 3 : buffering
  • 5 : video cued.
  • YT.PlayerState.ENDED
  • YT.PlayerState.PLAYING
  • YT.PlayerState.PAUSED
  • YT.PlayerState.BUFFERING
  • YT.PlayerState.CUED

Setting up Goals

Now that your tracking is all working, you can set up event-based goals in Google Analytics. You might want to set up the completion event as a goal, as this indicates that a user has fully engaged with your video content.