Odo Video

A lightweight html5 video wrapper.


IE9. No flash fallback. IE9 will need a classList polyfill.


screenfull.js. Assumes ES2015 Promise and Object.assign are available.




You may also add any attributes you normally would to the <video> element.

<div class="odo-video" id="video-wrapper">
    <source src="https://giant.gfycat.com/CandidImmaterialDromedary.webm" type="video/webm">
    <source src="https://giant.gfycat.com/CandidImmaterialDromedary.mp4" type="video/mp4">
      Your browser does not support the <code>video</code> element. <a href="https://gfycat.com/CandidImmaterialDromedary">Source.</a>


var player = new OdoVideo(document.querySelector('#video-wrapper'));

Control Styles

OdoVideo comes with three built-in styles: below (default), overlay, and on top. All you need to do is add a class (or multiple) to the main .odo-video element.

<div class="odo-video odo-video--overlay">
<!-- or -->
<div class="odo-video odo-video--overlay odo-video--on-top">

Control Layouts

OdoVideo comes with three built-in styles: none, inline progress (default), and stacked progress. There is also a fourth option: custom, which lets you define the structure of the controls.

// Stacked progress (the one above)
var instance = new OdoVideo(document.querySelector('#stacked'), {
  controls: OdoVideo.Controls.STACKED_PROGRESS

// No controls
var instance = new OdoVideo(document.querySelector('#video-wrapper'), {
  controls: OdoVideo.Controls.NONE

// Custom
var instance = new OdoVideo(document.querySelector('#video-wrapper'), {
  controls: OdoVideo.Controls.CUSTOM,
  layoutControls: function(elements) {
    // Create your layout here.
  updateControls: function(seconds) {
    // Update any controls here.
    console.log(seconds, instance.getPrettyTime(seconds)); // 2, '0:02'

Custom Layout - layoutControls(elements)

When using a custom controls layout, you must specify the layoutControls option. The elements has all the default controls. This is what OdoVideo does internally with the default layout:

Controls.prototype._createInline = function(elements) {

The elements.controls element is then appended to the OdoVideo element.

Custom Layout - updateControls(seconds)

When using a custom layout, you might need to update your controls display as the video progresses. This is a hook to do exactly that and nothing more. The function receives a float with the currentTime value of the video.


This component tests the browser to see if it can autoplay videos. It does this on page load by inserting a base64-encoded video into the page with the autoplay attribute set and then checks to see if it started. This test can occasionally give false negatives (mostly in IE) due to page load speed. OdoVideo will save the result of the autoplay test in the browser's localStorage as videoautoplay. To mitigate false negatives, if the test fails, OdoVideo will run the test again on the next page load - up to 3 times.

To provide a different fallback for browsers which cannot autoplay videos, use the autoplay promise of the instance or the static autoplay promise of the class.

In order to autoplay videos on iOS, there are some stipulations you must follow. Setting the muted and playsinline attributes should usually be all you need.

function handleAutoplay(canAutoplay) {
  if (canAutoplay) {
    console.log('Can autoplay');
  } else {
    console.log('Cannot autoplay');


// Or



Public methods of OdoVideo instances.


Play the video.


Pause the video.


If the video is playing, pause it. If the video is paused, play it.


Returns the main element of the OdoVideo component.


Returns the <video> element.

listenOnData(event, cb)

Fires a callback function when the video readyState is greater than 1, or the video event passed as the event parameter.


Returns the video element’s currentTime property.


Mute the video.


Unmute the video.


If the volume is muted, unmute it. If the volume is unmuted, mute it.


Returns whether the video is currently muted.


Update the current video source. This method changes the appropriate <source> src property because IE9 does not work when the <video>s src property or attribute is updated. The parameter is an absolute or relative path to the video, without the extension. .e.g. "/videos/cool-feature". OdoVideo will pick the correct extension/type based on its support.


Converts a time value to MMSS, so 91 seconds is "1:31".


Request or exit from fullscreen.


Remove all event listeners, references to DOM elements, and generated elements.

DOM Video Events

These exist within the OdoVideo.VideoEvent object.


{ name: 'loadedmetadata', readyState: 1 }

Corresponds to the loadedmetadata event. Video metadata, such as dimensions and track, have been loaded.


{ name: 'loadeddata', readyState: 2 }

Corresponds to the loadeddata event. Video data for the current frame has been loaded, but not enough to play the next frame.


{ name: 'canplay', readyState: 3 }

Corresponds to the canplay event. The browser has downloaded enough of the video to play, but may still need buffering during playback.


{ name: 'canplaythrough', readyState: 4 }

Corresponds to the canplaythrough event. The browser has downloaded enough of the video to play without buffering.

Removing focus box.

Although not recommended, you may remove the focus state from the buttons.

.odo-video__fullscreen:focus {
  box-shadow: none;


pauseOnClick: true

When the video element is clicked, pause the video.

controls, layoutControls, updateControls

All described above.