最新のブラウザでは、カメラ、マイク、スピーカーなどの入出力デバイスを選択できます。
次に例を示します。
- スマートフォンで、前面カメラまたは背面カメラを選択します。
- ノートパソコンで、内蔵スピーカーまたは Bluetooth で接続されたスピーカーを選択します。
- ビデオチャットの場合は、内蔵または外付けのマイクまたはカメラを選択します。
この機能はすべて、navigator.mediaDevices
によって返される MediaDevices オブジェクトによって公開されます。
MediaDevices には enumerateDevices()
と getUserMedia()
という 2 つのメソッドがあり、どちらもパソコン版と Android 版の Chrome 47 で実装されています。
enumerateDevices()
使用可能なデバイスの MediaDeviceInfo
オブジェクトの配列へのアクセス権を付与する Promise を返します。
このメソッドは MediaStreamTrack.getSources()
に似ていますが、これまで Chrome に実装されていたメソッドとは異なり、標準に準拠しており、オーディオ出力デバイスが含まれています。以下のデモで試すことができます。
このデモの 1 つを簡略化してコードを示します。
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()
を削除する予定はありません。引き続き仕様の一部です。
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) {
// ...
}
旗を放棄する顔
Chrome の enumerateDevices()
メソッドは「フラグレス」ですが、MediaDevices.getUserMedia()
については、chrome://flags で試験運用版のウェブ プラットフォーム機能を有効にするか、次のコマンドライン フラグを使用する必要があります。
--enable-blink-features=GetUserMedia
setSinkId()
の場合: 試験運用版のウェブ プラットフォーム機能を有効にするか、フラグを使用します。
--enable-blink-features=AudioOutputDevices
ブラウザ サポートの詳細については、以下をご覧ください。
今後の計画
提案された ondevicechange
イベント ハンドラは、その内容を実行します。つまり、使用可能な一連のデバイスが変更されたときに devicechange
イベントが発行され、ハンドラ内で enumerateDevices()
を呼び出して新しいデバイスリストを取得できます。この API はまだどのブラウザにも実装されていません。
Screen Capture draftは Media Capture API の拡張機能で、ユーザー ディスプレイの領域をメディア ストリームのソースとして使用できるようにする MediaDevices.getDisplayMedia()
メソッドを提案します。また、getSupportedConstraints()
に対する MediaDevices
拡張機能の提案もあります。これは、getUserMedia()
通話に使用できる制約(ブラウザでサポートされている音声機能と動画機能)に関する情報を提供します。
デモ
- getUserMedia()
- enumerateDevices():
- MediaDevices shim
補足説明
- Mozilla Developer Network: メディア デバイス
- 実装ステータス
- メディア キャプチャとストリーム編集者のドラフト: MediaDevices
- Audio Output Devices API