ウェブアプリからカメラ、マイク、スピーカーを選択する

最新のブラウザでは、カメラ、マイク、スピーカーなどの入力デバイスと出力デバイスを選択できます。

次に例を示します。

  • スマートフォンで、前面カメラまたは背面カメラを選択します。
  • ノートパソコンの場合は、内蔵スピーカーまたは Bluetooth で接続したスピーカーを選択します。
  • ビデオ チャットの場合は、内部マイクまたは外部マイク、または内部カメラまたは外部カメラを選択します。

これらの機能はすべて、navigator.mediaDevices によって返される MediaDevices オブジェクトによって公開されます。

MediaDevices には 2 つのメソッドがあります。どちらも、パソコンと Android の Chrome 47 に実装されています。enumerateDevices()getUserMedia() です。

オーディオ出力デバイスの選択。

enumerateDevices()

使用可能なデバイスの MediaDeviceInfo オブジェクトの配列にアクセスできる Promise を返します。

このメソッドは MediaStreamTrack.getSources() に似ていますが、Chrome でのみ実装されていたそのメソッドとは異なり、標準に準拠しており、オーディオ出力デバイスが含まれます。以下のデモで試すことができます。

デモのコードから、少し簡素化したコードを次に示します。

navigator.mediaDevices.enumerateDevices()
    .then(gotDevices)
    .catch(errorCallback);
...
function gotDevices(deviceInfos) {

    ...

    for (var i = 0; i !== deviceInfos.length; ++i) {
    var deviceInfo = deviceInfos[i];
    var option = document.createElement('option');
    option.value = deviceInfo.deviceId;
    if (deviceInfo.kind === 'audioinput') {
        option.text = deviceInfo.label ||
        'Microphone ' + (audioInputSelect.length + 1);
        audioInputSelect.appendChild(option);
    } else if (deviceInfo.kind === 'audiooutput') {
        option.text = deviceInfo.label || 'Speaker ' +
        (audioOutputSelect.length + 1);
        audioOutputSelect.appendChild(option);
    } else if (deviceInfo.kind === 'videoinput') {
        option.text = deviceInfo.label || 'Camera ' +
        (videoSelect.length + 1);
        videoSelect.appendChild(option);
    }

    ...

}

enumerateDevices() を使用して利用可能なデバイスの ID を取得したら、setSinkId()Audio Output Devices API で定義)を使用して、動画要素または音声要素のオーディオ出力先を変更できます。

element.setSinkId(sinkId)
    .then(function() {
    console.log('Audio output device attached: ' + sinkId);
    })
    .catch(function(error) {
    // ...
    });

このメソッドは、要素からの音声の出力デバイスを設定します。setSinkId() が呼び出されると、sinkId プロパティを使用して、要素の現在の出力オーディオ デバイスの ID を取得できます。

getUserMedia()

これは navigator.getUserMedia() に代わるものです。コールバックを使用する代わりに、MediaStream にアクセスできる Promise を返します。デベロッパーは MediaDevices.getUserMedia() を使用することをおすすめしますが、navigator.getUserMedia() を削除する予定はありません。navigator.getUserMedia() は仕様の一部のままです

WebRTC サンプルサイトでデモをご覧いただけます。

デモのコード フラグメントは次のとおりです。

navigator.mediaDevices.getUserMedia(constraints)
    .then(function(stream) {
    var videoTracks = stream.getVideoTracks();
    console.log('Got stream with constraints:', constraints);
    console.log('Using video device: ' + videoTracks[0].label);
    stream.onended = function() {
        console.log('Stream ended');
    };
    window.stream = stream; // make variable available to console
    video.srcObject = stream;
    })
    .catch(function(error) {
    // ...
    }

旗の掲揚

enumerateDevices() メソッドは Chrome では「フラグなし」ですが、MediaDevices.getUserMedia() の場合は、chrome://flags で試験運用版のウェブ プラットフォーム機能を有効にするか、次のコマンドライン フラグを使用する必要があります。

--enable-blink-features=GetUserMedia

setSinkId() の場合も同様です。試験運用版のウェブ プラットフォーム機能を有効にするか、フラグを使用します。

--enable-blink-features=AudioOutputDevices

ブラウザのサポートに関する詳細は、以下をご覧ください。

今後について

提案されている ondevicechange イベント ハンドラは、その名前の通りの動作を行います。使用可能なデバイスのセットが変わると devicechange イベントがトリガーされ、ハンドラで enumerateDevices() を呼び出してデバイスの新しいリストを取得できます。これはまだどのブラウザにも実装されていません。

Screen Capture ドラフトは、Media Capture API の拡張機能であり、ユーザーのディスプレイの領域をメディア ストリームのソースとして使用できるようにする MediaDevices.getDisplayMedia() メソッドを提案しています。getSupportedConstraints()MediaDevices 拡張プロポーザルもあります。これは、getUserMedia() 呼び出しに使用できる制約(ブラウザでサポートされている音声と動画の機能)に関する情報を提供します。

デモ

補足説明