Latest Interactive Video broke xAPI code

I recently upgraded the interactive videos on my site to the latest version, and have discovered that the custom xAPI code I was using to check if the user answered all of the questions correctly or not has stopped working. I turned on showing the xAPI event statement in the console, but I do not see why my code would not still work. Here is a snippet of the code I'm using:

H5P.externalDispatcher.on('xAPI', function(event){

  //Only check total score if the object is not the child of a larger object (e.g., Course Presentation)
  if (event.getVerifiedStatementValue(['context','contextActivities','parent']) === null) {
    if(event.getScore() !== null){
      if (event.getScore() === event.getMaxScore() ){
        showNext();
      } 
    }
  } 
});

 

You can see a sample video (with event statement shown in console) here: https://foxylearning.com/tutorials/tlr/5/264147-0412

After watching the video (and answering the question correctly), a "next" button should appear on the right side of the screen (this is what the showNext() function referenced in the code snippet does).

Does anyone know what changed in IV to make this no longer functional and how I can make this work again? Thanks in advance for any help or guidance. 

Content types: 

I just discovered that the problem is with this conditional statement in my code: 

if (event.getVerifiedStatementValue(['context','contextActivities','parent']) === null) {

Apparently Interactive Video now includes "parent" information in the context, so this condition will not be met. I only want to show the next button when all of the questions in a video or a question set (quiz) have been answered correctly. Removing this clause makes the next button appear after just one question is answered correctly. What is the best way to check for this?

otacke's picture

Hi spazfox!

We may further increase the detail of xAPI statements, so it's probably better not to rely on some property being set or not.

My spontaneous answer would be to access instances of H5P content by looking at the array H5P.instances (which will only have one item if there's just one main content on the page). Interactive video exposes the variable "interactions". This array keeps track of all the subcontent, and there should be several ways to retrieve the information you need, e.g. using getxAPIData() to get the xAPI object (undefined if no xAPI supported by subcontent, e.g. text overlay) or retrieving each instance using getInstance() and calling getScore() and getMaxScore() on it (both are not available for content that doesn't track score) to compare both and determine completion this way.

Best,
Oliver

Thanks for the additional info, Oliver. In this case, though, I really just need to know when someone has reached the end of a video. Your documentation (https://h5p.org/node/3430) states that a "completed" statement should be generated, but I don't see one (at least in my test video containing just one multiple-choice question and no summary task). Is your documentation incorrect or outdated or am I missing something?

Hmm....it appears that the "completed" statement is provided for Interactive Video now only if a submit screen (https://h5p.org/july-2018-release-note) is used. That's unfortunate, as I really don't want to use a submit screen for all of my videos (many of which are very short clips, some as short as 2 seconds). Is this a feature or a bug? Is there any other way to detect the end of an interactive video without using a submit screen?

otacke's picture

Hi spazfox!

Interactive video also exposes its video object on which you can listen for the 'stateChange' event. The property data will contain 0 (= H5P.Video.ENDED) when the video ends.

Best,
Oliver

This is something beyond the xAPI statement that gets produced, I assume? Does this mean there is no way to detect when a video has ended from just the xAPI statement (unless a submit screen is used)? 

otacke's picture

Yes, theres's currently no xAPI statement that's triggered when the video has ended (although we have plans to enhance the xAPI capabilities for videos in the future.

If you have an environment that you can use to listen for H5P events on the externalDispatcher, why can't you retrieve the video instance from the Interactive Video instance to listen on?

Primarily because I'm not a developer and now I need to spend time figuring out how to do this (or hire someone to do it).

Based on this experience (and other experiences with H5P upgrades), it would be awesome if you could include some sort of quick release notes (specifying new features, bugs fixed, and any xAPI changes) near the "update" button of the H5P Hub (or whatever it's called) used to do upgrades in Drupal (and elsewhere?). Too many times now I've done a quick upgrade of a content type -- assuming it might simply add new features or fix some existing bugs -- only to find out some change has broken something with how it integrates with my site. I realize I need to be more careful about testing these upgrades on a development server first, but without an easy way to see everything that's changed, it can be difficult to know exactly what to test and what to keep an eye on. 

otacke's picture

Hi spazfox!

It's not that complicated ... This should do (it sure looks like a lot, but remove all the comments and the two extra constants that I assigned ...).

// Since I don't know your environment, let's stick with ES5.
const that = this;

/*
 * Get first instance of H5P.interactiveVideo -- will not work
 * properly if there are more instances of IV.
 */
this.interactiveVideo = H5P.instances.filter(function(instance) {
  return instance.libraryInfo &&
    instance.libraryInfo.machineName === 'H5P.InteractiveVideo';
})[0];

// Determine which interactions are scored and get their instances
this.numberScoredInteractions = interactiveVideo.interactions
  .filter(function(interaction) {
    return typeof interaction.getInstance().getScore === 'function' &&
      typeof interaction.getInstance().getMaxScore === 'function'
  }).length;

// Here's where the action takes place ...
interactiveVideo.video.on('stateChange', function(event) {
  /*
   * H5P.Video should be accessible here, but H5P.Video.ENDED could also
   * be replaced with 0 currently.
   */ 

  // Listen for video ended events only (not play or pause or others that might be introduced)
  if (event.data !== H5P.Video.ENDED) {
    return;
  }

  /* Check if user got maximum score (without retries)
   * >= because you never know ...
   */
  const completed = that.interactiveVideo.getScore() >=
    that.interactiveVideo.getMaxScore();

  /*
   * The function getAnsweredTotal() is not part of a so called "contract"
   * and might change, but this is not likely.
   */

  // Check if user answered at least one question
  const answeredOne = that.interactiveVideo.getAnsweredTotal() > 0;

  // Check if user answered all scored questions, not necessarily correct
  const answeredAll = that.interactiveVideo.getAnsweredTotal() ===
    that.numberScoredInteractions;

  /*
   * Here you can insert the constant that you need (completed or answeredOne
   * or answeredAll), so replace "answered" with one of the other two if
   * you prefer them. You could delete the others, too, of course.
   */
  if (answeredOne) {
    /*
     * Show button, you may have to set the context correctly if showNext()
     * is not accessible from this function.
     */
    showNext();
  }
});

 

I just checked our previous release note, and it contains a link to the release overview which lists changes (e. g. "Stop sending xAPI completed on end of the video. This is now done only by the submit screen." for Interactive Video). There's a lot we could improve however, that's true. In fact, the feature you described is supposed to be in the update of the Hub -- when we get around to it.

It's good practice not to update on a production system before testing everything on an identical (fairly) system. You should be quite safe if you have a standard install, but the more you customize your system, the more can break -- that's a downside of H5P being so open.

Best,
Oliver

It may not be complicated to you, but to someone who isn't immersed in the development of H5P code it sure is! It's also way overkill for what I need to do, but I've figured out a different workaround, so it's fine.

I understand that there are release notes, but it can be rather challenging to find them on your site and to understand which releases go with which updates presented in the Hub. There is no direct link or mention of versions or release notes at all in the Hub update process. Without knowing exactly what the changes are, it makes it much more difficult to know what to test and check on your development server/system. 

otacke's picture

Hi spazfox!

I am fully aware that the perception of difficulty is relative, but you seemed to show a fair understanding of how the xAPI statements work and how they can be listened to in order to trigger other things.

I already agreed on github that it's a good idea to have the release note information on the details page of the Hub, and you're correct again: The library version is not mentioned on the details page within the Hub. You'd have to check it on the library settings page of the host system. We should take care of this when we update the Hub.

Best,
Oliver

sbarab's picture

Yeah, all our interactive videos are now broken and requiring users to wait and notice the submit screen is not a great solution. Is there any hope of the H5P fixing it soon? It sounds straightforward and it would be great if it worked again. Also, getting the essay into column with the video working would be amazing. thanks so much.

sbarab's picture

it also makes all your documentation on your site around interactive video incorrect. it would be great if it sent out completed again. thanks.

sbarab's picture

Oliver, do you think they are going to reimplement "Completed" as a verb when the video finishes without having to look at the summary feature? thanks much. Also, any updates on essay integration with Column or Question Set? thanks much

otacke's picture

Hi sbarab!

There's still some stuff on the shelf regarding xAPI statements for interactive video, but I can't promise anything. However, if you look at my short code example above, you can see that there has always been and still is a way to properly detect when the video has finished. All that's necessary is to add a listener to the video instance. I dare to assert that this is not more complicated than listening for xAPI events.

Best,
Oliver

otacke's picture

Sorry, I forgot: The for Essay integration into Column/Question Set still is https://h5ptechnology.atlassian.net/browse/HFP-1888 with a dependency to https://h5ptechnology.atlassian.net/browse/HFP-1879.

I added this code, and when my video ends, i get state 2 (PAUSED) instead of ENDED. I removed the submit screen but that did not seem to change the behavior. Any ideas on how to make this work? 

Unfortunately the updated broke a lot of existing use cases for interactive video.

otacke's picture

Hi DaveB!

What code are you referring to? I just tried

H5P.instances[0].video.on('stateChange', function(event) {
  if (event.data === H5P.Video.ENDED) {
	console.log('video ended');
  }
  else {
	console.log('some other video event');
  }
});

on the example interactive video, and the ended event works as it should. I also tested a video that contains the submit screen: no problem either.

Best,
Oliver