- TLC Home Home
- Discussions Discussions
- Documentation Documentation
- Knowledge Base Knowledge Base
- Education Education
- Blog Blog
- Support Desk Support Desk
Hi, I'm trying to tackle Brightcove video tracking for Google Analytics. I saw the great post for SiteCatalyst but found it hard to adapt to my needs.
I found a separate Brightcove event listener at http://www.analytics-ninja.com/blog/2016/03/tracking-brighcove-videos-with-gooogle-analytics.html which I've adapted for Tealium:
// Tracking for BrightCove Player // David Vallejo (@thyng) try { // CODE START Number.prototype.padLeft = function(base, chr) { var len = (String(base || 10).length - String(this).length) + 1; return len > 0 ? new Array(len).join(chr || '0') + this : this; } jQuery(function() { var $ = jQuery; var placeholder = '<div></div>'; // Loop thru all players in the page and reload them with needed params jQuery('object.BrightcoveExperience').each(function() { // Let's grab the videoId, playerKey, PlayerId, width and heigh values to create an updated player object later. var flashvars = $(this).attr('data').replace(/(^\?)/, '').split("&").map(function(n) { return n = n.split("="), this[n[0]] = n[1], this }.bind({}))[0]; var playerTemplate = '<object class="BrightcoveExperience"><param name="@videoPlayer" value="' + flashvars['%40videoPlayer'] + '" /><param name="playerID" value="' + flashvars.playerID + '" /><param name="playerKey" value="' + flashvars.playerKey + '" /><param name="width" value="' + flashvars.width + '" /><param name="height" value="' + flashvars.height + '" /><param name="bgcolor" value="#FFFFFF" /><param name="isVid" value="true" /><param name="isUI" value="true" /> <param name="dynamicStreaming" value="true" /> <param name="includeAPI" value="true" /> <param name="templateLoadHandler" value="onTemplateLoad" /> </object>'; var $p = $(placeholder); var $orig = $(this).replaceWith($p); $p.replaceWith(playerTemplate); }); brightcove.createExperiences(); return true; }); // onTemplateLoad function, here is where the listeners are added. function onTemplateLoad() { var bcPlayers = []; var APIModules = brightcove.api.modules.APIModules; // Let's grab all the players in the page, and set the listeners for them for (expId in brightcove.experiences) { if (expId.indexOf('bcExperienceObj') > -1) { var player = brightcove.api.getExperience(expId); bcPlayers[expId] = player.getModule(APIModules.VIDEO_PLAYER); bcPlayers[expId]["progress_already_fired"] = {}; bcPlayers[expId].addEventListener(brightcove.api.events.MediaEvent.BEGIN, self.onMediaEventFired); bcPlayers[expId].addEventListener(brightcove.api.events.MediaEvent.COMPLETE, onMediaEventFired); bcPlayers[expId].addEventListener(brightcove.api.events.MediaEvent.PLAY, onMediaEventFired); bcPlayers[expId].addEventListener(brightcove.api.events.MediaEvent.STOP, onMediaEventFired); bcPlayers[expId].addEventListener(brightcove.api.events.MediaEvent.COMPLETE, onMediaEventFired); bcPlayers[expId].addEventListener(brightcove.api.events.MediaEvent.SEEK_NOTIFY, onMediaEventFired); bcPlayers[expId].addEventListener(brightcove.api.events.MediaEvent.PROGRESS, onMediaProgressFired); } } // This is gonna be fired on every Begin, Play, Complete, Stop, Pause, Seek Events function onMediaEventFired(e) { var d = e.media.publishedDate; var c = e.media.creationDate; var action = e.type.replace("media", "").toLowerCase(); if (action == "stop") action = "pause"; if (Math.floor(100 * e.position / e.duration) > 99 && action == "pause") { return; } utag.link({ 'eventName': 'video interaction', 'video_interaction': 'video ' + action, 'video_id': e.media.id, 'video_name': e.media.displayName, 'video_description': e.media.shortDescription, 'video_length': e.duration, 'video_creation_date': [c.getFullYear(), (c.getMonth() + 1).padLeft(), c.getDate().padLeft()].join('-') + ' ' + [c.getHours().padLeft(), c.getMinutes().padLeft(), c.getSeconds().padLeft()].join(':'), 'video_publish_date': [d.getFullYear(), (d.getMonth() + 1).padLeft(), d.getDate().padLeft()].join('-') + ' ' + [d.getHours().padLeft(), d.getMinutes().padLeft(), d.getSeconds().padLeft()].join(':'), 'video_category': null, 'video_publisher_id': e.media.publisherId, 'video_publisher_name': e.media.publisherName, 'video_thumbnail': e.media.customFields.imagepath, 'video_codec': e.rendition.videoCodec, 'video_size': e.rendition.size, 'video_provider': 'brightcove' }); } // Video Progress Tracking function onMediaProgressFired(e) { var divisor = 25; var pct = Math.floor(100 * e.position / e.duration); var progress_point = divisor * Math.floor(pct / divisor); if (progress_point == 0) { //dont sent event on 0% progress return; } if (bcPlayers[expId]["progress_already_fired"][progress_point]) { return; } bcPlayers[expId]["progress_already_fired"][progress_point] = true; var d = e.media.publishedDate; var c = e.media.creationDate; utag.link({ 'eventName': 'video interaction', 'video_interaction': 'video percent ' + progress_point, 'video_id': e.media.id, 'video_name': e.media.displayName, 'video_description': e.media.shortDescription, 'video_length': e.duration, 'video_creation_date': [c.getFullYear(), (c.getMonth() + 1).padLeft(), c.getDate().padLeft()].join('-') + ' ' + [c.getHours().padLeft(), c.getMinutes().padLeft(), c.getSeconds().padLeft()].join(':'), 'video_publish_date': [d.getFullYear(), (d.getMonth() + 1).padLeft(), d.getDate().padLeft()].join('-') + ' ' + [d.getHours().padLeft(), d.getMinutes().padLeft(), d.getSeconds().padLeft()].join(':'), 'video_category': null, 'video_publisher_id': e.media.publisherId, 'video_publisher_name': e.media.publisherName, 'video_thumbnail': e.media.customFields.imagepath, 'video_codec': e.rendition.videoCodec, 'video_size': e.rendition.size, 'video_provider': 'brightcove' }); } } // CODE END } catch (e) {}
This works great in the console when I try it, and I can see the utag.link calls go by for the video progression in debug mode in the console. However, when I put this code in a Javascript Extension scoped to DOM Ready, nothing happens; the utag.link calls are not sent.
Am I missing something?
Thanks!
04-12-2016 02:39 PM - edited 04-12-2016 02:44 PM
04-12-2016 02:41 PM - edited 04-12-2016 02:43 PM
Hello @audrey_poulin. Have you seen this video?
Let's see if this will work for you.
@Paul Jinx!
Hi,
Yes, and I did implement event tracking for several other things for my GA tag.
My issue is with the video listener in the Javascript extension.
When I use the listener directly in the console with the Tealium debug cookie, my utag.link fires without a hitch :
However, when I implement the same code that I pasted in my first post in a Javascript extension scoped to DOM ready, the utag.link calls are not sent (I do not see them in my console in debug mode as I do when I paste the listener in my console).
Thanks
04-13-2016 08:05 AM - last edited on 04-13-2016 11:58 AM by kathleen_jo
Hey @audrey_poulin,
When setting up video tracking in the past, I've had similar experiences. Whenever I was having the same behavior, wherein the code works just fine when pasted and run in console, but doesn't run when loaded in a JS Code extension, it was because of a timing issue. Specifically the JS Code extension was running before the video player had loaded on the page. When I was running the code in console, I had no problem because that was usually well after the page had finished loading. I'm not familiar with the exact circumstances you're working in, but you can try changing the scope of the JS Code extension to DOM Ready, so it waits for the DOMReady signal before trying to run your tracking code. However, if the videos are being loaded in an AJAX fashion, that is the video player isn't loaded until some action by the visitor is taken, you might have to use something like a SetTimeOut or SetInterval function to check for the presence of the video player.
04-13-2016 12:44 PM - last edited on 04-13-2016 04:30 PM by kathleen_jo
Hi @Seth,
Yes, my extension was scoped to DOM Ready, and the videos are static (loaded on page load).
I opened a ticket with support, hopefully they can see what's wrong there.
Thanks!
Copyright All Rights Reserved © 2008-2023