やったこと
現場で使う可能性があるreact-webcam
というライブラリを使用して、ReactアプリでスマホやPCのカメラ機能を利用する方法について実践しました!
実際の作成画面
「撮影画面」でreact-webcam
を用いてカメラ映像を表示し、撮影ボタンを押下することでカメラ映像のスクショを取得することが出来ます。
デモアプリ全体
react-webcamとは?
Reactでウェブカメラを使用するコンポーネントを提供してくれるライブラリです。
導入
react-webcamの導入
npm install react-webcam
実装
実装箇所の説明をする前に今回のデモアプリのルーティングやコンポーネント名を示しておきます。
<StrictMode>
<div>
<header>
<h1>デモアプリ</h1>
</header>
<main>
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/capture" element={<Capture />} />
<Route path="/result" element={<Result />} />
<Route path="/error" element={<Error />} />
</Routes>
</BrowserRouter>
</main>
</div>
</StrictMode>
react-web
を用いた実装は、上記のCapture
コンポーネントでおこないます。
実際のコードを見てみましょう。
import { useCallback, useRef } from "react";
import { useNavigate } from "react-router";
import Webcam from "react-webcam";
import { JoyUiButton } from "./@joy-ui/Button/JoyUiButton";
export const Capture = () => {
const webCamRef = useRef<Webcam>(null);
const navigate = useNavigate();
const videoConstraints = {
width: 640,
height: 360,
facingMode: "user",
};
const onClickScreenShot = useCallback(() => {
const imageSrc = webCamRef.current?.getScreenshot();
navigate("/result", { state: { capture: imageSrc } });
}, [webCamRef]);
const goToErrorPage = () => {
navigate("/error");
};
return (
<div>
<div>
<h2>撮影画面</h2>
</div>
<div>
<Webcam
audio={false}
disablePictureInPicture={true}
screenshotFormat={"image/webp"}
onUserMediaError={goToErrorPage}
videoConstraints={videoConstraints}
ref={webCamRef}
/>
</div>
<div style={{ justifyItems: "center" }}>
<JoyUiButton content={"撮影"} handleClick={onClickScreenShot} />
</div>
</div>
);
};
【実装手順】
①Webcam
コンポーネントを配置する
→カメラ映像を画面に映し出したいだけならこれだけでOKです。めっちゃ簡単。
<Webcam />
②useRef
フックを使用しref
を宣言し、Webcam
コンポーネントのref
属性に渡す
→ここでDOMを取得し、Webcam
が内部に持つ「 カメラ映像のスクショを取得する 」メソッドにアクセスできるようになります。
const webCamRef = useRef<Webcam>(null);
return (
<Webcam ref={webCamRef} />
)
(参考)ref
の使い方
https://ja.react.dev/learn/manipulating-the-dom-with-refs
③撮影ボタン押下時にカメラ映像のスクショを取得する処理をおこなう関数を作成する
→Webcam
はgetScreenshot()
というメソッドをもち、カメラ映像のスクショを取得することが出来ます。
const onClickScreenShot = useCallback(() => {
const imageSrc = webCamRef.current?.getScreenshot();
navigate("/result", { state: { capture: imageSrc } }); // 今回は撮影した画像を遷移先で表示させたかったのでこういう実装
}, [webCamRef]);
④必要に応じてWebcam
コンポーネントのprops
を指定する
prop | 説明 |
---|---|
audio | 音声を取得するか否か ※実はスクショだけでなく録画も可能なんです |
disablePictureInPicture | ピクチャインピクチャを無効にするか否か |
mirror | 映像を反転(ミラー)で表示するか否か |
onUserMediaError | カメラ使用がブロックされた際に呼ぶコールバック関数 |
screenshotFormat | スクリーンショットの画像フォーマット(jpeg/png/webp) |
videoConstraints | その他の制約条件 |
videoConstraints
詳細
prop | 説明 |
---|---|
aspectRatio | アスペクト比の指定 |
facingMode | 内カメラか外カメラか指定(user or environment) |
height | 縦幅の指定 |
width | 横幅の指定 |
(詳しくはこちらでご確認ください)
・https://www.npmjs.com/package/react-webcam#props
・https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints
【追加実装】カメラ使用がブロックされた時にエラー画面に遷移する
Webcam
を使うと、最初のアクセス時にカメラを起動しようとした際に、カメラ使用の許可かブロックの選択を求められます。
許可をすれば当然画面にカメラ映像を表示します。
一方で、ブロックした際にはエラー画面などに遷移させたいことがあると思います。
方法
Webcam
コンポーネントのonUserMediaError
propsにコールバック関数を設定する
→カメラがブロックされるとコールバック関数が呼び出されます。
const goToErrorPage = () => {
navigate("/error");
};
return (
<Webcam
onUserMediaError={goToErrorPage}
ref={webCamRef}
/>
)
実際にブロックしてエラー画面に遷移することが確認出来ました。
おわり
帰宅後に色々調べながら実装していたら4:30になっていました。
次はface-api
を使ってカメラ内に顔がひとつだけの時のみ撮影ボタンを活性にするという処理を実装しようと思っています。