Skip to content

Instantly share code, notes, and snippets.

@surferxo3
Last active July 26, 2020 11:46
Show Gist options
  • Save surferxo3/3c456923f2078c4ecc691fec1f67f8a9 to your computer and use it in GitHub Desktop.
Save surferxo3/3c456923f2078c4ecc691fec1f67f8a9 to your computer and use it in GitHub Desktop.
A YouTube video tracker for tracking Play/Paused/Ended events via Google Analytics.
<!DOCTYPE html>
<html>
<body>
<script>
(function (i, s, o, g, r, a, m) {
i['GoogleAnalyticsObject'] = r;
i[r] = i[r] || function () {
(i[r].q = i[r].q || []).push(arguments)
}, i[r].l = 1 * new Date();
a = s.createElement(o),
m = s.getElementsByTagName(o)[0];
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m)
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
ga('create', 'UA-XXXXXXXX-XX', 'auto'); // don't forget to replace with your UA code
ga('send', 'pageview');
</script>
<iframe id="player" width="500" height="315" src="https://www.youtube.com/embed/eVH1Y15omgE?enablejsapi=1&origin=http://localhost" frameborder="0" allowfullscreen></iframe>
<h5>Record of user actions:</h5>
<script src="https://code.jquery.com/jquery-2.2.3.min.js" integrity="sha256-a23g1Nt4dtEYOj7bR+vTu7+T8VP13humZFBJNIYoEJo=" crossorigin="anonymous"></script>
<script src="https://www.youtube.com/iframe_api"></script>
<script>
/* if older analytics used i.e. ga.js
_gaq.push(['GA event method',
'Organize different types of custom events',
'Record unique user behaviors and acts',
'Associate dynamic or static values with events',
'Attribute optional integer values',
'Determine if your event affects bounces']);
*/
/* if newer analytics used i.e. analytics.js
ga('tracker', 'event', 'category', 'action', 'label', {nonInteraction: true});
ga('send', 'event', [eventCategory], [eventAction], [eventLabel], [eventValue], [fieldsObject]);
ga('send', {
hitType: 'event',
eventCategory: 'Videos',
eventAction: 'play',
eventLabel: 'Fall Campaign'
});
*/
/* Youtube js api events
YT.PlayerState.ENDED
YT.PlayerState.PLAYING
YT.PlayerState.PAUSED
YT.PlayerState.BUFFERING
YT.PlayerState.CUED
*/
/* Youtube js api events for error
2 – The request contains an invalid parameter value. For example, this error occurs if you specify a video ID that does not have 11 characters, or if the video ID contains invalid characters, such as exclamation points or asterisks.
5 – The requested content cannot be played in an HTML5 player or another error related to the HTML5 player has occurred.
100 – The video requested was not found. This error occurs when a video has been removed (for any reason) or has been marked as private.
101 – The owner of the requested video does not allow it to be played in embedded players.
150 – This error is the same as 101. It's just a 101 error in disguise!
*/
/* Formula for calculating percentages
* Finish Percentage => Finished (Unique Events) /Play (Unique Events)
* Play Percentage => Play (Unique Events) / Unique Pageviews
*/
var player;
var title;
//function invoked on youtube iframe ready
function onYouTubeIframeAPIReady() {
player = new YT.Player( 'player', {
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange,
'onError': onPlayerError
} // bind other events or playerVars
});
}
//function invoked on youtube player ready
function onPlayerReady(event) {
// do nothing, no tracking needed
/*
$.get('http://gdata.youtube.com/feeds/api/videos/oNrWOwQ3wfg?v=2&alt=json', function(data) {
title = data.entry.title.$t;
});
*/
title = player.getVideoData().title
}
//function invoked on youtube play/pause events
function onPlayerStateChange(event) {
/*
switch(event.data) {
case YT.PlayerState.ENDED:
record('video ended');
break;
case YT.PlayerState.PLAYING:
record('video playing from '+player.getCurrentTime());
break;
case YT.PlayerState.PAUSED:
record('video paused at '+player.getCurrentTime());
break;
}
*/
// track when user clicks to Play
if (event.data == YT.PlayerState.PLAYING) {
if (cleanTime() == 0) {
//console.log('started ' + cleanTime());
ga('send', 'event', 'Videos', 'Started', title);
}
else {
//console.log('playing ' + cleanTime())
ga('send', 'event', 'Videos', 'Played', 'v: ' + title + ' | t: ' + cleanTime());
}
}
// track when user clicks to Pause
if (event.data == YT.PlayerState.PAUSED) {
if (player.getDuration() - player.getCurrentTime() != 0) {
//console.log('paused' + ' @ ' + cleanTime());
ga('send', 'event', 'Videos', 'Paused', 'v: ' + title + ' | t: ' + cleanTime());
}
}
// track when video ends
if (event.data == YT.PlayerState.ENDED) {
//console.log('ended');
ga('send', 'event', 'Videos', 'Ended', title);
}
}
//function invoked on youtube player ready
function onPlayerError(event) {
if (event.data == 2) {
//console.log('' + video.id)
ga('send', 'event', 'Videos', 'Invalid ID', title);
}
else if (event.data == 100) {
ga('send', 'event', 'Videos', 'Not Found', title);
}
else if (event.data == 101 || event.data == 150) {
ga('send', 'event', 'Videos', 'Not Allowed', title);
}
}
//utility function: called to get youtube video played duration
function cleanTime() {
return Math.round(player.getCurrentTime());
}
//utility function: called to record user interaction with the youtube video
function record(str) {
//console.log("Current event log :: " + str);
var p = document.createElement("p");
p.appendChild(document.createTextNode(str));
document.body.appendChild(p);
}
</script>
</body>
</html>
@surferxo3
Copy link
Author

One can use the "ga" events to track any element in DOM and do in-dept analysis in Google Analytics Dashboard.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment