このページの本文へ

HTML5+JavaScriptでビデオエフェクターに挑戦! (3/6)

2010年05月12日 11時00分更新

文●古籏一浩

  • この記事をはてなブックマークに追加
本文印刷

動画をリアルタイムでCanvasに転送する

 VideoからCanvasに転送する方法が分かったら、次にリアルタイムで転送する処理を作ります。

 HTML5 Videoでは、再生時間が変わったタイミングで「timeupdate」というイベントが発生します。このtimeupdateイベントが発生したら、動画をCanvasに転送するようにしたものがサンプル02です。

 「同期開始」のボタンをクリックしてから映像を再生すると、ほぼリアルタイムで動画がCanvasに転送されるはずですが、実際に試してみるとFirefox 3.6以外のブラウザー(Safari 4/Google Chrome/Opera)ではカクカクした動きになっています。

Firefox 3.6ではほぼリアルタイムにキャンバスに描画されるが、他のブラウザーでは1秒間に数回しか描画されない


 実はこのtimeupdateイベントは、Firefoxではフレームレートとほぼ同時に発生するのに対し、他のブラウザーでは1秒間に2~3回程度しか発生しません。発生回数もブラウザーによって異なっています。どうやらtimeupdateイベントは今回の目的には向いていないようです。

 そこで、処理は重くなってしまいますが、タイマーを使って一定時間ごとに動画をCanvasに転送します。サンプル02の処理をタイマーを使って書き直したのがサンプル03です。サンプル03は、どのブラウザーでもほぼリアルタイムで映像がCanvasに転送されます。なお、ここでは元の動画のフレームレートが30フレーム(30fps)なので、転送処理の間隔を1000ミリ秒/30フレームとしています。もし24フレームであれば1000/24にしてください。

fig3-1

Firefox以外のブラウザー、SafariやOperaでもほぼリアルタイムで動画がCanvasに描画される


サンプル02[HTML]


<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <title>映像とキャンバスを同期</title>
        <link rel="stylesheet" href="css/main.css" type="text/css" media="all">
        <script type="text/javascript" src="js/view.js"></script>
    </head>
    <body>
    <h1>映像とキャンバスを同期</h1>
    <video id="myVideo" controls>
        <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">
        <button onclick="sync()">同期開始</button>
    </div>
</body>
</html>


サンプル02[JavaScritp:view.js]


function sync(){
    var video = document.getElementById("myVideo");
    video.addEventListener("timeupdate", function(){
        var can = document.getElementById("myCanvas");
        can.getContext("2d").drawImage(video, 0, 0); 
    }, true);
}


サンプル03[JavaScritp:view.js]


function sync(){
    var video = document.getElementById("myVideo");
    setInterval(function(){
        var can = document.getElementById("myCanvas");
        can.getContext("2d").drawImage(video, 0, 0); 
    }, 1000/30);
}


この連載の記事

一覧へ

この記事の編集者は以下の記事をオススメしています