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だけでカメラを使用する方法も記事にしています。
コメント