React(Next.js)でWebカメラ(USB)を使用するアプリを作成しようと思い、コンポーネントの作成をしました。リアルタイムキャプチャと撮影の機能を作成しました。カメラはロジクールのUSBカメラを使用しています。
Reactプロジェクトを用意する
今回はNext.jsでReactのプロジェクトを作成しました。
(素のReactでもコンポーネントは使用できると思います)
以下コマンドでプロジェクトを作成(他コマンドでも可)。
npx create-next-app [プロジェクト名]
Webカメラコンポーネントの名前を「UsbCamera」としました。
私は、src>components>UsbCameraフォルダ内にindex.jsx(ここでコンポーネントを記載)を参照する形にしました。
※フォルダ構成やファイルのパスは各自で合わせてください。
ReactのWebカメラコンポーネント
以下のようなUIで作成しました。

カメラの映像を表示し続けるVideo部(上)と、キャプチャボタンを押して取得した静止画を表示するPhoto部(下)になってます。
キャプチャ画像(下)は、デリートボタンを押すと消えます。
index.jsxを以下のように編集しました。
import React, { useEffect, useReducer, useRef } from 'react'
export function UsbCamera() {
const videoRef = useRef(null);
const photoRef = useRef(null);
// カメラで映像取得
const getVideo = () => {
navigator.mediaDevices.getUserMedia({
video: {width: 320, height: 180 }
})
.then(stream => {
let video = videoRef.current;
video.srcObject = stream;
video.play();
})
.catch(err => {
console.log(err);
})
}
useEffect(() => {
getVideo();
},[videoRef])
// 撮影
const takePhoto = () => {
const width = 320;
//const height = width / (16/9);
const height = 180;
let video = videoRef.current;
let photo = photoRef.current;
photo.width = width;
photo.height = height;
let ctx = photo.getContext('2d')
ctx.drawImage(video, 0, 0, width, height);
}
// 写真を消す
const closePhoto = () => {
let photo = photoRef.current;
let ctx = photo.getContext('2d');
console.log(photo)
ctx.clearRect(0, 0, photo.width, photo.height);
}
return (
<>
<h1>USBカメラの使用</h1>
{/* 動画表示 */}
<p>Video</p>
<div >
<video ref={videoRef}></video>
<button onClick={takePhoto}>Capture</button>
</div>
{/* 画像表示 */}
<p>Photo</p>
<div>
<canvas ref={photoRef} />
<button onClick={closePhoto}>Delete</button>
</div>
</>
);
}
さいごに
結構時間がかかってしまった。
もっと良い方法がある気もしますが、とりあえずしたいことができてよかったです。
Reactを使用しないhtmlとJavaScriptだけでカメラを使用する方法も記事にしています。




コメント