Opera Mobile 12を実行しているAndroidタブレットで実行される Javascript が少しあります。タブレットはオフィスの壁に取り付けられているため、このオフィスで働くすべての人が計時システムとして使用します (つまり、出勤/退勤に使用します)。この JavaScript は、特定のイベントが発生したときにユーザーの写真を撮り、この写真をデータ URL に変換して、サーバーに送信できるようにします。ただし、これはすべてバックグラウンドで実行されます。 要素と要素は両方とも に設定されます。video
canvas
display:none;
Web カメラの相互作用を処理するコードは次のとおりです。
var Webcam = function() {
var video = document.getElementById('video');
var stream_webcam = function(stream) {
video.addEventListener('loadedmetadata', function(){
video.play();
}, false);
video.src = window.URL.createObjectURL(stream);
}
// start recording
if (navigator.getUserMedia)
navigator.getUserMedia({video: true}, stream_webcam);
else
_error("No navigator.getUserMedia support detected!");
var w = {};
w.snap = function(callback) {
var canvas = document.getElementById('canvas');
canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
// delay is incurred in writing to canvas on opera mobile
setTimeout(function() {
callback(canvas.toDataURL());
}, 1);
};
return w;
}
w.snap(callback)
ユーザーが特定のボタンを押すと呼び出されます。問題は、への呼び出しと、実際にキャンバスに描画される画像との間にかなりの遅延があることです。発生する問題は次のとおりです。drawImage
- ユーザー 1 はタブレットを使用し、ボタンを押して、写真を「スナップ」し、サーバーに送信します。サーバーは、空の透明なイメージを受け取ります。( html5 キャンバス toDataURL が空白の画像を返すのと同じ問題ではありません。最初の画像は空白であるため、サーバーに送信されるデータは大幅に少なくなります)
- 数分後、ユーザー 2 がタブレットを使用してボタンを押すと、写真が「スナップ」されます。サーバーはユーザー 1 の写真を受け取ります。
- その後、ユーザー 3 が同じことを行い、サーバーはユーザー 2 の写真を取得します。
だから私は への呼び出しtoDataURL()
が古いデータを返していると推測drawImage()
しています。(非同期であるとどこかで読みましたが、確認できず、描画が終了したときにイベントをアタッチする方法が見つかりません。)
私はもう試した:
- タイムアウトを
snap()
さまざまな値に変更します。私が試した最高は2000でしたが、同じ問題が発生しました。(誰かがもっと高い数字を提案してくれたら、喜んで試してみますが、あまり高くしたくありません。なぜなら、あまり高くすると、ユーザー 2 を処理する前にユーザー 3 の写真が撮られる可能性があるからです。写真、つまり、完全に失う可能性があります!) - ページが最初に読み込まれたときにキャンバスに何かを描画させましたが、それは修正されませんでした.ユーザー1が写真を撮られたとき、サーバーはユーザー1の写真ではなく、ページが読み込まれたときに撮影された写真を受け取りました.
getElementById
を呼び出す前に、を使用してキャンバス要素を再度「取得」しますtoDataURL
。
さらにいくつかのメモ:
- これは、Chrome と Opera の私のコンピューター (MacBook Air) で正常に動作します。
- デバッガーを使用して確実に複製することはできません (Opera Dragonfly を使用してタブレットにリンクします)。
- 私の知る限り、Opera Mobile は、写真をサポートし
getUserMedia
、写真を撮ることができる唯一の Android ブラウザーです。 display:none;
とからを削除するvideo
とcanvas
、(タブレット上で) 正しく動作します。この問題は、ビデオとキャンバスが設定されている場合にのみ発生します。display:none;
このページはスクロールやズームを必要としないシングル ページ アプリであるため、考えられる回避策は、ビデオとキャンバスをページ フォールドの下に移動し、JavaScript でスクロールを無効にすることです (つまり、ユーザーがスクロールするたびに上部にスクロールします)。
しかし、可能であれば、回避策よりも適切な修正を希望します!