HTML 5 video & Mootools

This is about scripting the HTML 5 video-tag with Mootools 1.2.

One might ask, what is special about the video tag? At the first look nothing, it’s a HTML-element like any other. But if you try to use some mootools functions (adding events or querying properties) you soon realize that it doesn’t work out of the box in the current release. But there’s a workaround.

Read more about it at Lighthouse (mootools bugtracking) »

To put it briefly: To access video properties (like $(‘myvid’).currentTime) or to attach new events (like volumechange) via mootools, you can use this workaround:

var media_events = {
    loadstart: 2, progress: 2, suspend: 2, abort: 2,
    error: 2, emptied: 2, stalled: 2, play: 2, pause: 2,
    loadedmetadata: 2, loadeddata: 2, waiting: 2, playing: 2,
    canplay: 2, canplaythrough: 2, seeking: 2, seeked: 2,
    timeupdate: 2, ended: 2, ratechange: 2, durationchange: 2, volumechange: 2
Element.NativeEvents = $merge(Element.NativeEvents, media_events);
var media_properties = [
	'videoWidth', 'videoHeight', 'readyState', 'autobuffer',
	'error', 'networkState', 'currentTime', 'duration', 'paused', 'seeking',
	'ended', 'autoplay', 'loop',  'controls', 'volume', 'muted',
	'startTime', 'buffered', 'defaultPlaybackRate', 'playbackRate', 'played', 'seekable' // these 6 properties currently don't work in firefox		
	Element.Properties.set(prop, {
		set: function(value){
			this[prop] = value;
		get: function(){
			return this[prop];

Please note: This is only a quick workaround until it’s implemented in mootools-core.

How to realize video playback controls via mootools

You can see everything in the demo below


This is quite straightforward (using above workaround):

<button onclick="$('myvid').set('currentTime', 0)">rewind</button>
<button onclick="$('myvid').play()">play</button>
<button onclick="$('myvid').pause()">pause</button>
Showing the current playback time

We use a span to display the current time of the video playback and to update it continously we use the timeupdate-Event like this:

$('myvid').addEvent('timeupdate', function(an_event){
	$('timemeter').set('html', this.get('currentTime').toFixed(1));
Controlling volume via buttons and displaying it

Also no rocket science, but we have to look at not exceeding the limits for volume (from 0.0 up to 1.0):

<button onclick="$('myvid').set('volume', $('myvid').get('volume') < .1 ? 0.0 : $('myvid').get('volume') - 0.10)">vol-</button>
<button onclick="$('myvid').set('volume', $('myvid').get('volume') > .9 ? 1.0 : $('myvid').get('volume') + 0.10)">vol+</button>
<span id="volmeter">1.0</span>

And we want to show the current volume as a number. Therefore we use the “volumechange”-event and update a simple SPAN every time this event is being fired:

$('myvid').addEvent('volumechange', function(an_event){
	$('volmeter').set('html', this.get('volume').toFixed(1));
Adding a mute-button

The muted-state of the video overrides the current volume setting. It’s a toggle-button (on/off), so the implementation is also quite straightforward:

<button id="mutebutton" onclick="$('myvid').set('muted', !$('myvid').get('muted'))">mute</button>
Controlling volume via a slider

Buttons are okay, but usually we’re used to control the volume via a slider or knob. Therefore let’s use the mootools Slider (from mootools.more) to control the volume in ten steps.

First we need a container and a knob, here quickly done with a paragraph and a button:

<p id="volSliderBg" style="width: 100px; border: 1px solid #75838a;">
	<button id="volSlider">vol</button>

And now we setup the mootools Slider and use its onComplete event to change the volume accordingly:

var mySlider = new Slider('volSliderBg', 'volSlider', {
    range: [0, 100],
    wheel: true,
    snap: true,
    steps: 10,
    initialStep: 100,
    onComplete: function(step){
	$('myvid').set('volume', (step.toInt()/100));

As you can see by applying the above workaround we can very naturally use the new attributes and events to build our custom video controls.

All together now – Demo

Embedded video without controls
Scripted playback controls and time display

  play pause 0.0s

Scripted volume/mute controls and volume display


Alternative volume control (via slider)

Event and attribute information

Current Event:

Ready State:

Network State:


Next post will be showing how to realize a time slider (a movable bar showing the current position in the video which can be dragged to jump to a specific position).

And as always: Criticism, feedback etc. are very welcome.

12 Replies to “HTML 5 video & Mootools”

  1. 很好的教程,嘿嘿。

    (According to google translate: “Very good tutorial, Hei hei.”)

    1. Yes, a very good idea. I already started with a timeline-slider, but this is a bit tricky. But nevertheless: Either this will be the topic of a new post the next days or I’ll update this one here..

      1. Couldn’t help to play a bit, based on your code. First I created a slider to set the currentTime value. To also show the progress I did _not_ use the Slider.set() function, because that somehow messes things up.
        Instead I just changed the left position of the knob directly, actually bypassing the Slider. Also I checked the Slider.isDragging value, when it’s true I don’t set the position of the knob.

        I’ll put the code here but don’t know how legible it will be…
        $(‘myvid’).addEvent(‘timeupdate’, function(an_event){
        if (!mySlider.isDragging) {
        $(‘knob’).setStyle(‘left’, ($(‘timemeter’).getSize().x – $(‘knob’).getSize().x) * (this.get(‘currentTime’)/this.get(‘duration’)) + ‘px’);

        1. Cool, thanks! Yes, that’s what I meant by “tricky” :)…

          Slider.set() fires the change and complete events, so when moving the slider and calling set() this fires timeupdate on the video which (in return) again (re)-sets the slider…

          To check “is.Dragging” is a good idea, but I assume this breaks if you don’t *drag* the slider, but click in the white area to the left or right ?!

          And yes, setting the knob directly is also my solution. But I’m trying to find a solution which also works with different snap-values and things like left margin. You can see the first (ugly) try here, the thing is implemented as class, visible in the sourcecode:

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.