MediaDevices.ondevicechange

MediaDevices.ondevicechangeプロパティはEventHandlerであり、MediaDevicesインスタンスでdevicechangeが発生した時に呼び出される関数です。このイベントは、user agent、Webサイト、アプリケーションによって利用可能なメディアデバイスの一覧が変更された時に発生します。更新された利用可能デバイスの一覧はenumerateDevices()によっていつでも取得することができます。

文法

MediaDevices.ondevicechange = eventHandler;

devicechangeイベントが発生したことを示すEventオブジェクトを入力として受け付ける関数を指定してください。このイベントオブジェクトには、変更に関する情報が含まれていませんので、更新されたデバイスの一覧を取得したい場合は、enumerateDevices()を呼び出してください。

この例では、updateDeviceList()という関数があり、この関数はMediaDevices.getUserMedia()が成功して、ストリームを取得できた時に一度だけ呼び出され、その後デバイスの一覧に変更があった場合も複数回呼び出されます。この関数は、ブラウザウィンドウに2つの一覧を出力します。1つは、オーディオデバイスの一覧であり、もう1つはビデオデバイスの一覧です。これら2つのリストは、デバイスラベル (名前)とこのデバイスが入力か出力であるかを示すものです。この例では、devicechangeイベントのハンドラを設定しているので、実行中にデバイスが接続または接続を解除されるたびに一覧が更新されます。

オーディオとビデオデバイスの一覧に使用される<ul>要素への参照を保持するためのグローバル変数を用意します。

let audioList = document.getElementById("audioList");
let videoList = document.getElementById("videoList");

デバイス一覧 の取得と描画

updateDeviceList()メソッドでは、現在のメディアデバイスの一覧を取得した後、先ほど用意したグローバル変数を用いて、表示されているオーディオとビデオのデバイス一覧を更新します。

function updateDeviceList() {
  navigator.mediaDevices.enumerateDevices()
  .then(function(devices) {
    audioList.innerHTML = "";
    videoList.innerHTML = "";
    
    devices.forEach(function(device) {
      let elem = document.createElement("li");      
      let [kind, type, direction] = device.kind.match(/(\w+)(input|output)/i);
      
      elem.innerHTML = "<strong>" + device.label + "</strong> (" + direction + ")";
      if (type === "audio") {
        audioList.appendChild(elem);
      } else if (type === "video") {
        videoList.appendChild(elem);
      }
    });
  });
}

updateDeviceList()は、navigator.mediaDevicesプロパティから参照できるMediaDevicesオブジェクトにあるenumerateDevices()関数の呼び出しから構成されます。コードが実行されるのは、enumerateDevices()によって返されたpromiseが完了した時です。デバイス一覧の準備ができると、完了ハンドラが呼び出されます。このデバイス一覧は、完了ハンドラの引数としてMediaDeviceInfoオブジェクトの配列で渡されます。この配列のそれぞれの要素は、1つのメディア入力デバイスまたは出力デバイスについての情報を含みます。

すべてのデバイスの情報を出力するために、forEach()ループを使用します。それぞれのデバイスで、ユーザへこのデバイス情報を見せるために新しい<li>オブジェクトを作成します。

let [kind, type, direction] = device.kind.match(/(\w+)(input|output)/i);の行について詳しく説明します。ここでは分割代入 (ECMAScript 6の新しい機能)を使用しており、String.match()によって返された配列の値をkindtypedirectionの変数へ代入しています。なぜこのようなことをするのかというと、MediaDeviceInfo.kindの文字列は、"audioinput"や"videooutput"のように、メディアタイプとメディアフローの向きの2つの情報を含んでいるためです。この行で、タイプ("audio"または"video")と方向("input"と"output")を取り出すことで、リストに表示する文字列を作成することができます。

太字のデバイス名と括弧で囲まれた方向を含む文字列が作成されると、デバイスタイプに基づいてaudioListまたはvideoList対応する一覧へappendChild()の呼び出しによって追加されます。

デバイス一覧の変更を扱う

updateDeviceList()は2箇所から呼び出されます。1箇所目はgetUserMedia()のpromiseの完了ハンドラであり、ストリームが開かれた時に最初に一覧を埋めます。2箇所目はdevicechangeのイベントハンドラからです。

navigator.mediaDevices.ondevicechange = function(event) {
  updateDeviceList();
}

このコードでは、ユーザがカメラ、マイク、他のメディアデバイスを接続したり、電源を入れたり、電源を切ったりする度に、updateDeviceList()を呼び出し接続されたデバイス一覧を再描画します。

結果

仕様

仕様 状況 コメント
Media Capture and Streams
ondevicechange の定義
勧告候補 初版

ブラウザ互換性

現在、互換性データを可読形式の JSON フォーマットに置き換えているところです。 この互換性一覧は古い形式を使っており、これに含まれるデータの置き換えが済んでいません。 手助けしていただける場合は、こちらから!

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari (WebKit)
Basic support 57 51 (51) ? 34 ?
Feature Android Webview Chrome for Android Firefox Mobile (Gecko) IE Phone Opera Mobile Safari Mobile
Basic support 未サポート 未サポート ? 未サポート 34 ?

Support for this event was added for Linux and Windows—and it was enabled by default—starting in Firefox 52.

[1] devicechangeイベントとMediaDevices.ondevicechangeのサポートはFirefox 51からですが、ただしMacだけであり、デフォルトで無効になっています。有効にするには、media.ondevicechange.enabledtrueに設定してください。Firefox 52から、LinuxとWindowsでサポートされており、デフォルトで有効になっています。

関連項目

ドキュメントのタグと貢献者

このページの貢献者: e53e04ac
最終更新者: e53e04ac,