やってみたらなんとかなる

プログラミングをする上で調べたこととかやったこととか

[React] WebRTC x React でP2Pビデオ電話アプリを作ってみる #3 ~映像・音声取得編~

概要

WebRTCとReactを使った簡単なビデオ通話アプリ作成の第3回です。 今回は、映像の取得まで行います。

今回行うこと

  • getUserMedia()を使った映像と音声の取得

今回使用するコード

次の①、②のコードを書いた後にnpm startでカメラに映った自分が表示されると思います。

①src/VideoView.js (新規作成)

import React from 'react';

export default function VideoView() {
  const videoRef = React.useRef(null);
  const constraints = {
    video: true,
    audio: false,
  }

  React.useEffect(() => {
    navigator.mediaDevices.getUserMedia(constraints)
      .then((stream) => {
        videoRef.current.srcObject = stream;
      })
      .catch((error) => {
        console.log(error);
      })
  }, []);

  return (
    <div className="VideoView">
      <video playsInline autoPlay ref={videoRef} />
    </div>
  )
}

②src/index.js (編集)

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

import VideoView from './VideoView'; // 変更点

ReactDOM.render(
  <React.StrictMode>
    <VideoView />  // 変更点
  </React.StrictMode>,
  document.getElementById('root')
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

コードの中身

React.useRef

useRefはReact内でタグのパラメータを操作する時に使用します。 タグの中に<video src="./hogehoge.mp4" />のように書き込めればそれでいいのですが、 今回使用するパラメータsrcObjectはそのように書き込めません。 そんな時に便利なのがuseRefです。
タグに<video ref={videoRef}>のようにrefパラメータを記述し、その変数videoRefを受け取ります。 そこからvideoRef.current.srcObject = streamのようにパラメータに値を代入するとという使い方です。

React.useEffect

useEffectは「この変数の値が変更されたらこの処理を実行したい」という時に使います。

React.useEffect(() => {
  // 実行したい処理
}, [. 変更を検知したい変数達. ]);

こんな感じで使用します。変更を検知したい変数はArrayとして複数指定することが可能です。
今回のコードのように空のArrayが指定された場合は、最初に読み込まれた時のみ処理が実行されます。

navigator.mediaDevices.getUserMedia

今回の主役です。ユーザーのビデオもしくはオーディオを取得します。

navigator.mediaDevices.getUserMedia(取得制約)
      .then((stream) => {
        // 取得成功時の処理
      })
      .catch((error) => {
        // 取得失敗時の処理
      })

ビデオ等を取得する時にはブラウザ側から「ビデオとか取得するけどOK?」という確認があります。 この確認で拒否されてしまった場合やそもそもビデオがない時などに「取得失敗時の処理」行われます。
取得制約は何を取得するのかをjson形式で指定します。

{
  video: true,
  audio: false
}

のように指定すると、「ビデオは取得するけど、オーディオは取得しません」という意味になります。
今回の場合、audio: trueにするとハウリングが起こるので注意してください

まとめ

今回はgetUserMediaを用いてビデオ・オーディオの取得を行いました。次回は取得したデータを相手に渡します。

次のページ→ [React] WebRTC x React でP2Pビデオ電話アプリを作ってみる #4 ~データ交換編~ - やってみたらなんとかなる