Expand my Community achievements bar.

SOLVED

Reg : Youtube video tracking

Avatar

Level 3

Hi,

I am tracking YouTube video by using DTM. In normal HTML 5 video tracking is working fine using event based rules / event type selection like below .

Same way i am tracking YouTube videos. But i am not able to track. 

Kindly let me know how to track YouTube videos using DTM.

If you required any customization or documents related to this issue , please share your inputs.

Thanks & Regards,

Satish Kumar G

1 Accepted Solution

Avatar

Correct answer by
Level 10

Hi Satish ,

As discussed , Please find below Steps with Code to be implemented through DTM to track you tube videos through iframe.

1.Embed the video in an iframe with with the API turned on e.g. http://www.youtube.com/v/8pB5sRsX5OU?fs=1&rel=0&enablejsapi=1 on your webpage.

Please note that it is must to provide an "Id" to the iframe .Please see below code for more help.

<p>YouTube  video in iframe embed tag</p> <iframe id="player1" frameborder="0" width="425" height="344" allowfullscreen="1" title="YouTube video player" src="https://www.youtube.com/embed/wcv8zQo9HyU?enablejsapi=1">

2. Add the  Adobe Analytics Media tracking module to your Appmeasurement (or similar).It Should be placed somewhere after your config section and before the "DO NOT ALTER ANYTHING BELOW THIS LINE !".  In case of legacy implementation you need to have code version of H.15.1 or newer. You'll get this Media module from your Adobe Analytics Account  : Admin ----> Code Manager---->App Measurement ------> App Measurement Media Module.js

3. Add the following plugin into Head of the page just below DTM header code .

<script type="text/javascript" src="https://www.youtube.com/iframe_api"></script> <script type="text/javascript"> var video_obj=null; var video_length=0; var video_name='Movie name ' + new Date().getTime(); // 3. This function creates an <iframe> (and YouTube player) //    after the API code downloads. var player; function onYouTubeIframeAPIReady() { console.log('*** iFrame embed onYouTubeIframeAPIReady'); player = new YT.Player("player1", { events: { 'onReady': onPlayerReady, 'onStateChange': onPlayerStateChange } }); } // 4. The API will call this function when the video player is ready. function onPlayerReady(event) { // event.target.playVideo(); console.log('*** iFrame embed onPlayerReady ', player); } // 5. The API calls this function when the player's state changes. //    The function indicates that when playing a video (state=1), //    the player should play for six seconds and then stop. var done = false; function onPlayerStateChange(event) { console.log('*** iFrame embed onPlayerStateChange ' + event.data + ' --- YT Player state ' + YT.PlayerState.PLAYING, player.getCurrentTime(), player); /* if (event.data == YT.PlayerState.PLAYING && !done) { setTimeout(stopVideo, 6000); done = true; } */ video_name = player.getVideoData(); video_name = video_name.title; video_length = player.getDuration(); // if(event.data === YT.PlayerState.PLAYING && (event.data === 1 || event.data < 0)){ if((event.data === 1 || event.data < 0) && YT.PlayerState.PLAYING === 1){ //*-* PLAY console.log("*-* Player is on play mode " + event.data + ' ' + player.getCurrentTime(), s); if(player.getCurrentTime() === 0) { s.Media.open(video_name, video_length, 'Youtube Object Embed'); s.Media.play(video_name, player.getCurrentTime()); } else { s.Media.play(video_name, player.getCurrentTime()); } }else if(event.data === 2){ //*-* PAUSE --- CAN USE THIS FOR ENDING TOO =-- check on time -5 sec!! console.log("*-* Player is on pause mode " + event.data+' '+player.getCurrentTime()); s.Media.stop(video_name, player.getCurrentTime());//this will cause the monitor to have media.event='STOP' }else if(event.data === 3){ //*-* SKIPPING console.log("*-* Player is on skipping mode " + event.data); s.Media.stop(video_name, player.getCurrentTime());//this will cause the monitor to have media.event='STOP' }else if(event.data === 0){ //*-* Completed console.log("*-* Player has been completed " + event.data); s.Media.stop(video_name, player.getCurrentTime()); s.Media.close(video_name); } } function onYouTubePlayerReady(playerId) { video_obj=document.getElementById(playerId);//playerId video_obj.addEventListener("onStateChange", "onytplayerStateChange"); video_length= video_obj.getDuration(); console.log('*-* Youtube Video Ready - in call back function --- ' + playerId, 'video duration= ' + video_obj.getDuration(), 'video current time= ' + video_obj.getCurrentTime()); } function onytplayerStateChange(newState) { console.log("*-* Player's new state: " + newState); //-1 --> <0 is not started if(newState===1){ //*-* PLAY console.log("*-* Player is on play mode " + newState + ' ' + video_obj.getCurrentTime(), s); if(video_obj.getCurrentTime() === 0) { s.Media.open(video_name, video_length, 'Youtube Object Embed'); s.Media.play(video_name, video_obj.getCurrentTime()); // s.Media.play(video_name, video_obj.getCurrentTime(),5,'a segment name', 30); } else { s.Media.play(video_name, video_obj.getCurrentTime()); } }else if(newState===2){ //*-* PAUSE --- CAN USE THIS FOR ENDING TOO =-- check on time -5 sec!! console.log("*-* Player is on pause mode " + newState+' '+video_obj.getCurrentTime()); s.Media.stop(video_name, video_obj.getCurrentTime());//this will cause the monitor to have media.event='STOP' // s.Media.stop(video_name, video_obj.getCurrentTime());//this will cause the monitor to have media.event='STOP' //*-*if not used (ie. not pausing) then CLOSE will kick in when the video completes otherwise video completes will also send 'STOP' }else if(newState===3){ //*-* SKIPPING console.log("*-* Player is on skipping mode " + newState); s.Media.stop(video_name, video_obj.getCurrentTime());//this will cause the monitor to have media.event='STOP' }else if(newState===0){ //*-* Completed console.log("*-* Player has been completed " + newState); s.Media.stop(video_name, video_obj.getCurrentTime()); s.Media.close(video_name); } } </script>

4. After you insert the code in your project, you need to map the conversion variables and events you are using to track video.
 For code please see step 4 of my previous reply.

Thanks & Regards

Parit Mittal

 

View solution in original post

15 Replies

Avatar

Level 10

Hi Satish ,

DTM is a tool to allow you to do things faster. We can track HTML5 videos using event based rules in DTM.   However It doesn't have any out of the box functionality to track Videos provided by other different video providers ((Brightcove, Youtube, Vimeo, VideoJS, Flowplayer, etc.)

However if someone  uses the video service that has some sort of JavaScript API (Brightcove, Youtube, Vimeo, VideoJS, Flowplayer, etc.), we can use DTM to add the API code to listen for the different video events. It is required to load the code you need in a page load rule (make sure it loads at the correct spot, i.e. page top or page bottom), and that will setup the API and/or listeners to track the videos.  Then we have to define what we want to do when it comes to capturing and sending the video data.  we can use the Media Module implementation which won't require any additional settings in DTM.

Please see the following steps for tracking the "You tube Video" through Media Module Implementation.

1.Embed the video with with the API turned on e.g. http://www.youtube.com/v/8pB5sRsX5OU?fs=1&rel=0&enablejsapi=1&playerapiid=myytplayer on your webpage.

Note- * Please make sure you don't have two tags with the same ID, but make sure the tag has an ID that matches the playerapiid parameter

<p>Sample YouTube in OBJECT embed tag</p> <object id="myytplayer" width="425" height="344" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"> <param name="movie" value="http://www.youtube.com/v/AhgtoQIfuQ4?fs=1&rel=0&enablejsapi=1&playerapiid=myytplayer"></param> <param name="allowFullScreen" value="true"></param> <param name="allowscriptaccess" value="always"></param> <embed id="myytplayer2" src="http://www.youtube.com/v/AhgtoQIfuQ4?fs=1&rel=0wcv8zQo9HyU&enablejsapi=1&playerapiid=myytplayer2" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed> </object>

2. Add the  Adobe Analytics Media tracking module to your Appmeasurement (or similar).It Should be placed somewhere after your config section and before the "DO NOT ALTER ANYTHING BELOW THIS LINE !".  In case of legacy implementation you need to have code version of H.15.1 or newer. You'll get this Media module from your Adobe Analytics Account  : Admin ----> Code Manager---->App Measurement ------> App Measurement Media Module.js

3. Add the following plugin into your Appmeasurement (or similar) just before the Media Module code mentioned in Step2 .

var adytt={pl:[]};adytt.p=function(){var k=function(a,b){var c=a.indexOf('?');var d=a.indexOf('#'); if(c<0){return""}var e=a.substr(c+1);if(d>0){e=a.substring(c+1,d)}var f=e.split('&');var i;for(i=0; i<f.length;i++){var g=f[i].split('=');g[0]=unescape(g[0]);if(g[0]===b){g[1]=unescape(g[1]); if(g[1].indexOf('"')>-1){var h=/"/g;g[1]=g[1].replace(h,'\\"')}if(g[1].indexOf('+')>-1){var j=/\+/g; g[1]=g[1].replace(j,' ')}return g[1]}}return""};var l=function(a,b,c){if(typeof a==='object'&&a!==null) {if(a.attachEvent){a['e'+b+c]=c;a[b+c]=function(){a['e'+b+c](window.event)};a.attachEvent('on'+b,a[b+c])} else{a.addEventListener(b,c,false)}}};this.p=null;this.id="";this.op=false;this.pl=false;this.po=0; this.du=0;this.bl=0;this.tp=false;this.i=function(a){var b=0;if(typeof s!=="object"){b=3}if(!b) {this.p=document.getElementById(a);if(this.p){if(a.match(/^[a-z0-9]+$/i)){window['adyttsc'+a]=function(o) {adytt.pl[a].st(o)};this.p.addEventListener("onStateChange","adyttsc"+a)}else{this.p.addEventListener ("onStateChange","adytt.pl['"+a+"'].st")}var c=this;l(window,"unload",function(e){if(c.op) {if(typeof c.sc==='function'){c.sc(c.po,true)}}})}}else{}};this.sc=function(a,b){if(this.pl) {s.Media.stop(this.id,a);this.pl=false;this.tp=false}if(b&&this.op){s.Media.close(this.id);this.op=false; clearInterval(this.tf)}};this.st=function(a){this.tp=false;switch(a){case 0:this.sc(this.du,true);break; case 1:this.du=Math.floor(this.p.getDuration());if(!this.op){var b=this.p.getVideoUrl(); this.id="YT|"+k(b,'v');if(typeof adytt.getID==='function'){this.id=adytt.getID({url:b})} s.Media.open(this.id,this.du,"YouTube Embedded Player",{id:this.id});var c=this;this.tf=setInterval (function(){c.ti()},500);this.op=true}this.tp=true;break;case 2:this.sc(Math.floor(this.po),false);break; case 3:this.bl=this.p.getVideoBytesLoaded();this.po=this.p.getCurrentTime();if(this.bl===-1) {this.sc(Math.floor(this.po),true)}else{this.sc(Math.floor(this.po),false)}break;case-1:break; case 5:this.sc(Math.floor(this.po),false);break}};this.ti=function(){if(!document.getElementById(this.p.id)) {this.sc(this.po,true)}else if(this.p&&(this.p.getPlayerState()===1||this.tp)){this.po=this.p.getCurrentTime(); this.bl=this.p.getVideoBytesLoaded();if(this.tp&&this.bl>0&&!this.pl){this.pl=true;this.tp=false; s.Media.play(this.id,Math.floor(this.po))}}}};function onYouTubePlayerReady(a){a=decodeURIComponent(a); if(adytt.pl[a]){adytt.pl[a].sc(Math.floor(adytt.pl[a].po),true);delete adytt.pl[a]} adytt.pl[a]=new adytt.p();adytt.pl[a].i(a)} //adytt.getID = function(o) { return o.url; }; console.log(adytt);

 

4. After you insert the code in your project, you need to map the conversion variables and events you are using to track video.

s.loadModule("Media"); s.Media.onLoad = function() { console.log('**** MEDIA module loaded'); /*Configure Media Module Functions */ s.Media.autoTrack= false; s.Media.trackWhilePlaying=false; // s.Media.trackSecond=0; // set to 30 if milestone in seconds console.log('**** MEDIA module loaded1'); s.Media.completeByCloseOffset = true; //*** Enabled if you want to allow the video to be completed a few seconds before the actual end of the video s.Media.completeCloseOffsetThreshold = 10; s.Media.trackVars="events,eVar16,eVar17"; //**NOTE: Add additional data which will be pushed either in the plugin or on the page s.Media.trackEvents="event16,event17,event18,event19,event20,event21"; //**NOTE: Add additional data which will be pushed either in the plugin or on the page s.Media.trackMilestones="25,50,75"; s.Media.playerName="My TEst You tube video tracking"; s.Media.segmentByMilestones = false; s.Media.trackUsingContextData = true; console.log('**** MEDIA module loaded2'); s.Media.contextDataMapping = { "a.media.name":"eVar16", "a.media.segment":"", "a.contentType":"eVar17", "a.media.timePlayed":"event18", "a.media.view":"event16", "a.media.segmentView":"", "a.media.complete":"event17", "a.media.milestones": { 25:"event19", 50:"event20", 75:"event21" } } console.log('**** MEDIA module loaded3'); /* * can use the below IF wanna pass additional data --- Need to update s.Media.trackVars --- BUT we could potential set it on above var and avoid using the below */ s.Media.monitor =function(s, media){ console.log('**** MEDIA module loaded4'); console.log(media); //https://marketing.adobe.com/resources/help/en_US/sc/appmeasurement/video/video_mediamonitor.html console.log('in the video monitor, can help add additional evar, prop or events', media); if(media.event == "OPEN") { s.contextData = s.Media.contextDataMapping s.Media.track(media.name); } else if(media.event == "MILESTONE") { s.contextData = s.Media.contextDataMapping s.Media.track(media.name); } else if(media.event == "CLOSE") { s.contextData = s.Media.contextDataMapping s.Media.track(media.name); } } }

Please see the attached Sample App Measurement JS file for complete flow of code .

Also, please see the following link for more information on Video tracking -

https://marketing.adobe.com/resources/help/en_US/sc/appmeasurement/video/video_js.html

https://marketing.adobe.com/resources/help/en_US/sc/appmeasurement/video/video_ref_methods.html

https://marketing.adobe.com/resources/help/en_US/sc/appmeasurement/video/video_ref_variables.html

https://marketing.adobe.com/resources/help/en_US/sc/appmeasurement/video/video_js_sample.html

Thanks & Regards

Parit Mittal

Avatar

Level 3

Hi Parit Mittal,

Thank you for the quick response.

As mentioned, Same steps has been followed. But still i am not able to track my Youtube Video.

Note : We developed web site by using AEM.

Can you please take the web ex and resolve this issue and let me know your convenient time to send the web ex link.

Thanks & Regards,

Satish Kumar G

Avatar

Level 3

Hi Parit Mittal,

I am waiting for your response. Please help us to resolve this issue and do the needful.

Thanks & Regards,

Satish Kumar G

Avatar

Level 10

Hi Satish ,

Can we the screen sharing session today itself ?

Thanks & Regards

Parit Mittal

Avatar

Level 3

Hi Parit Mittal,

Can i share you the link now. or let me  know your convenient time ?

Thanks & Regards,

Satish kumar G

Avatar

Level 10

Hi Satish,

Instead of sharing the link . I would suggest to have a live connect session with me. I have sent you the details in a private message . Please let me know in case you suggest some other time.

Thanks & Regards

Parit Mittal

Avatar

Level 3

Hi Parit Mittal,

Below mentioned  timings are US based? We are in IST zone that means below mentioned timings are almost midnight for us :) 

If its fine for  you to start a webex session now?  web ex link has shared in a private message.

Or else please schedule live connect session as per IST timings( in between 9 AM to 7 PM) 

Thanks & Regards,

Satish Kumar G

Avatar

Level 3

Hi Parit,

As discussed , Please join the same web ex link @ 6 PM.

Regards,

Satish Kumar G

Avatar

Correct answer by
Level 10

Hi Satish ,

As discussed , Please find below Steps with Code to be implemented through DTM to track you tube videos through iframe.

1.Embed the video in an iframe with with the API turned on e.g. http://www.youtube.com/v/8pB5sRsX5OU?fs=1&rel=0&enablejsapi=1 on your webpage.

Please note that it is must to provide an "Id" to the iframe .Please see below code for more help.

<p>YouTube  video in iframe embed tag</p> <iframe id="player1" frameborder="0" width="425" height="344" allowfullscreen="1" title="YouTube video player" src="https://www.youtube.com/embed/wcv8zQo9HyU?enablejsapi=1">

2. Add the  Adobe Analytics Media tracking module to your Appmeasurement (or similar).It Should be placed somewhere after your config section and before the "DO NOT ALTER ANYTHING BELOW THIS LINE !".  In case of legacy implementation you need to have code version of H.15.1 or newer. You'll get this Media module from your Adobe Analytics Account  : Admin ----> Code Manager---->App Measurement ------> App Measurement Media Module.js

3. Add the following plugin into Head of the page just below DTM header code .

<script type="text/javascript" src="https://www.youtube.com/iframe_api"></script> <script type="text/javascript"> var video_obj=null; var video_length=0; var video_name='Movie name ' + new Date().getTime(); // 3. This function creates an <iframe> (and YouTube player) //    after the API code downloads. var player; function onYouTubeIframeAPIReady() { console.log('*** iFrame embed onYouTubeIframeAPIReady'); player = new YT.Player("player1", { events: { 'onReady': onPlayerReady, 'onStateChange': onPlayerStateChange } }); } // 4. The API will call this function when the video player is ready. function onPlayerReady(event) { // event.target.playVideo(); console.log('*** iFrame embed onPlayerReady ', player); } // 5. The API calls this function when the player's state changes. //    The function indicates that when playing a video (state=1), //    the player should play for six seconds and then stop. var done = false; function onPlayerStateChange(event) { console.log('*** iFrame embed onPlayerStateChange ' + event.data + ' --- YT Player state ' + YT.PlayerState.PLAYING, player.getCurrentTime(), player); /* if (event.data == YT.PlayerState.PLAYING && !done) { setTimeout(stopVideo, 6000); done = true; } */ video_name = player.getVideoData(); video_name = video_name.title; video_length = player.getDuration(); // if(event.data === YT.PlayerState.PLAYING && (event.data === 1 || event.data < 0)){ if((event.data === 1 || event.data < 0) && YT.PlayerState.PLAYING === 1){ //*-* PLAY console.log("*-* Player is on play mode " + event.data + ' ' + player.getCurrentTime(), s); if(player.getCurrentTime() === 0) { s.Media.open(video_name, video_length, 'Youtube Object Embed'); s.Media.play(video_name, player.getCurrentTime()); } else { s.Media.play(video_name, player.getCurrentTime()); } }else if(event.data === 2){ //*-* PAUSE --- CAN USE THIS FOR ENDING TOO =-- check on time -5 sec!! console.log("*-* Player is on pause mode " + event.data+' '+player.getCurrentTime()); s.Media.stop(video_name, player.getCurrentTime());//this will cause the monitor to have media.event='STOP' }else if(event.data === 3){ //*-* SKIPPING console.log("*-* Player is on skipping mode " + event.data); s.Media.stop(video_name, player.getCurrentTime());//this will cause the monitor to have media.event='STOP' }else if(event.data === 0){ //*-* Completed console.log("*-* Player has been completed " + event.data); s.Media.stop(video_name, player.getCurrentTime()); s.Media.close(video_name); } } function onYouTubePlayerReady(playerId) { video_obj=document.getElementById(playerId);//playerId video_obj.addEventListener("onStateChange", "onytplayerStateChange"); video_length= video_obj.getDuration(); console.log('*-* Youtube Video Ready - in call back function --- ' + playerId, 'video duration= ' + video_obj.getDuration(), 'video current time= ' + video_obj.getCurrentTime()); } function onytplayerStateChange(newState) { console.log("*-* Player's new state: " + newState); //-1 --> <0 is not started if(newState===1){ //*-* PLAY console.log("*-* Player is on play mode " + newState + ' ' + video_obj.getCurrentTime(), s); if(video_obj.getCurrentTime() === 0) { s.Media.open(video_name, video_length, 'Youtube Object Embed'); s.Media.play(video_name, video_obj.getCurrentTime()); // s.Media.play(video_name, video_obj.getCurrentTime(),5,'a segment name', 30); } else { s.Media.play(video_name, video_obj.getCurrentTime()); } }else if(newState===2){ //*-* PAUSE --- CAN USE THIS FOR ENDING TOO =-- check on time -5 sec!! console.log("*-* Player is on pause mode " + newState+' '+video_obj.getCurrentTime()); s.Media.stop(video_name, video_obj.getCurrentTime());//this will cause the monitor to have media.event='STOP' // s.Media.stop(video_name, video_obj.getCurrentTime());//this will cause the monitor to have media.event='STOP' //*-*if not used (ie. not pausing) then CLOSE will kick in when the video completes otherwise video completes will also send 'STOP' }else if(newState===3){ //*-* SKIPPING console.log("*-* Player is on skipping mode " + newState); s.Media.stop(video_name, video_obj.getCurrentTime());//this will cause the monitor to have media.event='STOP' }else if(newState===0){ //*-* Completed console.log("*-* Player has been completed " + newState); s.Media.stop(video_name, video_obj.getCurrentTime()); s.Media.close(video_name); } } </script>

4. After you insert the code in your project, you need to map the conversion variables and events you are using to track video.
 For code please see step 4 of my previous reply.

Thanks & Regards

Parit Mittal

 

Avatar

Level 3

Hi Parit,

Now we are able to track the youtube video in local environment. But in server showing below error message on console while click on YouTube play .

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://www.youtube.com' is therefore not allowed access. The response had HTTP status code 404.

Please help us to resolve this issue. PFA screen shot FYR.

Thanks & Regards,

Satish Kumar G

Avatar

Level 10

Hi Satish ,

The problem you stated above is a browser issue and not at all related to DTM. I would suggest to go through the following link to debug the same.

http://stackoverflow.com/questions/20035101/no-access-control-allow-origin-header-is-present-on-the-...

Thanks & Regards

Parit Mittal

Avatar

Level 3

Hi Parit,

In local environment website, We  configured the youtube and tested it's working. Note : Web site is not done by through AEM.

In server same steps i followed , but it's not working .  Note : Web site is developed by AEM component.

In appmeasurement js s.Media.monitor =function(s, media) this method is not loading in my web page console. PFA screen shot FYR.

If possible please arrange me the live connect session. 

Thanks & Regards,

Satish Kumar G

Avatar

Level 10

Hi , 

This seems to be an AEM issue because the same set of code is working for other website . Please contact your AEM developer to resolve the same.

Thanks & Regards 

Parit Mittal

Avatar

Level 2

Hi Parit,

I have tried this method but none of he YouTube video data is getting tracked in Adobe Analytics.

1. YouTube Iframe don have video id and API on page

   - for this i have create a JQuery function to append the Player ID and API (enablejsapi=1) in embedded YouTube iframe, this script is setup under DTM > Analytics > Customize Page Code After UI settings (custom code takes precedence)

1241891_pastedImage_5.png

Can you please have look and let me know  what is the best approach to configured the same.

Regards,

Vasim

Avatar

Level 10

Hi Vasim ,

The code you have used in step 3  ( var adytt ...........................)  is for tracking you tube videos that are embedded using object tag instead of iframe.

For tracking you tube videos embedded via iframe , Please see the following article :Marketing Cloud Help | How to track youtube videos using DTM?  and see step 3.

Regards

Parit