This post shows how to track user’s activity when viewing YouTube videos on your site. It can track when a user starts/stops/pauses a video, watches a video all the way through, and also tracks at different points 25%/50%/75%. I used example code from lunametrics that creates YouTube objects from any existing iframe plugins on the site. Reference: http://www.lunametrics.com @lunametrics.
First, first this to work - all iframe src value needs to contain the following:&enablejsapi=1&origin=http%3a%2f%2fwww.mroma.net. Where www.mroma.net would be the domain you are running your site on.
var tag = document.createElement(‘script’); tag.src = “//www.youtube.com/iframe_api”; var firstScriptTag = document.getElementsByTagName(‘script’)[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); var videoArray = new Array(); var playerArray = new Array(); // find all existing iframes, convert to youtube objects (function (\() { function trackYouTube() { var i = 0; jQuery('iframe').each(function () { var video = \)(this); if (video.attr(‘src’) === undefined) { var vidSrc = “”; } else { var vidSrc = video.attr(‘src’); } var regex = /h?t?t?p?s?:?\/\/www.youtube.com\/embed\/([\w-]{11})(?:\?.*)?/; var matches = vidSrc.match(regex); if (matches && matches.length > 1) { videoArray[i] = matches[1]; \((this).attr('id', matches[1]); i++; } }); onYouTubeIframeAPIReady(); } \)(document).ready(function () { trackYouTube(); }); })(jQuery); // handle when iframe api is ready function onYouTubeIframeAPIReady() { // check if already executed if (videoArray.length == 0 || playerArray.length > 0) { return; } // go through each video, get the player object for (var i = 0; i < videoArray.length; i++) { playerArray[i] = new YT.Player(videoArray[i], { events: { ‘onReady’: onPlayerReady, ‘onStateChange’: onPlayerStateChange } }); } } // youtube player ready function onPlayerReady(event) { } // youtube player state change function onPlayerStateChange(event) { // track state change YouTubeTracking.checkStateChange(event); }
Now that we have a player object for each YouTube video on the page, here is the code that tracks each event and tracks have checkpoints met. The checkpoints array contains which percents to check.
// define youtube tracking api var YouTubeTracking = { // define checkpoints to track checkpointsToTrack: [25, 50, 75], // define player array players: [], // define pause flag _pauseFlag: false, // define interval id intervalId: 0, // function that gets the player info, creates new if not exists get: function (id) { if (YouTubeTracking.players[id] == undefined) { YouTubeTracking.players[id] = { timePercent: 0 }; } return YouTubeTracking.players[id]; }, // function that start the interval, if not already started startChecking: function () { // check if not already started if (YouTubeTracking.intervalId == 0) { YouTubeTracking.intervalId = setInterval(YouTubeTracking.checkPlayers, 500); } }, // function that checks players on an interval checkPlayers: function () { // go through each player make sure atleast one playing var anyPlaying = false; \(.each(playerArray, function (i, p) { // check if playing if (p.getPlayerState() == YT.PlayerState.PLAYING) { anyPlaying = true; // get the video info var duration = p.getDuration(); var timeSoFar = p.getCurrentTime(); var id = p.getVideoData().video_id; // get what we tracked so far on this video var playerPerc = YouTubeTracking.get(id).timePercent; // check if any duraction if (duration > 0) { // get the percentage played var thisPerc = timeSoFar / duration * 100; // check each checkpoint \).each(YouTubeTracking.checkpointsToTrack, function (j, checkpoint) { // check if we reached a checkpoint milestone if (playerPerc < checkpoint && thisPerc > checkpoint) { YouTubeTracking.players[id].timePercent = checkpoint; YouTubeTracking.pushEvent(id, “Watched ” + checkpoint + “%”); } }); } } }); // check if none player, stop intveral if (!anyPlaying) { clearInterval(YouTubeTracking.intervalId); YouTubeTracking.intervalId = 0; } }, // track state check checkStateChange: function (event) { // get the id var id = event.target.a.id; // video playing if (event.data == YT.PlayerState.PLAYING) { YouTubeTracking.pushEvent(id, “Play”); YouTubeTracking.pauseFlag = false; // start checkpoint checking YouTubeTracking.startChecking(); } // video end if (event.data == YT.PlayerState.ENDED) { YouTubeTracking.pushEvent(id, “Watch to End”); } // video paused if (event.data == YT.PlayerState.PAUSED && YouTubeTracking.pauseFlag == false) { YouTubeTracking.pushEvent(id, “Pause”); YouTubeTracking.pauseFlag = true; } // buffering if (event.data == YT.PlayerState.BUFFERING) { YouTubeTracking.pushEvent(id, “Buffering”); } // cued if (event.data == YT.PlayerState.CUED) { YouTubeTracking.pushEvent(id, “Cueing”); } }, // track in GA pushEvent: function (id, catg) { // get the title, then trach \(.get("https://gdata.youtube.com/feeds/api/videos/" + id + "?v=2&alt=json", function (d) { _gaq.push(['_trackEvent', 'Videos', catg, d.entry.title.\)t]); }); } };
The full source file can be downloaded here: mroma-youtube-tracking.js