For many of my projects I use MediaElementJS. This is an awesome library for HTML5 video with a fallback to Flash or Silverlight. Anyway, I had a client request to add google analytics for all their videos. I found the following code which adds the events to each player in order to start tracking events. The code is a great start but I needed a deeper dive than simply the play, pause, and completed counts for each video. I decided to track which parts of the videos were viewed by bucketing the videos into 30 second chunks.

*I was tweaking the code while working on it so the last three buckets (8,9,10) should be merged with 4,5,6 but you get the idea.
The code is fairly straight forward but I thought I would post it as it may help someone out who needs to accomplish the same task.
$.extend(mejs.MepDefaults, {
googleAnalyticsTitle: '',
googleAnalyticsCategory: 'Videos',
googleAnalyticsEventPlay: 'Play',
googleAnalyticsEventPause: 'Pause',
googleAnalyticsEventEnded: 'Ended',
googleAnalyticsEventTime: 'Time'
});
var formatTime = function (timeInSeconds) {
var sec_numb = parseInt(timeInSeconds);
var hours = Math.floor(sec_numb / 3600);
var minutes = Math.floor((sec_numb - (hours * 3600)) / 60) + hours * 60;
var seconds = sec_numb - (hours * 3600) - (minutes * 60);
if (seconds < 10) { seconds = "0" + seconds; }
return minutes + ':' + seconds;
};
$.extend(MediaElementPlayer.prototype, {
buildgoogleanalytics: function (player, controls, layers, media) {
var timeInterval = 30, counter = 1, time, currentInterval = 0;
media.addEventListener('play', function () {
if (typeof _gaq != 'undefined') {
_gaq.push(['_trackEvent',
player.options.googleAnalyticsCategory,
player.options.googleAnalyticsEventPlay,
(player.options.googleAnalyticsTitle === '') ? player.currentSrc : player.options.googleAnalyticsTitle,
parseInt(player.getCurrentTime())
]);
}
time = parseInt(player.getCurrentTime());
counter = 1;
while (timeInterval * counter < time) {
counter += 1;
}
}, false);
media.addEventListener('pause', function () {
if (typeof _gaq != 'undefined') {
_gaq.push(['_trackEvent',
player.options.googleAnalyticsCategory,
player.options.googleAnalyticsEventPause,
(player.options.googleAnalyticsTitle === '') ? player.currentSrc : player.options.googleAnalyticsTitle,
parseInt(player.getCurrentTime())
]);
}
}, false);
media.addEventListener('ended', function () {
if (typeof _gaq != 'undefined') {
time = parseInt(player.getCurrentTime());
currentInterval = timeInterval * counter;
_gaq.push(['_trackEvent',
player.options.googleAnalyticsCategory,
player.options.googleAnalyticsEventEnded,
(player.options.googleAnalyticsTitle === '') ? player.currentSrc : player.options.googleAnalyticsTitle,
time
]);
_gaq.push(['_trackEvent',
player.options.googleAnalyticsCategory,
formatTime(currentInterval - timeInterval) + " - " + formatTime(time),
(player.options.googleAnalyticsTitle === '') ? player.currentSrc : player.options.googleAnalyticsTitle
]);
}
}, false);
media.addEventListener('timeupdate', function () {
if (typeof _gaq != 'undefined') {
time = parseInt(player.getCurrentTime());
currentInterval = timeInterval * counter;
if (time > currentInterval) {
counter += 1;
_gaq.push(['_trackEvent',
player.options.googleAnalyticsCategory,
formatTime(currentInterval - timeInterval) + " - " + formatTime(currentInterval),
(player.options.googleAnalyticsTitle === '') ? player.currentSrc : player.options.googleAnalyticsTitle
]);
}
}
}, true);
}
});