MediaDevices.getUserMedia()

MediaDevices.getUserMedia() メソッドは、要求された種類のメディアを含むトラックを持つ MediaStream を生成するメディア入力を使用する許可をユーザーに求めます。このストリームには、例えば、動画トラック (カメラ、ビデオ録画機器、スクリーン共有サービスなどのような、ハードウェアまたは仮想ビデオソースによって生み出される)、音声トラック (同様に、マイク、A/D 変換器などの物理的または仮想オーディオソースによって生み出される)、その他の可能な種別を含めることができます。

これは MediaStream オブジェクトに解決する Promise を返します。ユーザーが拒否した場合や、一致するメディアが利用できない場合、 Promise はそれぞれ NotAllowedError または NotFoundError で拒否されます。

メモ: ユーザが選択する必要が全くなく、リクエストを他順に無視できる場合、返却された Promise が解決または拒絶のどちらにもならない可能性があります。

一般的に、 MediaDevices のシングルトンオブジェクトは以下のように、 navigator.mediaDevices を使用してアクセスします。

navigator.mediaDevices.getUserMedia(constraints)
.then(function(stream) {
  /* ストリームを使用 */
})
.catch(function(err) {
  /* エラーをハンドル */
});

構文

var promise = navigator.mediaDevices.getUserMedia(constraints);

引数

constraints

MediaStreamConstraints オブジェクトで、それぞれの種類のために何らかの要件に沿って要求するメディアの種類を指定します。

constraints 引数は MediaStreamConstraints であり、二つのメンバー video および audio を持ち、要求されたメディアの種類を記述します。どちらか、または両方を指定する必要があります。ブラウザーが指定された条件に合う指定されたタイプを持つすべてのメディアトラックを発見できない場合、返却された Promise は NotFoundError で拒否されます。

次の例は特定の要件なしに audio と video の両方を要求します。

{ audio: true, video: true }

メディアの種類に true が指定された場合、結果のストリームはそのタイプのトラックが中にある必要があります。何らかの理由で含めることができない場合、 getUserMedia() の呼び出しはエラーが返ります。

ユーザーのカメラやマイクについての情報は、プライバシー上の理由からアクセスできませんが、アプリケーションは追加の制約を使用することで、カメラやマイクの能力を必要に応じて要求することができます。次の例は、 1280x720 のカメラ解像度の設定を表しています。

{
  audio: true,
  video: { width: 1280, height: 720 }
}

ブラウザーはこれに忠実であろうとしますが、正確に一致するものが使用できない場合や、ユーザーがこれをオーバーライドした場合は、異なる解像度を返すかもしれません。

機能を要求するために、 min, max, exact (つまり min == max) の各キーワードが使用できます。次の例は 1280x720 の最小解像度を要求しています。

{
  audio: true,
  video: {
    width: { min: 1280 },
    height: { min: 720 }
  }
}

この解像度以上のカメラがない場合、返却された Promise は OverconstrainedError として拒否され、ユーザーには通知されません。

動作が異なるの理由は、 min, max, exact のキーワードが本質的に必須であるのに対し、 ideal と呼ばれるプレインな値とキーワードはそうでないからです。より充実したサンプルを示します。

{
  audio: true,
  video: {
    width: { min: 1024, ideal: 1280, max: 1920 },
    height: { min: 776, ideal: 720, max: 1080 }
  }
}

ideal の値は、使用された場合は重みをもち、つまりブラウザーは ideal の値からみた最適距離が最小になるような設定 (および、複数ある場合はカメラ) を見つけようとすることを意味します。

プレインの値は本質的に ideal ですので、これは上記の解像度の例を以下のように書くこともできることを意味します。

{
  audio: true,
  video: {
    width: { ideal: 1280 },
    height: { ideal: 720 }
  }
}

すべての constraint が数字とは限りません。例えば、次の例はリアカメラよりもフロントカメラを (利用できるなら) を選好します。

{ audio: true, video: { facingMode: "user" } }

リアカメラが必要であれば、次のようにします。

{ audio: true, video: { facingMode: { exact: "environment" } } }

他の数値以外の制約として、 deviceId の制約があります。 deviceIdmediaDevices.enumerateDevices() から分かっているのであれば、これを使用して特定の機器を要求することができます。

{ video: { deviceId: myPreferredCameraDeviceId } }

上記のものは要求されたカメラを返しますが、特定したカメラが利用できない場合は別なカメラを返します。また、特定のカメラが必要なのであれば、以下のようにすることができます。

{ video: { deviceId: { exact: myExactCameraOrBustDeviceId } } }

返値

要求されたメディアが正しく取得できたときに MediaStream を受け取るハンドラーを示す Promise を返します。

例外

返却されたpromiseの拒否は DOMExceptionに構成されたMediaStreamErrorとして生成されます。関連するエラーは以下の通りです。

AbortError
Although the user and operating system both granted access to the hardware device, and no hardware issues occurred that would cause a NotReadableError, some problem occurred which prevented the device from being used.
NotAllowedError
The user has specified that the current browsing instance is not permitted access to the device; or the user has denied access for the current session; or the user has denied all access to user media devices globally.
Older versions of the specification used SecurityError for this instead; SecurityError has taken on a new meaning.
NotFoundError
constraint で指定された機能を満たすメディアトラックの種類が見つからない。
NotReadableError
Although the user granted permission to use the matching devices, a hardware error occurred at the operating system, browser, or Web page level which prevented access to the device.
OverconstrainedError
The specified constraints resulted in no candidate devices which met the criteria requested. The error is an object of type OverconstrainedError, and has a constraint property whose string value is the name of a constraint which was impossible to meet, and a message property containing a human-readable string explaining the problem.
Because this error can occur even when the user has not yet granted permission to use the underlying device, it can potentially be used as a fingerprinting surface.
SecurityError
User media support is disabled on the Document on which getUserMedia() was called. The mechanism by which user media support is enabled and disabled is left up to the individual user agent.
TypeError
The list of constraints specified is empty, or has all constraints set to false.

ユーザーのプライバシー

As an API that may involve significant privacy concerns, getUserMedia() is held by the specification to very specific requirements for user notification and permission management. First, getUserMedia() must always get user permission before opening any media gathering input such as a webcam or microphone. Browsers may offer a once-per-domain permission feature, but they must ask at least the first time, and the user must specifically grant ongoing permission if they choose to do so.

Of equal importance are the rules around notification. Browsers are required to display an indicator that shows that a camera or microphone is in use, above and beyond any hardware indicator that may exist. They must also show an indicator that permission has been granted to use a device for input, even if the device is not actively recording at the moment.

In Firefox, for example, the URL bar displays a pulsing red icon to indicate that recording is underway. The icon is gray if the permission is in place but recording is not currently underway. The device's physical light is used to indicate whether or not recording is currently active. If you've muted your camera (so-called "facemuting"), your camera's activity light goes out to indicate that the camera is not actively recording you, without discarding the permission to resume using the camera once muting is over.

幅と高さ

この例ではカメラの解像度の設定を与えて、結果の MediaStream オブジェクトを vide 要素に割り当てます。

// Prefer camera resolution nearest to 1280x720.
var constraints = { audio: true, video: { width: 1280, height: 720 } }; 

navigator.mediaDevices.getUserMedia(constraints)
.then(function(mediaStream) {
  var video = document.querySelector('video');
  video.srcObject = mediaStream;
  video.onloadedmetadata = function(e) {
    video.play();
  };
})
.catch(function(err) { console.log(err.name + ": " + err.message); }); // always check for errors at the end.

古いブラウザーでの新しい API の使用

Here's an example of using navigator.mediaDevices.getUserMedia(), with a polyfill to cope with older browsers. Note that this polyfill does not correct for legacy differences in constraints syntax, which means constraints won't work well across browsers. It is recommended to use the adapter.js polyfill instead, which does handle constraints.

// Older browsers might not implement mediaDevices at all, so we set an empty object first
if (navigator.mediaDevices === undefined) {
  navigator.mediaDevices = {};
}

// Some browsers partially implement mediaDevices. We can't just assign an object
// with getUserMedia as it would overwrite existing properties.
// Here, we will just add the getUserMedia property if it's missing.
if (navigator.mediaDevices.getUserMedia === undefined) {
  navigator.mediaDevices.getUserMedia = function(constraints) {

    // First get ahold of the legacy getUserMedia, if present
    var getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia;

    // Some browsers just don't implement it - return a rejected promise with an error
    // to keep a consistent interface
    if (!getUserMedia) {
      return Promise.reject(new Error('getUserMedia is not implemented in this browser'));
    }

    // Otherwise, wrap the call to the old navigator.getUserMedia with a Promise
    return new Promise(function(resolve, reject) {
      getUserMedia.call(navigator, constraints, resolve, reject);
    });
  }
}

navigator.mediaDevices.getUserMedia({ audio: true, video: true })
.then(function(stream) {
  var video = document.querySelector('video');
  // Older browsers may not have srcObject
  if ("srcObject" in video) {
    video.srcObject = stream;
  } else {
    // Avoid using this in new browsers, as it is going away.
    video.src = window.URL.createObjectURL(stream);
  }
  video.onloadedmetadata = function(e) {
    video.play();
  };
})
.catch(function(err) {
  console.log(err.name + ": " + err.message);
});

フレームレート

帯域幅に制限のあるWebRTC通信のようなケースでは、低フレームレートが望ましいかもしれません。

var constraints = { video: { frameRate: { ideal: 10, max: 15 } } };

フロントカメラとバックカメラ

携帯電話での例。

var front = false;
document.getElementById('flip-button').onclick = function() { front = !front; };

var constraints = { video: { facingMode: (front? "user" : "environment") } };

パーミッション

getUserMedia() をインストール可能なアプリ (たとえば、Firefox OS app) で使用するには、マニフェストファイルに一つまたは両方のフィールドを設定する必要があります。

"permissions": {
  "audio-capture": {
    "description": "Required to capture audio using getUserMedia()"
  },
  "video-capture": {
    "description": "Required to capture video using getUserMedia()"
  }
}

詳しくは permission: audio-capture および permission: video-capture をご覧ください。

仕様書

仕様書 状態 備考
Media Capture and Streams
MediaDevices.getUserMedia() の定義
勧告候補 初回定義

ブラウザーの対応

Update compatibility data on GitHub
デスクトップモバイル
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewAndroid 版 ChromeAndroid 版 FirefoxAndroid 版 OperaiOSのSafariSamsung Internet
getUserMediaChrome 完全対応 52
完全対応 52
未対応 47 — 52
補足 無効
補足 Older versions of Chrome implement navigator.webkitGetUserMedia, a prefixed form of the legacy navigator.getUserMedia API.
無効 From version 47 until version 52 (exclusive): this feature is behind the Experimental Web Platform features preference (needs to be set to Enabled). To change preferences in Chrome, visit chrome://flags.
Edge 完全対応 12Firefox 完全対応 36
補足
完全対応 36
補足
補足 Older versions of Firefox implement navigator.mozGetUserMedia, a prefixed form of the legacy navigator.getUserMedia API.
補足 Before Firefox 55, getUserMedia() incorrectly returns NotSupportedError when the list of constraints specified is empty, or has all constraints set to false. Starting in Firefox 55, this situation now correctly calls the failure handler with a TypeError.
補足 When using the Firefox-specific video constraint called mediaSource to request display capture, Firefox 66 and later consider values of screen and window to both cause a list of screens and windows to be shown.
補足 Starting in Firefox 66, getUserMedia() can no longer be used in sandboxed <iframe>s or data URLs entered in the address bar by the user.
IE 未対応 なしOpera 完全対応 40
完全対応 40
未対応 34 — 40
補足 無効
補足 Older versions of Opera implement navigator.webkitGetUserMedia, a prefixed form of the legacy navigator.getUserMedia API.
無効 From version 34 until version 40 (exclusive): this feature is behind the Experimental Web Platform features preference (needs to be set to Enabled).
Safari 完全対応 11WebView Android 完全対応 53Chrome Android 完全対応 52
完全対応 52
未対応 47 — 52
補足 無効
補足 Older versions of Chrome implement navigator.webkitGetUserMedia, a prefixed form of the legacy navigator.getUserMedia API.
無効 From version 47 until version 52 (exclusive): this feature is behind the Experimental Web Platform features preference (needs to be set to Enabled). To change preferences in Chrome, visit chrome://flags.
Firefox Android 完全対応 36
補足
完全対応 36
補足
補足 Older versions of Firefox implement navigator.mozGetUserMedia, a prefixed form of the legacy navigator.getUserMedia API.
補足 Before Firefox 55, getUserMedia() incorrectly returns NotSupportedError when the list of constraints specified is empty, or has all constraints set to false. Starting in Firefox 55, this situation now correctly calls the failure handler with a TypeError.
補足 When using the Firefox-specific video constraint called mediaSource to request display capture, Firefox 66 and later consider values of screen and window to both cause a list of screens and windows to be shown.
補足 Starting in Firefox 66, getUserMedia() can no longer be used in sandboxed <iframe>s or data URLs entered in the address bar by the user.
Opera Android 完全対応 41
完全対応 41
未対応 34 — 41
補足 無効
補足 Older versions of Opera implement navigator.webkitGetUserMedia, a prefixed form of the legacy navigator.getUserMedia API.
無効 From version 34 until version 41 (exclusive): this feature is behind the Experimental Web Platform features preference (needs to be set to Enabled).
Safari iOS 完全対応 11Samsung Internet Android 完全対応 あり
Secure context requiredChrome 完全対応 ありEdge 未対応 なしFirefox 完全対応 68IE 未対応 なしOpera ? Safari ? WebView Android 完全対応 ありChrome Android 完全対応 ありFirefox Android 完全対応 68Opera Android ? Safari iOS ? Samsung Internet Android ?

凡例

完全対応  
完全対応
未対応  
未対応
実装状況不明  
実装状況不明
実装ノートを参照してください。
実装ノートを参照してください。
ユーザーが明示的にこの機能を有効にしなければなりません。
ユーザーが明示的にこの機能を有効にしなければなりません。

関連情報