Celebrate Excellence in Education: Nominate Outstanding Educators by April 15!
Found this content helpful? Log in or sign up to leave a like!
Dear members of the Canvas Developer Group
For digital exams, we need a media player that only plays video/audio files only once and prevents any possibility of playing the file a second time, pausing or rewinding the file. After a (quite long) search, we have found a player that does just that. On github we found a code, which only needs to be embedded on a web page (see here: https://github.com/tvandervossen/playonly/blob/main/index.html).
It works perfectly, the code can be embedded on an HTML page without any problems. However, it is not possible to embed the code in a canvas quiz, because there are also a few lines that have to be placed in the page header and we do not have access to the page header in canvas.
The specific question now are:
Do somebody knows a way to embed this code in a canvas quiz (i.e. classic quiz)? Is there a way to do it without the header definitions? Or is there a possibility in Canvas to add this code in the page header somehow?
Due to our very (!) limited coding skills we do need help from this great community...
Many thanks in advance for your support and best regards
Samuel
Solved! Go to Solution.
Ah, I assumed it was an online test that the students would be taking off campus - but then it seems that the solution you found is good! All you gotta do is take this HTML snippet:
<p><video class="exam-video" style="width: 100%; height: 100%;" src="INSERT-LINK" controls="controls"></video></p>
And insert it into the quiz question (using the HTML editor). Replace where it says "INSERT-LINK" with the link to the video you want to play - retain the "" around the link. This has to be a direct link to the video and not something an embed link from YouTube or Vimeo.
This is a paragraph with a video in it, scaling 100% meaning it will scale to the max size of the quiz question window (and it will respond if the window is resized). It has a special class called "exam-video" which we will be using to target it's video controls for removal. We handle this with JavaScript, so you will need to upload a JavaScript file in the Canvas account themes. This is the JS you need:
if (document.getElementsByClassName("exam-video") != null){ const exam_video = document.querySelector(".exam-video") exam_video.addEventListener("play", (event) => { exam_video.removeAttribute("controls"); }); }
This works a little different than the GitHub project you posted, issue being that Canvas doesn't allow inline-JavaScript in the Rich Content Editor and it will be erased upon saving the content. But basically, this little script checks - every time a page on the course account is loaded - if there's any elements on the page with the "exam-video" class and if true, it adds an event to the video that removes the video controls once the video plays.
You can get both the HTML and the JS file here: https://github.com/MichaelMarboe/remove_vidcontrols
Then, go into your Canvas instance and open the sub-account that has the course with the exam quiz in it. Select Themes on the left-side menu, open your current theme, select Upload in the top left corner, find JavaScript and select the JavaScript file on your computer. NB: If there's already a JavaScript file here, you already have custom JavaScript and you will need to make a file that has both this code and mine (put it in the end of the file using something like Sublime Text to edit it). Hit Preview, Save and then Apply and you should be up and running. 🙂
NB: This won't work on more than the first exam-video per page load. Also, do some tests once it's up and running - I only tested it in a single question in a classic quiz (not the New Quizzes but it should work the same).
Edit: I only tested this in Firefox. The script will use whatever standard, basic video controls the browser has (and they can vary a bit) but if the special lockdown browser you're using doesn't have basic video controls in it, this may not work at all.
You don't need to access to the page headers to pull this off and you could actually implement it quite easily. But it's not a good solution in practice.
The GitHub project you linked utilizes the .remove() function which will simply remove an element from the page, in this scenario the play button in the video player after a user clicks it. But just off the top of my head I can think of four different ways of circumventing this measure but most notably, a student could simply reload the page by hitting update in their browser and the button would appear again. There is no way to prevent them from doing this and only by tracking their page views would you be able to determine if they did it - and that would probably create some even more challenging legal issues, but I'm no expert here. But even if this was legally fine, there are still many other ways to circumvent the measure.
While it's technically possible to have a video server only show a video once and then closing access, it's not realistic. You'd need students to sign in, you'd need a system to evaluate if the student has seen the video yet, you'd need to account for what happens if a student's computer crashes while they're watching it and I could keep going, it's a huge project.
From a technical stand-point it seems borderline impossible to prevent a student from viewing the video more than once so if I was you, I'd opt for a different strategy. Essentially, you can't design an exam around anything on the web only being viewable once because even if the page prevents a re-watch/reload or what have you, you cannot account for screen recordings, page downloads, copy-pastes etc. and you might easily end up underestimating the students' technical capabilities in this day and age what with ChatGPT around.
I would try to work with it instead of against it, somehow... I think by designing an examination that doesn't revolve around a video only being viewable one time. But yeah, this is more in the area of tuition design than technical development.
Edit: But if the .remove functionality is sufficient for you, I can help, just let me know.
Dear @michael5
Thank you very much for your reply to my post!
You bring up some very important points that we have already discussed intensively. In the original post, I didn't mention that we do the exams in combination with a lock-down browser. This prevents students from being able to reload the page, make a screen recording, download the file, check the source URL, or similar. In addition, we conduct all digital examinations on campus (no remote exam), with on-site examination invigilators. In short: We have intensively tested the described setting and have not yet found a way for students to cheat without at least the invigilators noticing.
In this respect, the points you mentioned are really important considerations, but the lock-down browser and on-site invigilators are very effective in preventing them.
By the way: The reasonableness of students only being allowed to listen to a file once can of course also be discussed, but our language lecturers simply want to have it that way (to check listening comprehension)...:-)
However, I would be very happy if you could help us adapt the code so that we can use the embed code without page header.
Thanks for your constructive feedback and many thanks in advance for your support!
Best regards
Samuel
Ah, I assumed it was an online test that the students would be taking off campus - but then it seems that the solution you found is good! All you gotta do is take this HTML snippet:
<p><video class="exam-video" style="width: 100%; height: 100%;" src="INSERT-LINK" controls="controls"></video></p>
And insert it into the quiz question (using the HTML editor). Replace where it says "INSERT-LINK" with the link to the video you want to play - retain the "" around the link. This has to be a direct link to the video and not something an embed link from YouTube or Vimeo.
This is a paragraph with a video in it, scaling 100% meaning it will scale to the max size of the quiz question window (and it will respond if the window is resized). It has a special class called "exam-video" which we will be using to target it's video controls for removal. We handle this with JavaScript, so you will need to upload a JavaScript file in the Canvas account themes. This is the JS you need:
if (document.getElementsByClassName("exam-video") != null){ const exam_video = document.querySelector(".exam-video") exam_video.addEventListener("play", (event) => { exam_video.removeAttribute("controls"); }); }
This works a little different than the GitHub project you posted, issue being that Canvas doesn't allow inline-JavaScript in the Rich Content Editor and it will be erased upon saving the content. But basically, this little script checks - every time a page on the course account is loaded - if there's any elements on the page with the "exam-video" class and if true, it adds an event to the video that removes the video controls once the video plays.
You can get both the HTML and the JS file here: https://github.com/MichaelMarboe/remove_vidcontrols
Then, go into your Canvas instance and open the sub-account that has the course with the exam quiz in it. Select Themes on the left-side menu, open your current theme, select Upload in the top left corner, find JavaScript and select the JavaScript file on your computer. NB: If there's already a JavaScript file here, you already have custom JavaScript and you will need to make a file that has both this code and mine (put it in the end of the file using something like Sublime Text to edit it). Hit Preview, Save and then Apply and you should be up and running. 🙂
NB: This won't work on more than the first exam-video per page load. Also, do some tests once it's up and running - I only tested it in a single question in a classic quiz (not the New Quizzes but it should work the same).
Edit: I only tested this in Firefox. The script will use whatever standard, basic video controls the browser has (and they can vary a bit) but if the special lockdown browser you're using doesn't have basic video controls in it, this may not work at all.
Dear Michael
Thank you very much for your reply!
We have tested it and unfortunately it doesn't work (tested in Chrome, Edge and Firefox).
I have added the following code to the JavaScript (at the very end of the JavaScript file):
/* Exam Video Setup */
if (document.getElementsByClassName("exam-video") != null){
const exam_video = document.querySelector(".exam-video")
exam_video.addEventListener("play", (event) => {
exam_video.removeAttribute("controls");
});
}
And on the page where the video is embedded, the following code:
<p><video class="exam-video" style="width: 50%; height: 50%;" src="https://tube.switch.ch/external/c9e8c62f" controls="controls"></video></p>
The video is displayed and can be played, but the controls do not disappear as expected. Have we done something wrong?
Thank you again for your great effort!
Best regards
Samuel
It was working when I tested it here but I only tested it once. Likely it has something to do with the page load order or because the script conflicts with something else in your local script - these are more complex problems but I've adjusted the script a little:
window.onload = (event) => {
const examVideo = document.getElementById("exam-video");
console.log("Element found");
examVideo.addEventListener("play", (event) => {
examVideo.removeAttribute("controls");
});
};
This should cause the script to wait until the page has loaded fully before looking for the object from which it has to remove the video controls. This won't work on multiple videos per page, only the first it finds.
If you already have a "window.onload" event in your existing JavaScript, you will probably need some technical support to add this correctly - there can only be one of these events so the inside of this code will have to go inside your existing onload event.
And updated HTML snippet (the previous one won't work):
video id="exam-video" style="width: 50%; height: 50%;" src="https://tube.switch.ch/external/c9e8c62f" controls="controls"></video>
Insert the correct link under src - also, width/height can be adjusted.
This works on our instance, so probably the best I can do without direct access. It causes a trivial error because Canvas loads the script twice (don't ask me why) but it doesn't appear to have any consequences. 🙂
To participate in the Instructure Community, you need to sign up or log in:
Sign In