JavaScriptでのカメラ起動とCanvas表示
カメラの起動
まずはコードです。
HTML
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>カメラ起動</title>
</head>
<body>
<video id="video" src="" width="300" height="300" playsinline></video>
</body>
</html>
- HTMLはvideoタグを用意します
- このときplaysinlineを指定することで画面内に表示できます
Javascript
window.addEventListener('load', function(){
//videoのstream
let stream = null;
//video設定値
const constraints = {
audio: false,
video: {
width: 300,
height: 300,
//フロントカメラの場合
facingMode: 'user',
//リアカメラの場合
// facingMode: { exact: "environment" },
},
}
//カメラ起動
async function startCamera(constraints) {
try {
stream = await navigator.mediaDevices.getUserMedia(constraints);
const video = document.getElementById('video');
video.srcObject = stream;
video.onloadedmetadata = () => {
video.play();
};
} catch (err) {
//エラーハンドリング
console.error(err);
}
}
//カメラ停止
function stopCamera(){
const video = document.getElementById('video');
const tracks = video.srcObject.getTracks();
tracks.forEach((track) => {
track.stop();
});
video.srcObject = null;
}
//初期処理
startCamera(constraints);
});
- navigator.mediaDevices.getUserMedia(constraints)でデバイスにアクセスします
- constraintsにvideoを指定することでカメラにアクセスでき、解像度とどのカメラを使うか指定します
- 扱うときは非同期のためasync/awaitを使って制御します
- 結果のstreamをvideoタグに詰めて、video.playで開始します
- カメラを停止するときは逆にstreamを取得し停止します
canvasに表示
上記でカメラで動画を映し続けていると思いますが、その動画をcanvasタグに常に表示させます。
追加部分のコードです。
HTML
<canvas id="canvas" width="300" height="300"></canvas>
videoタグと同様にcanvasタグを用意します。
Javascript
//canvas描画
function drawCanvas(){
const canvas = document.getElementById('canvas');
const context = canvas.getContext('2d');
//videoエレメントを指定
const video = document.getElementById('video');
context.drawImage(video, 0, 0, canvas.width, canvas.height);
requestAnimationFrame(drawCanvas);
}
drawCanvas();
- canvasタグからcontentを取得します
- context.drawImageでvideoタグを渡すことができますので渡すと勝手に表示してくれます
- requestAnimationFrameに自身を渡すことで定期的(毎秒60回ぐらい)にループしてくれます
setIntervalでもできますが画面描画に関してはrequestAnimationFrameの方がよいとされています。