Lesson activity navigation control

A client asked me last week how they could force their students to first watch a video in the Lesson activity, before continuing to the next page.

They provide videos in the lesson activity. The students need to watch the video, then proceed to answer a few questions about the video. The students were skipping the video and then answering the questions incorrectly. The video is an embedded YouTube video.

My immediate response was that it wasn’t possible. Well, it turns out you can hide the button until the video has finished. Naturally the students can drag the control to the end, so there is that. I guess with a little more time one may be able to control the player as well. Fortunately in South Africa – with our bandwidth – you won’t be doing to much dragging.

Anyway on to the code. I added all the code to mod->lesson->view.php

Step 1 – At the top of the page
<!DOCTYPE html>
<html lang=”en”>
<meta charset=”UTF-8″>
<title>Document</title><script src=”http://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js”></script>


Step 2 – Check if the content contains a youtube video
line 391 – just after “$lessoncontent = $lessonoutput->display_page($lesson, $page, $attempt);”
$youtube = strpos($lessoncontent, ‘youtube’);       // check if there is a youtube video
Step 3 – Get the video url and then the id
// get the id of the video
$pattern = ‘%(?:https?://)?(?:www\.)?(?:youtu\.be/| youtube\.com(?:/embed/|/v/|/watch\?v=))([\w-]{10,12})[a-zA-Z0-9\< \>\”]%x’;
$result = preg_match($pattern, $lessoncontent, $matches);$vidURL = $matches[0];          // url of embed video
//$vidID = $matches[1];           // 0Bmhjf0rKe8 NOTE: this does not return the correct id

function youtube_id_from_url($url) {
$pattern =
‘%^# Match any youtube URL
(?:https?://)?  # Optional scheme. Either http or https
(?:www\.)?      # Optional www subdomain
(?:             # Group host alternatives
youtu\.be/    # Either youtu.be,
| youtube\.com  # or youtube.com
(?:           # Group path alternatives
/embed/     # Either /embed/
| /v/         # or /v/
| /watch\?v=  # or /watch\?v=
)             # End path alternatives.
)               # End host alternatives.
([\w-]{10,12})  # Allow 10-12 for 11 char youtube id.
$result = preg_match($pattern, $url, $matches);
if (false !== $result) {
return $matches[1];
return false;

$vidID = youtube_id_from_url($vidURL);

//print_r(‘id  ‘.$vidID);
//print_r(‘url ‘.$vidURL);

Step 4 – js script
script src=”http://www.youtube.com/player_api”></script><script>
has_video = <?PHP echo $youtube; ?>;            // check if there is a youtube video
var video_id = <?PHP echo ‘”‘.$vidID.'”‘; ?>;       // assign an id to the iframe

// stop the iframe from loading
if (navigator.appName == ‘Microsoft Internet Explorer’) {
} else {

if(has_video > 0) {
$(‘.singlebutton’).css(“display”,”none”);   // hide the Submit button
$(‘<div id=”player” style=”border: 1px solid #DDD;”></div>’).appendTo(“.mediaplugin_youtube”);

// create youtube player
var player;
//var video_id = <?PHP echo ‘”‘.$vidID.'”‘; ?>;

function onYouTubePlayerAPIReady() {

console.log(‘the video id is: ‘ + video_id);

player = new YT.Player(‘player’, {
videoId: video_id,
events: {
‘onReady’: onPlayerReady,
‘onStateChange’: onPlayerStateChange

// autoplay video
function onPlayerReady(event) {

// when video ends
function onPlayerStateChange(event) {
if(event.data === 0) {
console.log(‘video done’);
$(‘.singlebutton’).css(“display”,”block”);   // show the Submit button


0 thoughts on “Lesson activity navigation control

  1. You could put the video in one lesson and the questions in a second lesson. If the video is, say, 10 minutes long, set the conditional activity settings for lesson 2 to require the student to spend 10 minutes in lesson 1 before accessing it.

Leave a Reply

Your email address will not be published. Required fields are marked *