I've been working on an html5 canvas video player with a lot of fun little extras and ui toys, the main one being a chroma key (green screen) effect that allows the user to key out different colors or ranges of color while the video is playing.
I seem to have hit a snag in the recommended chroma key method. It works, but it is a really heavy process and can tax the cpu to the point where the video will look choppy if the user is running other applications in the background.
Here is the stripped down code I'm using for the chroma key effect:
<video id="sourceVid" controls="true">
<source src="http://s3.amazonaws.com/dfc_attachments/public/documents/3185373/AAA.webm" />
</video>
<canvas id="hCanvas"></canvas>
<canvas id="dCanvas"></canvas>
<script type="text/javascript">
var doc = document;
var sourceVid = doc.getElementById("sourceVid");
var hCanvas = doc.getElementById("hCanvas");
var dCanvas = doc.getElementById("dCanvas");
var hContext = hCanvas.getContext("2d");
var dContext = dCanvas.getContext("2d");
sourceVid.addEventListener('loadeddata', function() {
hCanvas.setAttribute('width', sourceVid.offsetWidth);
dCanvas.setAttribute('width', sourceVid.offsetWidth);
hCanvas.setAttribute('height', sourceVid.offsetHeight);
dCanvas.setAttribute('height', sourceVid.offsetHeight);
}, false);
sourceVid.addEventListener('play', function() {
runAnalysis();
});
var runAnalysis = function() {
if (sourceVid.paused || sourceVid.ended) {
return
}
frameFix();
if (window.requestAnimationFrame) {
requestAnimationFrame(runAnalysis);
} else {
setTimeout(runAnalysis, 0);
}
};
var frameFix = function() {
hContext.drawImage(sourceVid, 0, 0, sourceVid.videoWidth, sourceVid.videoHeight);
var frame = hContext.getImageData(0, 0, sourceVid.videoWidth, sourceVid.videoHeight);
var length = frame.data.length;
for (var i = 0; i < length; i++) {
var r = frame.data[i * 4 + 0];
var g = frame.data[i * 4 + 1];
var b = frame.data[i * 4 + 2];
if (g >= 0 && g < 100 && r >= 0 && r < 100 && b >= 0 && b < 100) {
frame.data[i * 4 + 3] = 0;
}
}
dContext.putImageData(frame, 0, 0);
return
};
Hoping to find ways to further optimize this for performance.