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 …