HTML5 Video on Canvas + pixel manipulation

One of my latest experiments was to create a fullscreen background with a video, for this I used HTML5 video tag and loaded it on a canvas element.
Although it worked it somehow felt incomplete because it was simply a video as background, it needed some edge add to it, for this I decided to use Pixelate library http://close-pixelate.desandro.com/ and extend it so it supported video as well as images.
Github extension can be found also here:

https://github.com/netgfx/close-pixelate

** Note This example is best viewed with latest Chrome or Webkit browser. **

DEMO

The DOM

Minimal html code is required:

<video id="video">
<source src="big_buck_bunny_480p.webm" type='video/webm; codecs="vp8, vorbis"' ></source>        
  Video tag not supported. Download the video <a href="movie.webm">here</a>.
</video>
       
  <canvas id="c"></canvas>

I could also include other formats for the video, but since WebM is generaly perceived as the generic one I’m using this.


The CSS

Some rules to make the video hide and not render (thus slowing down our performance).

body {
    background: black;
}

#c {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    width:100%;
    height:100%;
}

#video {
    position: absolute;
    top: 100px;
    left: 100px;
    border:5px solid #000;
    width:200px;
    z-index:200;
    display:none;
}

The Magic Script

Now here is the javascript that makes magic happen.

$(document).ready(function(){
 
  $("#video").get(0).play();
 
  var video = document.getElementById('video');
  var canvas = document.getElementById('c');
  var context = canvas.getContext('2d');
 
   $("#c").width($('document').width());
   $("#c").height($('document').height());
 
    var cw = Math.floor(canvas.clientWidth );
    var ch = Math.floor(canvas.clientHeight );
    canvas.width = cw;
    canvas.height = ch;

     canv = canvas;
     c = context;
     v = video;
     w = cw;
     h = ch;
     
     draw(v,context,cw,ch);
});

var canv;
var c;
var v;
var w;
var h;

function draw() {
   
    if(v.paused || v.ended){
        return false;
    }
   
    var myPixelation = new ClosePixelation( v, [
        { resolution : 8,shape:'circle', video:true, videoW:w, videoH:h }
  ]);

    c.putImageData(myPixelation,0,0);
    window.requestAnimationFrame(draw);
    //setTimeout(draw,20);  // alternative
}

What we are doing here is to actually pass the video and the browser width & height to the draw function that calls the Pixelate library and returns the modified canvas pixels back, then we draw the pixels by calling

c.putImageData(myPixelation,0,0);

And then we repeat that at a desired frame-rate or simply by calling

requestAnimationFrame(draw);

Note that my extended version of Pixelate library also includes the polyfill for requestAnimationFrame from here:
http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating


** Note The video will not load when testing this locally (unless you have a local server setup) because of the canvas taint. Read more here:

As always you can view an example here:

DEMO

Enjoy!

facebooktwittergoogle_pluspinterestlinkedin
linkedin
Tagged , , , , . Bookmark the permalink.

2 Responses to HTML5 Video on Canvas + pixel manipulation

  1. justin says:

    hey man, I know this post is a year old now but if you’re still around: do you know why the video blacks out at the end when running this? normally when I have a video set to loop it’ll loop without having to stop and replay but when I’m running it through the pixelator it stops for a split second, screen goes black, then restarts. any ideas? thanks!

  2. justin says:

    haha nevermind that previous question, i tried using the alternative setTimeout method of initiating the draw and it seems to have solved that issue for whatever reason

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>