Fixing HTML Video on Mobile

1-HnEpDa3knnXVj7qxuW_pXQ

Samir Zahran on how and why they built Whitewater, an open source video encoder and player for their site:

Common HTML5 Video features such as preloading and autoplay are completely missing in some browsers. The scripting APIs are limited compared to what’s available on desktop. Worst of all, Safari on the iPhone (the most popular mobile browser to visit our site) does not allow inline video playback at all (not until iOS 10 is released)

It renders on <canvas> and requires you to first encode your video to the Whitewater format which uses diffmaps.

Fixing HTML Video on Mobile →
Whitewater Mobile Video →

Note: In case you don’t want to encode your videos you can – alternatively – use the hack that powers “players” such as iphone-inline-video: manually change the currentTime of the video element.

Here’s a little snippet of a (non-public) project that I’m working on that might be of help:

play(reset = false) {

  // Reset to start if need be
  if (reset) {
    this.refs.video.currentTime = 0;
  }

  // Store time
  this.lastTime = Date.now();

  // "Play" the video, using requestAnimationFrame
  this._rAFRender();

}

pause() {
  this.rAF && cancelAnimationFrame(this.rAF);
}

_rAFRender() {

  // Calculate time difference between this and the previous call to _rAFRender
  const time = Date.now();
  const elapsed = (time - this.lastTime) / 1000;

  // More time has passed than the framerate
  if (elapsed >= (1 / 25)) {

    // Seek the video to currentTime, thus rendering a new frame even though it's not playing
    this.refs.video.currentTime = this.refs.video.currentTime + elapsed;

    // Store time as lastTime
    this.lastTime = time;

  }

  // We are not at the end of the video: keep on rendering
  if (this.refs.video.currentTime < this.refs.video.duration) {
    this.rAF = requestAnimationFrame(this._rAFRender);
  }

}

If you create an <audio> element in parallel, you can even sync up the audio from the video with it – a feature Whitewater has not.

Note to self: I urgently need to release this component …

Leave a comment

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.