@singuerinc


2014.01.22 by Nahuel Scotti | 2 min read

Perfect HTML5 Video Sync


When you work with video and Javascript and you need to tracking an object you can't trust in video events or time, you need to identify each frame, because if the frame rate drops or anything else happends you need to stay in sync.

There are a lot of tutorials of how to do this in ActionScript: 1 2 3

But I want to focus on JavaScript, as described in these tutorials you need to write in each frame the frame number in binary (with black and white). There is a script for After Effect that do the job for you.

So, how we get this data?

// get the video element
var video = document.getElementById("video");

// create a tmp canvas element and get the context
var canvas = document.createElement("canvas"),
  ctx = canvas.getContext("2d");

function loop() {
  // draw from the video those pixels that contains binary data
  ctx.drawImage(video, 1281, 0, 1, 48, 0, 0, 1, 48);

  // get pixels data
  var pixData = ctx.getImageData(0, 0, 1, numPixToRead).data;

  var binStr = "";
  for (var i = 0, n = pixData.length; i < n; i += 4) {
    //the pixel data has 4 values by pixel read (r,g,b,a)

    // after the video compression the pixels
    // aren't black (0) or white (255) so we need to
    // separate them by luminosity and convert in 0s and 1s
    var binNum = pixData[i] > 127 ? 1 : 0;

    // store binary num in reverse order
    binStr = binNum + "" + binStr;
  }

  // convert binary string into decimal, you have the FRAME number
  var frame = parseInt(binStr, 2); //1,2,3,4,5....
}

function animate() {
  loop();
  requestAnimationFrame(animate);
}

animate();
Code source

Demo (binary pixels are on top-right)

  • #html5
  • #javascript
  • #sync
  • #video