HTML5 video and JavaScript
Introduction
This tutorial shows how to add interactivity to HTML5 multimedia audio and video elements. Let us first recall the essentials. The audio
and video
multimedia elements are fully integrated in the page, which allows:
- Using HTML5 attributes to define controls (play, pause, etc.)
- Setting CSS style properties to change the appearance of media items
- Using JavaScript to control elements and even add complex interactions
Before dealing with use of HTML5 tags, it is useful to understand what is a multimedia element. An audio or video file is actually a "container" (ie Multimedia container format) that contains different types of files with data (e.g. audio or video streams, subtitles, metadata, etc.). The "container" is then compressed with a codec, i.e. a compression algorithm that follows, for example, the same principle as the JPEG algorithm for images.
There are two aspects to browser compatibility:
- The browser is compatible with audio and video tags from HTML5 (most recent versions of browsers are in most cases now).
- The browser is compatible with the format (and codec) of the audio / video file
To resolve both compatibility issues, there are solutions that will be discussed later in the page, including the use of a JavaScript library for HTML5 tag compatibility and the use of multiple source files for audio / video format compatibility.
The most popular video formats on the web (with their default video codec) are:
- Webm / VP8 with .webm extension
- Mp4 / H.264 with .mp4 extension
- Ogg / Theora with .ogv extension
Audio / Video with JavaScript
The advantage of having native elements for HTML5 media elements also implies the availability of an API to interact with audio
and video
elements with JavaScript . The Media Elements API provides:
- Methods (eg
play()
) that mainly control the reading of the media - Properties (eg
currentTime
) that allow to obtain or modify some media properties - Events (eg
timeupdate
) that trigger certain behavior based on media events
See the full list on W3Schools
Thanks to this ability to interact with the audio / video elements, we can mainly imagine three frameworks of use:
- Use JavaScript to create audio / video elements
- Use JavaScript to control the broadcasting of audio / video elements
- Use JavaScript to add interactive elements triggered by audio / video elements or that modify audio / video elements
In the rest of this section, we will illustrate some examples for each framework of use. The audio
and video
elements being very close, the examples will focus mainly on the video tag, but can be easily adapted to the audio tag.
Create audio / video elements
Add a simple video
The video
tag can be treated like any other tag in the DOM, so you can easily create one with the document.createElement("video")
and then set the video's attributes like source, controls, and so on. Here's an example that adds a video inside a div
with id = "myVideo" .
HTML code
<h2>Video inserted with JavaScript</h2>
<div id="myVideo"></div>
JavaScript code:
var c = document.getElementById ("myVideo");
// Create an element <video>
var v = document.createElement ("video");
// Set the attributes of the video
v.src = "http://tecfa.unige.ch/guides/html/html5-video/videos/state-of-wikipedia-480x272.ogv";
v.controls = true;
// Add the video to <div>
c.appendChild (v);
Which ultimately produces for the browser the following HTML code:
<h2>Video inserted with JavaScript</h2>
<div id="myVideo">
<video src = "video.mp4" controls = ""> </ video>
</div>
Add a video with multiple sources and subtitles
The same principle applies to insert a more complex video, with several source video formats and subtitles: always with the function document.createElement()
we can create source
and track
elements and insert them into a video
tag. Here is the JavaScript code:
<source lang = "JavaScript"> // Video with multiple sources and subtitles var cc = document.getElementById ("myVideo"); var vc = document.createElement ("video"); vc.controls = true; Source var source1 = document.createElement ("source"); source1.src = "video.mp4"; Source var source2 = document.createElement ("source"); source2.src = "video.webm"; // Track 1 var track1 = document.createElement ("track"); track1.kind = "subtitles"; track1.src = "subtitles_en.vtt"; track1.label = "English"; track1.srclang = "en"; track1.type = "text / vtt"; // Track 2 var track2 = document.createElement ("track"); track2.kind = "subtitles"; track2.src = "subtitles_en.vtt"; track2.label = "French"; track2.srclang = "fr"; track2.type = "text / vtt"; // Append everything vc.appendChild (source1); vc.appendChild (source2); vc.appendChild (track1); vc.appendChild (track2); cc.appendChild (vc); </ Source>
Which corresponds to the following HTML code:
<source lang = "HTML5"> <video controls = ""> <source src = "video.mp4"> <source src = "video.webm"> <track kind = "subtitles" src = "subtitles_en.vtt" label = "English" srclang = "en"> <track kind = "subtitles" src = "subtitles_en.vtt" label = "English" srclang = "en"> </ Video> </ Source>
There are also two JavaScript functions to avoid having to create DOM elements for sources and tracks:
canPlayType( type )
determines whether the browser supports a certain audio format, which allows you to create anif... else
cycle to determine thesrc
attribute instead of inserting multiple sources (see canPlayType on W3Schools )addTextTrack( kind,label,language )
allows you to add textual content without creatingtrack
elements. It is used with theaddCue()
function and thenew TextTrackCue
object to directly add the contents without an external file. (see addTextTrack on W3Schools )
Control audio / video with JavaScript
The JavaScript API for media elements provides 3 methods to control them:
play()
: starts (or restarts) playing the media filepause()
: stops playback at the current locationload()
: allows to substitute the active video in the player with another (for example, after changing the src attribute)
As a method (ie functions of an object), to execute them you must first identify the video (eg through the document.getElementById( id )
) and then associate the method with the dot notation:
var myVideo = document.getElementById ("myVideo"); myVideo.play ()
In addition, as objects, the audio / video elements also have several properties, among which are (in addition to the attributes shown above in the page):
currentTime
: time at a given time in reading the media file in secondsduration
: duration of the media file in secondsvolume
:volume
level (between 0.0 and 1.0)
Like any property of an object, they can serve two ways:
- Retrieve the value associated with a given property
- Associate a new value with a given property
Here is an example with the currentTime
property for a given instance of myVideo:
<source lang = "JavaScript"> console.log (myVideo.currentTime); // Displays in the console the playing time of a video
myVideo.currentTime = 60; // Move the player of the video to 60 seconds </ Source>
Create controls for a video in HTML
Thanks to the methods and properties associated with the video
tag, one can easily create custom controls that replace the standard controls added by the browser if the controls
attribute is declared. To do this, one must first have a video to handle, for which the controls attribute is not declared, even if the presence or absence of standard controls does not influence the operation of external controls.
<source lang = "HTML5"> <video id = "myVideo">
<source src = "http://tecfa.unige.ch/guides/html/html5-video/videos/state-of-wikipedia-480x272.ogv"> <source src = "http://tecfa.unige.ch/guides/html/html5-video/videos/state-of-wikipedia-480x272.mp4"> <source src = "http://tecfa.unige.ch/guides/html/html5-video/videos/state-of-wikipedia-480x272.webm">
</ Video> </ Source>
Then we add three buttons with the button
tag for the play, pause and stop controls.
<source lang = "HTML5"> <button id = "playBtn"> Play </ button> <button id = "pauseBtn"> Pause </ button> <button id = "stopBtn"> Stop </ button> </ Source>
Finally, we add the JavaScript code (in an external file or inside a script
tag):
<source lang = "JavaScript"> // Identify HTML elements var myVideo = document.getElementById ("myVideo"); var playBtn = document.getElementById ("playBtn"); var pauseBtn = document.getElementById ("pauseBtn"); var stopBtn = document.getElementById ("stopBtn");
// start play with play () playBtn.onclick = function () {
myVideo.play ();
}
// pause playback pauseBtn.onclick = function () {
myVideo.pause ();
}
// The stop () function does not exist, so we combine pause with currentTime = 0; stopBtn.onclick = function () {
myVideo.pause (); myVideo.currentTime = 0;
} </ Source>
Control an audio in background
In some applications, such as video games, there is often background music that repeats itself in time, but that the user can decide to cut if he wishes. There are several ways to create an audio element in background with HTML5, but the easiest way is to insert an audio element without setting the controls
attribute . In most web browsers that support the audio tag, this simply disguises the element.
Here is the HTML code that inserts audio with multiple sources as well as two ON and OFF buttons. So that the audio in background starts automatically it is necessary to declare the attribute autoplay
and so that it repeats the attribute loop
:
<source lang = "JavaScript"> <audio id = "audioBg" autoplay loop>
<source src = "http://tecfa.unige.ch/guides/html/html5-audio/audio/guitar.mp3"> <source src = "http://tecfa.unige.ch/guides/html/html5-audio/audio/guitar.ogg"> <source src = "http://tecfa.unige.ch/guides/html/html5-audio/audio/guitar.m4a"> <source src = "http://tecfa.unige.ch/guides/html/html5-audio/audio/guitar.wav"> Your browser does not support HTML5. Maybe you should upgrade.
</ Audio> </ Source>
To control the volume of the audio, instead of two buttons, you can use a range input (introduced with HTML5). For this type of input we can define:
- The minimum value
- The maximum value
- The scale of each variation (ie the "step")
The volume of an audio / video source ranges from 0 (no sound) to 1 (maximum volume compared to the current audio of the computer). Here is the code to add a range input to control the volume:
<source lang = "HTML5"> Audio volume <input type = "range" min = "0" max = "1" step = "0.1" value = "1" id = "audioVolume"> </ Source>
The basic volume of an audio / video source is the maximum value of 1, so that the range and the volume correspond we define a value
of 1 which will then be modified with the cursor. Each move corresponds to a change of 0.1 (defined by the step
value).
To associate the range with the volume of the audio we can use the onchange
event:
<source lang = "JavaScript"> // Identify HTML elements var audio = document.getElementById ("audioBg"); var audioVolume = document.getElementById ("audioVolume");
// associate volume with range type input audioVolume.onchange = function () {
audio.volume = audioVolume.value;
} </ Source>
It is also possible to create the audio element directly in JavaScript using the document.createElement("audio")
and specifying the autoplay
and loop
attributes.
Interactive audio / video with JavaScript
Earlier we have seen that audio / video elements can be controlled by other elements of the DOM and, consequently, also by DOM-related events. You can, for example, trigger a video based on the scroll of the page, or stop it if the user is writing something in a text field. On the other hand, it is also possible to modify other elements of the DOM according to events directly related to the audio / video element. Here is a non-exhaustive list of events related to audio / video:
onplay()
: event triggered each time the media starts or restarts;onpause()
: event triggered each time the media is paused;ontimeupdate()
: event triggered each time the playback time changes.
Ask a question at a given point in a video
In this example, we will display a question (using the JavaScript prompt()
) after 10 seconds of playing the video. If the user answers the question correctly, the video will resume normally, otherwise it will resume from the beginning. Here is the result in image:
Here is the HTML code:
<source lang = "HTML5">
Ask a question at a given point in a video
The question is displayed after 10 seconds, if the answer given is correct (ie Wikipedia), the video continues, if not it starts again from the beginning
<video id = "myVideo" controls>
<source src = "http://tecfa.unige.ch/guides/html/html5-video/videos/state-of-wikipedia-480x272.mp4"> <source src = "http://tecfa.unige.ch/guides/html/html5-video/videos/state-of-wikipedia-480x272.webm">
</ Video> </ Source>
And here the commented JavaScript code:
<source lang = "JavaScript"> // First identify the video in the DOM var myVideo = document.getElementById ("myVideo"); myVideo.ontimeupdate = function () {
// Remove the decimal numbers from the time var currentTime = Math.floor (myVideo.currentTime); if (currentTime == 10) { myVideo.pause (); // Ask the question promptly var r = prompt ("What is the video about?"#####136960$$ // check the answer if (r.toLowerCase () == "wikipedia") { myVideo.currentTime = 11; // Add a second otherwise the question will be displayed again; myVideo.play (); } else { myVideo.currentTime = 0; // Put the video back to 0; myVideo.play (); } }
} </ Source>
Test this example (Please note that using prompt is not ergonomic at all, it would be better to use an HTML form)