Tracking how long participants watch YouTube video | XM Community
Skip to main content

Hi, I am trying to record the time a participant watches an embedded video by tracking the time lapsed on page when a participant presses play and when they press pause. I currently have put the below JavaScript (provided by AI support -- I am not very familiar with JS) in the individual question (each on their own page with nothing but the qualtrics hidden timing question to know when they click to the next page), created embedded fields with the two variable names (image attached for verification, this is at the very start of my survey), and added <script src="https://www.youtube.com/iframe_api"></script> to my header (image also attached) However, there are no metrics showing in my data, just two empty column called FirstPlayTime and FirstPauseTime. I tried with the simple layout and flat layout, tested in different browsers on both published and preview versions. Any guidance would be much appreciated, thank you!

 

Qualtrics.SurveyEngine.addOnload(function()
{
    /*Place your JavaScript here to run when the page loads*/

});

Qualtrics.SurveyEngine.addOnReady(function() {
    console.log("Survey Engine Ready");
    
    // Load the YouTube IFrame API
    var tag = document.createElement('script');
    tag.src = "https://www.youtube.com/iframe_api";
    var firstScriptTag = document.getElementsByTagName('script')n0];
    firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

    // Function to create the YouTube player
    window.onYouTubeIframeAPIReady = function() {
        console.log("YouTube IFrame API Ready");
        var iframe = document.querySelector('iframe');
        if (iframe) {
            console.log("Iframe found");
            var player = new YT.Player(iframe, {
                events: {
                    'onStateChange': function(event) {
                        if (event.data == YT.PlayerState.PLAYING) {
                            console.log("Video playing");
                            if (!Qualtrics.SurveyEngine.getEmbeddedData('FirstPlayTime')) {
                                var firstPlayTime = new Date().getTime();
                                Qualtrics.SurveyEngine.setEmbeddedData('FirstPlayTime', firstPlayTime);
                                console.log("First Play Time: " + firstPlayTime);
                            }
                        } else if (event.data == YT.PlayerState.PAUSED) {
                            console.log("Video paused");
                            if (!Qualtrics.SurveyEngine.getEmbeddedData('FirstPauseTime')) {
                                var firstPauseTime = new Date().getTime();
                                Qualtrics.SurveyEngine.setEmbeddedData('FirstPauseTime', firstPauseTime);
                                console.log("First Pause Time: " + firstPauseTime);
                            }
                        }
                    }
                }
            });
        } else {
            console.log("Iframe not found");
        }
    };
});

Qualtrics.SurveyEngine.addOnUnload(function()
{
    /*Place your JavaScript here to run when the page is unloaded*/

});

 

 

IF NEEDED, this is the code for the youtube video:
<iframe title="YouTube video player" style="width:100%" src="https://www.youtube.com/embed/oB2AYcZfc9Q?si=9_EkHg4q71ehTSnq?enablejsapi=1" height="400"></iframe>

 

 

@nallard Your embedded link is wrong, 2nd querryString should be “&“ instead of “?”
https://www.youtube.com/embed/oB2AYcZfc9Q?si=9_EkHg4q71ehTSnq&enablejsapi=1

Use this JS instead to pass security policies. Keep in mind, the times are in miliseconds

Qualtrics.SurveyEngine.addOnload(function() {
var iframe = document.querySelector('iframe');
if (iframe) {
var player = new YT.Player(iframe, {
events: {
'onStateChange': function(event) {
if (event.data == YT.PlayerState.PLAYING) {
console.log("Video playing");
if (!Qualtrics.SurveyEngine.getEmbeddedData('FirstPlayTime')) {
var firstPlayTime = new Date().getTime();
Qualtrics.SurveyEngine.setEmbeddedData('FirstPlayTime', firstPlayTime);
console.log("First Play Time: " + firstPlayTime);
}
} else if (event.data == YT.PlayerState.PAUSED) {
console.log("Video paused");
if (!Qualtrics.SurveyEngine.getEmbeddedData('FirstPauseTime')) {
var firstPauseTime = new Date().getTime();
Qualtrics.SurveyEngine.setEmbeddedData('FirstPauseTime', firstPauseTime);
console.log("First Pause Time: " + firstPauseTime);
}
}
}
}
});
} else {
console.log("Iframe not found");
}
});

Hope it can help you


@Nam Nguyen Thank you so much! I really appreciate your help … unfortunately I am still not getting any metrics. Is there anything else I need to do in the embedded data part on survey flow to pull through the data? All I did was create the variable name but I didn’t set a value


@nallard Press F12 when previewing to see if the log confirm that the code is working

The setEmbedded Data block, do you put it before or after the video Question block. You have to declare the field name before getting into question

Then you will get what you want
 



 


I get this error message, is there anything I can do to fix this? (I really really appreciate your responsiveness and helpfulness)

 

 


I get this error message, is there anything I can do to fix this? (I really really appreciate your responsiveness and helpfulness)

 

 

@nallard Got it, change the function setEmbeddedData in the code to setJSEmbeddedData


Thanks! It looks like we are getting closer because it is capturing the times but still not showing in the dataset. (I also changed getembeddeddata to getJSembedded data but let me know if that wasn’t correct) I am currently getting the below when I do f12. I attached my current code as well. Thanks again! Hoping we can get this solved, I am very grateful for your assistance.

 

 

Qualtrics.SurveyEngine.addOnload(function()
{
    /*Place your JavaScript here to run when the page loads*/

});

Qualtrics.SurveyEngine.addOnload(function() {
    var iframe = document.querySelector('iframe');
    if (iframe) {
        var player = new YT.Player(iframe, {
            events: {
                'onStateChange': function(event) {
                    if (event.data == YT.PlayerState.PLAYING) {
                        console.log("Video playing");
                        if (!Qualtrics.SurveyEngine.getJSEmbeddedData('FirstPlayTime')) {
                            var firstPlayTime = new Date().getTime();
                            Qualtrics.SurveyEngine.setJSEmbeddedData('FirstPlayTime', firstPlayTime);
                            console.log("First Play Time: " + firstPlayTime);
                        }
                    } else if (event.data == YT.PlayerState.PAUSED) {
                        console.log("Video paused");
                        if (!Qualtrics.SurveyEngine.getJSEmbeddedData('FirstPauseTime')) {
                            var firstPauseTime = new Date().getTime();
                            Qualtrics.SurveyEngine.setJSEmbeddedData('FirstPauseTime', firstPauseTime);
                            console.log("First Pause Time: " + firstPauseTime);
                        }
                    }
                }
            }
        });
    } else {
        console.log("Iframe not found");
    }
});

Qualtrics.SurveyEngine.addOnUnload(function()
{
    /*Place your JavaScript here to run when the page is unloaded*/

});

 

 

YOUTUBE QUESTION CODE
<iframe title="YouTube video player" style="width:100%" src="https://www.youtube.com/embed/oB2AYcZfc9Q?si=9_EkHg4q71ehTSnq&enablejsapi=1" height="400"></iframe>

 

HEADER CODE
<script src="https://www.youtube.com/iframe_api"></script>


@nallard 
I think I found the problem. Are you using simple layout? Because setEmbeddedData worked for me but setJSEmbeddedData doesnt. So you have 2 choice:

1. Dont use simple layout and use setEmbeddedData

2. If you have to use simple layout, follow this post 

Change the field name in the surveyflow and add additional header.
Let me know if it solve the problem
 


It’s working!!! (using flat layout with setEmbeddedData). Wow, thank you so much!!!! You were very helpful. (if you happen to easily know any code to make it only record the very first play and the very last pause, or the number of play/pause clicks total on the player, if not no worries. thank you again!)


Leave a Reply