2016-11-01 8 views
1

私はHTML5ビデオとその上にキャンバスの描画(640x480ピクセル)のアプリケーションを作成しています。目的は、エンコードされたビデオとともにキャンバスの描画を記録して、単一のビデオとしてそれを生成することでした。私はFFMPEGを使用してこれらのすべてを行うことができました。しかし、私が直面している問題は、HTML5ビデオの実行時にCPUの約50%がかかることです。キャンバス上の描画もCPUを要求しているので、ブラウザは特定の時間が経過するとフリーズし、クロムのそのタブのCPU使用率は100を超えて連続的に表示されます。html5キャンバスレンダリングを最適化しようとしました。しかし何も助けなかった。はるかに少ないCPU使用量でこのビデオを実行する方法はありますか?または他の最適化が可能ですか?HTML5ビデオとキャンバスのCPU最適化

答えて

3

ハードウェアがビデオをデコードして表示するためにCPUを使用する必要がある場合は、あまりできません。キーワードは妥協です。

追加の障壁を取り除くことはできますが、いくつかのことができます。これらは、しかし、一般的なヒントを考慮する必要があります。

効率的なループ

そうでない場合には、あなたのループを呼び出すためにrequestAnimationFrame()を使用してください。

setTimeout()/は、パフォーマンスが重く、モニタのリフレッシュレートに適切に同期できません。あなたはすでにこれをやっていない場合

更新負荷も

を削減:ビデオはめったに上記30/29.97 FPS(ヨーロッパでは25 FPS)であるキャンバスは通常、60 FPSで更新されます。これは、すべての2番目のフレーム更新をスキップし、最適なレートでビデオを表示できることを意味します。これを達成するためにトグルを使用してください。

25FPSのビデオは、30FPSに再同期されます(モニタは、内部的に電子的に再同期される欧州のモデルでも60Hzで動作します)。ドロップ/ダブルフレームなどを処理する必要があります。内部的には何もできません)。 canvas要素

// draw video at 30 FPS 
var toggle = false; 

(function loop() { 
    toggle = !toggle; 
    if (toggle) { /* draw frame here */ } 
    requestAnimationFrame(loop); 
})(); 

避けスケーリング必ずキャンバスサイズとCSSサイズはまったく同じであることを確認してください。単純に言えば、キャンバスのサイズを設定するのにCSSを使わないでください。

無効にアルファチャンネル組成

あなたはもう少しスピードを得るために、一部のブラウザでキャンバスのアルファ成分を無効にすることができます。コンシューマービデオにはアルファチャンネルは一切付属していません。エンコードの段階で

// disable alpha-composition of the canvas element where supported 
var context = canvas.getContext("2d", {alpha: false}); 

微調整の設定が

サイズと解凍負荷のバランスを使用してビデオをエンコードすることを確認します。ビデオが圧縮されるほど、再構築する必要があります。異なるエンコーダ設定でエンコードして、シナリオで機能するバランスを見つけます。

色深度、つまり16対24ビットなどの側面も考慮してください。

H264コーデックは、さまざまなディスプレイインターフェイスハードウェアで広くサポートされているため、好ましいコーデックです。

ビデオを減らすFPS

ビデオの内容が許せば、f。例。動きや変化はほとんどなく、30 FPSの代わりに15 FPSを使用してエンコードします。 (上記のように)を使用すると、より小さな光源サイズ

エンコードにのみ4:

// draw video at 15 FPS 
var modToggle = 0; 

(function loop() { 
    if (modToggle++ % 4 === 0) { /* draw frame here */ } 
    requestAnimationFrame(loop); 
})(); 

エンコードビデオで3つのフレーム及び更新キャンバスをスキップすることができる場所ので、代わりトグルMODULOを使用する場合ビデオは8分の1の小さなサイズで分割されます(この場合、私はハーフサイズ320x240を提案します - 実験!)。その後drawImage()方法のスケールパラメータを使用して描画:

context.drawImage(video, 0, 0, video.videoWidth, video.videoHeight, 0, 0, 640, 480); 

このヘルプをロードして、復号することが必要なデータ量を削減するが、もちろん、品質が低下します。それがどのように判明したかは、コンテンツに再び依存する。

コンテキスト上でimageSmoothingEnabledをfalseに設定して補間をオフにすることもできます(注:一部のブラウザではプロパティに接頭辞が必要です)。このためには、サイズを50%に減らすことは望ましくないかもしれませんが、わずかです(この場合は600x420のようなものです)。

注:フレームレートを「減らす」場合でも、キャンバスはまだ60 FPSで再描画されますが、中間フレームでは実際の作業は行われないため、CPU/GPUの負荷がまだ残ります全体的に厳しいパフォーマンス予算。

これはいくつかの入力を希望します。

+0

フィードバックいただきありがとうございます。あなたが言及したようにFPSを減らして最適化しました。キャンバス上のインタラクションをリアルタイムで見る必要があるので、FPSで試してみました。私が正確にしたことは、キャンバスを12FPSで記録し、FFMPEGを使用して24FPSでそれをエンコードしたことです。これは望ましい結果を達成するのに役立ちました。 –

関連する問題