エフェクト処理を分離してプラグイン化する
サンプル04をベースにすれば、ビデオエフェクターをいくらでも作成できますが、より簡単にエフェクトの種類を増やせるように、エフェクト部分の処理を分離してプラグインとして機能するようにします。
まず、サンプル04からエフェクト処理部分だけをそっくり抜き出して別ファイルにします。中身はJavaScriptですから.jsファイルになります。次に、複数のエフェクトを呼び出せるように、プラグインファイルのURLを格納する配列を用意します。配列には以下のように書いておきます。
[
'halfred.js',
'http://footage.openspc2.org/fx/blue.js'
]
「halfred.js」は同じドメインにあるエフェクトプラグインです。2番目のURLは、http://footage.openspc2.org/fx/にあるプラグイン「blue.js」を指します。このように、複数のエフェクトをかけたい場合でも、配列要素に新たなURLを追加するだけで済みます。プラグインのURLを格納する配列はjsファイル(fxlist.js)にしておき、非同期で読み込んで使用します。なお、非同期でのデータ読み込みにはjQueryを利用しています。
fxlist.jsファイルを読み込んだら、配列に書かれているエフェクトのスクリプトを読み込みます。読み込んだ段階でエフェクトが実行されては困るので、すぐには実行せず、スクリプトを配列に入れていきます。
エフェクトをかける時には、配列の内容をeval()を使って評価することで、処理が実行されることになります。これらの処理を、読み込んだエフェクトプラグインの数だけ繰り返します。
エフェクトプラグインのスクリプトは以下のような構成になっています。
fx[maxFx++] = "\
for(var i=0; i<can.width*can.height*4; i+=4){\
p[i] = p[i] >> 2;\
}\
";
fxは配列で、maxFxはプラグインの数を示しています。それ以外の部分は単純にエフェクト処理のスクリプトを抜き出しただけです。機構がやや複雑ですが、スクリプト自体は短いのでコードを追ってもらえば流れが分かると思います。
ここまでをまとめたものがサンプル05です。さすがに2段階でピクセル処理をするとリアルタイムでの処理は難しくなります。
●サンプル05[HTML]
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>JSONエフェクト</title>
<link rel="stylesheet" href="css/main.css" type="text/css" media="all">
<script type="text/javascript" src="js/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="js/view.js"></script>
</head>
<body>
<h1>JSONエフェクト</h1>
<video id="myVideo" controls autobuffer>
<source src="movie.mov" width="384" height="216">
<source src="movie.ogv" width="384" height="216">
</video>
<canvas id="myCanvas" width="384" height="216"></canvas>
<div id="control">
赤の輝度を半分にし、さらに他サーバーにある縦縞にするエフェクトも同時に適用してから映像をキャンバスに再描画します。<br>
</div>
</body>
</html>
●サンプル05[JavaScritp:view.js]
var fx = []; // 実行するプラグインのコード
var maxFx = 0; // プラグインの最大数
window.addEventListener("load", function(){
var video = document.getElementById("myVideo");
var can = document.getElementById("myCanvas");
var con = can.getContext("2d");
setInterval(function(){
con.drawImage(video, 0, 0);
var pxdata = con.getImageData(0, 0, can.width, can.height);
var p = pxdata.data;
for(var i1969=0; i1969<maxFx; i1969++){
eval(fx[i1969]); // エフェクトを実行する
}
con.putImageData(pxdata, 0, 0);
}, 1000/30); // 30フレーム
// エフェクトプラグインデータを読み込む
$.get('fxlist.js', function(text){
var list = eval(text); // プラグインリストを取得
for(var i=0; i<list.length; i++){
$.getScript(list[i]); // エフェクト処理のスクリプトを読み込む
}
});
}, true);
●サンプル05[JavaScritp:fxlist.js]
[
'halfred.js',
'http://footage.openspc2.org/fx/blue.js'
]
●サンプル05[JavaScritp:halfred.js]
fx[maxFx++] = "\
for(var i=0; i<can.width*can.height*4; i+=4){\
p[i] = p[i] >> 2;\
}\
";
●サンプル05[JavaScritp:blue.js]
fx[maxFx++] = "\
for(var i=0; i<can.width*can.height*4; i+=4){\
p[i+2] = i & 255;\
}\
";