Build a self guided Training course with api.video

June 28, 2021 - Doug in Analytics, Dynamic Metadata, JavaScript, NodeJS

Online video training is huge. There are many companies that offer video training courses where the course follows one video after another. The only way to continue in the course is to finish a video, and when the video is completed, the next video is unlocked. This ensures that the video course is taken in thr order designed by the insrtuctor, and that the stdents are not 'skipping' ahead through the coursework.

Other use cases for this might be a corporate training, where it is requried atht every employee wathces each video in a series to be compliant with the poicies of an organization (as a vetran of AT&T, I have taken months of this sort of training)

In this post, we'll walk through how you can build a video training app with api.video. There is a demo app on Github,and test it your self at training.a.video.

Connecting a session to a user

The first step in any training course will be to login your user. In the case of training a video, we'll skip a secure login form (it is just a demo!) and siply ask you to enter your name:

When you submit this form, we'll search through the videos connected to the course (in this case, they are hardcoded in the app as an array:

var videolist = ['vi47Q8KHXLYyaOoX2Yoznxqh','vi6QvU9dhYCzW3BpPvPsZUa8','vi1DrBc0VkPfedcfTc21U1TP'];
var videoDurations= [91,321,333];

Note, we also hardcoded in the duration of the 3 videos (but in a more dyanmic app, you can get the video duration from the video status endpoint.

Now for each of these videos, I have created dynamic metadata entry:

	"metadata": [
			"key": "classUserName",
			"value": "__classUserName__"

when the value of a metadata entry has two underscores on eitehr side of the value, any value can be applied to the metadata entry. In this case, we'll apply the username as the value. We can search for any video sessions that have the classUserName "Doug" for each of the videos in the training session. (in the code below, I am using the NodeJS client:

			currentPage = '1';
      pageSize = '25';
      var metadata = {'classUserName': userName};
      var params = { videoId, metadata, currentPage, pageSize};
      const result = client.rawStatistics.listVideoSessions(params);

This will result in the first 25 sessions where the variable userName (Doug) is saved as the classUsername metadata. (Of course, if you believe that you users might havemore than 25 sessions per video, you can expand that number up to 100 - but for a training course, 25 viewing sessions per video per user is probably more than adequate).

The response from this will be every session that the user has had for the video. For each of these sessions, we want to know iof the video was watched all the way through. We've written up this analysis of session events. As soon as we discover a session that has watched the video, we stop looking through the sessions.

How many videos to unlock?

This approach will then be completed for each video in the series, until we reach a video that has not been watched. This is done through the recursive function iterateVideos:

function iterateVideos(videolist, videoDurations, userName, videoCounter){
  return new Promise(function(resolve, reject){
      //soo take list of videos, and iterate until we know which video can be watched.
      console.log("testing video "+videoCounter);
      var videowatched  = videoWatched(videolist[videoCounter], videoDurations[videoCounter], userName);
        console.log("video "+videoCounter+ " "+ passfail);
          //video was watched, so lets check the next one
          if (videoCounter < videolist.length){
            var nextVideo = iterateVideos(videolist, videoDurations, userName, videoCounter);
            //the last video was watched so, stop and show all the videos...
            resolve(videoCounter -1);
          //video was NOT watched start wit this video
          console.log("resolve the counter of the first video not watched", videoCounter);
      }).catch((error) =>{


the videoWatched function checks each session to see if the video has been completed.

If the video has been completed, it returns true. Then we check the next video to see if it has been watched. (If we reach the end of the video list - we show all of the videos.).

If the video has not been watched - we know where to stop displaying playable videos, and we can display the page.

What the user sees

For this simple example with three videos, there are just three potential views:

  • If no videos have been watched - the first video will have no sessions, and the session analysis will stop immediately. The page will show the first video as playable, and the subsequent videos as locked.

  • If the first video has been completed, but not the second: the page will show the first two videos as playable, but the third video will still be locked.

  • If videos 1-2 are completed (or if all 3 videos are completed), all three videos appear as watchable.

Looking at the HTML

<iframe type="text/html" src="https://embed.api.video/vod/vi6QvU9dhYCzW3BpPvPsZUa8?metadata[classUserName]=Doug" width="960" height="320" frameborder="0" scrollling="no"></iframe>

See how each video adds the metadata[classUserName]=Doug this will ensure that any video session that is started on this page will be assigned to the user Doug. Once a video is watched, the user can refresh the page, and all the session data will be recalculated, and the next video will be unlocked.

Build your own video training app

With api.video, you can easily upload your videos for playbacl. Using our analytics and dynamic metadata, we can build a training application that unlockas each video as content is viewed. Try it your self at training.a.video and build your own based on our code on Github.


Developer Evangelist

Get started now

Connect your users with videos