Getting video to render on canvas on iOS

playah.js Render HTML video on canvas by advancing the currentTime attribute

Inlining video components although mostly useful on mobile is less than straightforward to set up on iOS because it lacks support for using video as a source for the canvas drawImage() method. The trick is to advance the playhead position at an even pace much like you would when manually fiddling with a tape roll. First create an off document video element to hold the source,

// Create placeholder video
var video = document.createElement('video');

// Set video source
video.setAttribute('src', '/path/to/video.mp4');

// Load the video,
// automatic preload not available on iOS

Then set currentTime according to how much time has passed since the last update call,

// Last update timestamp
var then;

// Flag on if playing
var isRunning;

// Run on each frame
var update = function() {
  var now = new Date().getTime();
  var delta = now - (then || now);

  if (isRunning) {
    video.currentTime += delta * 0.001;
    // Reset
    if (video.currentTime >= video.duration) {
      video.currentTime = 0;

      isRunning = false;

  then = now;

Then paste the video still onto the canvas context,

// Given a canvas element on page, 
// grab the drawing context 
var context = document.querySelector('canvas').getContext('2d');

var render = function() {

  // Paste video frame onto canvas
  context.drawImage(video, 0, 0);

And repeat on each animation frame,

// Raf reference
var frameId;

// Run on each frame
var animate = function(elapsed) {
  frameId = window.requestAnimationFrame(animate);

Trigger the animation when the video is playback ready,

// After video has loaded
video.addEventListener('loadstart', () => {

  // Start animating
  frameId = window.requestAnimationFrame(animate);

Browserify compatible source, thewhodidthis/playah →