xAPI Can Tell You What They Learned from the Video

Good learning content takes a lot of effortto create—especially video content. You want to make sure that the videos youcreate accomplish their goals. Do they convey the information you want them to?Are your students actually learning anything from them? Or, are they justletting the videos play?

In previous articles, I’ve covered the four steps to send an xAPIstatement and way to build statementstailored to your users and your environment. But there are other things toconsider when sending xAPI statements. You must consider what data you’ll needin order to show that the user learned anything, and how you can get it.

I presented on this topic at The eLearningGuild’s DevLearn 2016 Conference. For that presentation, I needed to show thefollowing steps to demonstrate that the user actually consumed the video, and whetheror not they learned from it, using a quiz question referring to a specificsegment of the video:

  • Show how to collect video consumption using xAPI
  • Show how to collect test answers using xAPI
  • Show how to issue a query for the video and test answer, and tie them together

In this article, I’ll focus on the first twosteps. I’ll discuss some of the decisions I made in how the data was collectedand how it was formatted. And, of course, I’ll share some code with you to helpyou get started. The third step will be covered in an upcoming article.

Build your programming skills

To effectively use xAPI for an effort likethis, you need to understand how you can construct the data to show acorrelation between video consumption and quiz performance. In making thiscomparison, there are three practical outcomes:

  • Theaverage user watches the video, but gets the answer incorrect. This could potentiallyindicate the video is not effective.
  • Theaverage user does not watch the video, but does get the answer correct. Thiscould indicate that the question was too simple.
  • Theaverage user who did watch the video answers the question correctly, and theaverage user who did not watch the video answers the question incorrectly. Thiswould tend to indicate that both the question and the video are effective.

By seeing the steps involved demonstratedwith practical code, you’ll have a better understanding of how you can designyour content to ensure you have the data you’ll need available and sent to yourlearning record store (LRS). Similarly, if your content isn’t performing aswell as expected, you’ll see how xAPI can help you narrow down where theproblems might be.

Getting started

In looking at how to demonstrate that thevideo is effective, I took a simple approach: Ask a question about a veryspecific piece of information presented in the video. In this case, I’m goingto ask what the first animal is that you see in the video. It’s a sillyquestion, agreed. But it illustrates the steps and concepts easily, and theanswer is only 15.6 seconds into the video.

Note: I’m using the video Big Buck Bunny to demonstrate this.Big Buck Bunny is open source andshared under the Creative Commons license, so you can use it and share it atwill. It’s also a pretty awesome video. (Editor’snote: The link will take you to a page where you must choose a version ofthe video suitable for your system. The files are large and take some time todownload.)

First, I’ll need to know if the student playedthat bit of the video. Then, I need to ask the question. So, I’ll need to thinkabout what information should be sent to the LRS when I capture that activity.

Capturing video playback

First things first: If we want to track videoconsumption, we’ll need some xAPI statements sent to reflect video playback. Butwe need to be smart about it. Do we want to send statements when the user hitsplay? Do we send statements when the user hits pause? And what data should besent? To answer those questions, we first must ask ourselves, “How will I usethe data I’m collecting?” and “How can I show that my videos are making adifference?”

Note: For the purposes ofthis discussion, I’m going to use vanilla HTML5 and the <video> tag.Using players such as JW Player or Video.js will use many of thesame concepts, although the code will vary a little—but not much.

Looking at this logically, it would be easy tosend a statement that says, “Anthony played the video from the xx second mark.”Then I could send another statement when I hit pause: “Anthony paused the videoat yy seconds.” But if I do that, when I pull the statements from the LRS, I mustmake sure they are in chronological order by when the event occurred. And I’dhave to compare multiple statements. So, what if I sent the start and end timesin a single statement? Then I only need to look at one statement at a time whenI do the reporting. If the Play timestamp is greater than 15.6, or the pause isless than 15.6, I can disregard that statement. That’s easier on both the frontand back sides of this. So, we’ll do that. Asbefore, we are using a bit of ADL code too.

I’ll need to know when the user starts toplay the video. That can be easily done by creating a variable with the starttime:

// When the user hits Play...vid.onplay = function() {    playFrom = (vid.currentTime).toFixed(2);}; // End onPlay()

This sets the variable playFrom to the timein the video when the user hit play. It also rounds it to the nearest hundredthof a second (e.g., 15.6012334 becomes 15.60).

Nowthat we have that piece, we can set up the onPause statement:

// When the user hits Pause...// onpause also runs when the video endsvid.onpause = function() {    console.log("The user has paused the video");    var statement = {        "actor": {            "mbox": "mailto:" + firstName + "@devlearn16.com",            "name": firstName,        "objectType": "Agent"        },        "verb": {            “id": "https://adlnet.gov/expapi/verbs/Play",            "display": { "en-US": "Video Played" }        },        "object": {            "id": "https://example.com/bigbuckbunnyvid.html",            "definition": {                "name": { "en-US": "Big Buck Bunny Video" },                "description": { "en-US": "sample description" }            },            "objectType": "Activity"        },        "result": {            "extensions":{                "https://example.com/xapi/period_start" : playFrom,                "https://example.com/xapi/period_end" : (vid.currentTime).toFixed(2)            }        },    };  //end statement definition    ADL.XAPIWrapper.sendStatement(statement, function(){}); }; // End onPause()

Not much new here from what we’ve seenbefore. But look at the Result section, lines 23 through 27. Here, you’ll seeI’m using extensions to send two keyed pairs: The period_start, paired with theplayFrom variable we defined in onPlay(), and period_end, paired with thetimestamp in the video when the user hit pause (both of which I’m also roundingto two decimal places). So, this statement will effectively say, “The userplayed the video from xx seconds to yy seconds.” By sending the statement onPAUSE and not on PLAY, we can get both the start and stop times in a singlestatement. This will be important later.

Tracking test responses

We know what parts of the video the studentwatched. Now there are two more things we need: what the student answered tothe question and where in the video that answer is found. For this, we need tolook at two things: building the quiz and sending the statement.

The easiest way to find out where the answerto the question is found is to simply add that to the answer when we send thatstatement. To build the quiz, I used the excellent xAPI Wrapper Tutorial from Tyler Mulliganas the basic starting point. And I built the quiz using a simple form:

<form onsubmit="submission()">    <label> What is the first animal you see in the video?</label>    <label><input type="radio" name="question1" ts="15.6" /> Flying Squirrel    </label>    <label><input type="radio" name="question1" ts="15.6"/> Bunny</label>    <label><input type="radio" name="question1" ts="15.6"/> Bird</label>    <label><input type="radio" name="question1" ts="15.6"/> Butterfly</label>    <br />    <input type="submit" /></form>

I ask a simple question: “What is the firstanimal you see in the video?” Then, for each answer, there are two attributesthat really matter: the answer given, and where in the video the answer can befound (denoted here by the variable “ts”).

When the user selects an answer, a functionis called to send the statement:

function answered(question, answer, ts) {            var statement = {        "actor": {            mbox": "mailto:" + firstname + "@devlearn16.com",            "name": firstname,            "objectType": "Agent"        },        "verb": {            "id": "https://adlnet.gov/expapi/verbs/answered",            "display": { "en-US": "answered" }        },        "object": {            "id": "https://example.com/xapi/quiz_tracker",            "definition": {                "name": { "en-US": "xAPI Video Quiz" },                "description": { "en-US":                 "Correlating quiz answers to video consumption" }            },            "objectType": "Activity"        },        "result": {            "response" : answer,            "extensions": {                "https://example.com/xapi/location" : ts            }        }    };    ADL.XAPIWrapper.sendStatement(statement, function(){}); }

Same as with the video, most of this looksfamiliar by now. But, again, notice the Result section. The response given is akeyed pair, with the answer the user selected as the value. Also, I’m usinganother extension recording the location of the answer in the video. In thiscase, another keyed pair with the ts variable sent as thevalue.

So, when the user selects, for example,“Bunny” as the answer, the page will build a statement that says “This useranswered Bunny to this question. And you can find the answer in the video at15.6 seconds.”

In conclusion…

We’ve started collecting data on who iswatching which parts of the video. We’re also collecting their answers on thequiz, and when in the video you can find the correct answer to that question. Next,we need to look at how to pull this information back out of the LRS and startto show whether the users who got the question correct are actually watchingthat part of the video or not. That’s when the fun starts.

Because this is what xAPI was built for: real-timeanalytics on how your users are consuming and applying your content! No needfor a dedicated reporting platform. The opportunities are wide open! This couldmean content can tailor itself to how your students have done in previousclasses. This could mean content tailors itself to how other students are doing in that same class. This could meanreporting on student progress in a course as you’re watching them take it.

And that means sending somexAPI queries!

Share:


Contributor

Topics:

Related