メソッドを解説！ウェブカメラ・マイク活用術

ウェブブラウザでユーザーのカメラやマイクにアクセスし、音声や動画をリアルタイムで取得する──そんな魔法のような機能を実現するのが、MediaDevices.getUserMedia() メソッドです。WebRTC (Web Real-Time Communication) の基盤となる重要なこの機能は、ビデオ通話アプリやオンライン会議システム、写真撮影ツールなど、多岐にわたるウェブアプリケーションで活用されています。

しかし、ただ「カメラをオンにする」だけでなく、どのような設定で、どのような種類のメディアを取得したいのかを細かく指定できることをご存知でしょうか？この記事では、getUserMedia() メソッドの基本的な使い方から、様々なオプション（制約）の指定方法、そしてプライバシーとセキュリティに関する重要な側面までを、具体的な例を交えながら詳しく解説します。

getUserMediaとは何か？

getUserMedia() は、MediaDevices インターフェイスのメソッドであり、ユーザーにメディア入力（カメラやマイクなど）の使用許可を求め、要求された種類のメディアを含む MediaStream を生成します。例えば、カメラからの映像トラックや、マイクからの音声トラックなどを含めることができます。

このメソッドは Promise を返し、ユーザーがアクセスを許可し、メディアストリームの取得に成功した場合に MediaStream オブジェクトで解決されます。

しかし、ユーザーが拒否した場合や、指定された条件に合うメディアが利用できない場合は、それぞれ NotAllowedError または NotFoundError の DOMException で Promise が拒否されます。

基本的な使い方

getUserMedia() メソッドは、引数として constraints というオブジェクトを一つ受け取ります。この constraints オブジェクトが、どのような種類のメディアを、どのような要件で要求するかをブラウザに伝える役割を果たします。

constraints オブジェクトは、主に video と audio の2つのメンバーを持ちます。どちらか、または両方を指定する必要があります。

• 音声と動画の両方を有効にする例:

• この最もシンプルな指定では、ブラウザはデフォルトのカメラとマイクにアクセスしようとします。

• 音声のみ、または動画のみを有効にする例:

• false を指定した場合、結果として得られるストリームにはその種類のトラックが含まれてはなりません。video と audio はどちらもデフォルトで false なので、constraints オブジェクトにプロパティを全く含まない場合や、全く存在しない場合は、Promise は常に拒否されます。

より詳細な制約（オプション）の指定

video や audio の値を単なる論理値 (true/false) だけでなく、オブジェクトとして指定することで、さらに細かくメディアの要件を定義できます。このオブジェクトは MediaTrackConstraints 辞書として解釈されます。

1. 解像度の指定

カメラの動画トラックの解像度を指定することができます。

• 理想の解像度を要求する例:

• この場合、ブラウザは 1280x720 に最も近い解像度を提供しようとします。正確に一致するものが利用できない場合や、ユーザーがオーバーライドした場合は、異なる解像度が返されることがあります。

• 必須の解像度を要求する例 (min, max, exact): 特定の解像度を必須とする場合は、min, max, exact の各キーワードを使用します。これらは本質的に必須条件となります。

• この要件を満たすカメラがない場合、Promise は OverconstrainedError として拒否され、ユーザーには通知されません。

• 理想値と必須値を組み合わせる (ideal): ideal キーワードを使用すると、ブラウザは ideal の値から見て最適距離が最小になるような設定を見つけようとします。プレーンな値は本質的に ideal と見なされます。

• この例では、幅が 1024px 以上 1920px 以下で、高さが 576px 以上 1080px 以下という範囲内で、1280x720 が理想的な解像度として選択されるようにブラウザに伝えています。

2. カメラの向きの指定

スマートフォンなどのデバイスでは、フロントカメラ（ユーザー側）とバックカメラ（環境側）を切り替えることができます。

• フロントカメラを選好する例:

• バックカメラを必須とする例:

• exact を使うことで、そのカメラが利用できない場合はエラーとなります。

3. 特定のデバイスの選択

MediaDevices.enumerateDevices() メソッドで利用可能なメディアデバイスのリストを取得し、その中から特定のカメラやマイクを deviceId で指定して使用することができます。

• 特定のカメラを要求する例:

• これは要求されたカメラを返しますが、指定したカメラが利用できない場合は別のカメラを返す可能性があります。

• 特定のカメラを必須とする例:

• exact を使用することで、そのデバイスが利用できない場合はエラーとなります。

4. フレームレートの指定

ビデオ通話など、帯域幅の制限があるケースでは、フレームレートを調整することが望ましい場合があります。

• フレームレートの理想値と最大値を指定する例:

プライバシーとセキュリティに関する重要な注意点

getUserMedia() はユーザーの非常にプライベートな情報（映像や音声）にアクセスするため、プライバシーとセキュリティは非常に厳しく管理されています。

1. 安全なコンテキスト (Secure Context) のみ: getUserMedia() メソッドは、HTTPS を使って読み込まれたページや localhost から読み込まれたページなど、安全なコンテキストでのみ利用できます。保護されていない HTTP 接続のページでは、navigator.mediaDevices プロパティが undefined となり、getUserMedia() にアクセスすることはできません。この状態でアクセスしようとすると TypeError が発生します。

2. 常にユーザーの許可が必要: カメラやマイクにアクセスする際には、常にユーザーの明示的な許可が必要です。ブラウザは、どのドメインがどのデバイスにアクセスを要求しているのかをユーザーに通知し、許可または拒否の選択を促します。一度許可された場合でも、ブラウザはカメラやマイクが使用されていることを示すインジケーター（例えば、URLバーのアイコンなど）を表示することが義務付けられています。

3. 権限ポリシー (Permissions-Policy): ウェブサイトのセキュリティをさらに強化するために、権限ポリシーを使用できます。例えば、埋め込み 要素内で getUserMedia() を使用する場合、親文書が Permissions-Policy ヘッダーや の allow 属性で明示的に camera や microphone の使用を許可する必要があります。

4. これにより、 内でのみ権限を要求することができ、より安全な運用が可能になります。

エラー処理も忘れずに

getUserMedia() は Promise を返すため、エラー処理も重要です。

navigator.mediaDevices
.getUserMedia(constraints)
.then((stream) => {
// ストリームを正常に取得できた場合の処理
const video = document.querySelector("video");
video.srcObject = stream;
video.onloadedmetadata = () => {
video.play();
};
})
.catch((err) => {
// エラー処理
console.error(`${err.name}: ${err.message}`);
// 例:
// NotAllowedError: ユーザーがアクセスを拒否した場合 [2]
// NotFoundError: 指定された種類のメディアトラックが見つからない場合 [8]
// OverconstrainedError: 指定された制約が満たせない場合 [8]
// TypeError: 安全でないコンテキストでの呼び出しなど [5]
});

まとめ

MediaDevices.getUserMedia() メソッドは、ウェブ上でリッチなインタラクティブ体験を提供する強力なツールです。基本的な audio: true, video: true の指定から、解像度、カメラの向き、特定のデバイス選択、フレームレートといった多様な制約オプションを使いこなすことで、アプリケーションの要件に合わせた最適なメディアストリームを柔軟に取得できます。

しかし、その強力さゆえに、プライバシーとセキュリティへの配慮は不可欠です。常に安全なコンテキストで開発し、ユーザーの許可を適切に取得・表示するよう心がけましょう。