MediaDevices.getUserMedia()

This translation is incomplete. この記事の翻訳にご協力ください

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

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

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

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

async function getMedia(constraints) {
  let stream = null;

  try {
    stream = await navigator.mediaDevices.getUserMedia(constraints);
    /* ストリームを使用 */
  } catch(err) {
    /* エラーを処理 */
  }
}

同様に、生の Promise を直接使用すると、コードは次のようになります。

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

メモ: 現在の文書が安全に読み込まれなかった場合は、 navigator.mediaDevicesundefined になり、 getUserMedia() を使用することはできません。セキュリティの節に、この件やその他の getUserMedia() のし尿に関するセキュリティ問題の詳細があります。

構文

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
One or more of the requested source devices cannot be used at this time. This will happen if the browsing context is insecure (that is, the page was loaded using HTTP rather than HTTPS). It also happens if the user has specified that the current browsing instance is not permitted access to the device, the user has denied access for the current session, or the user has denied all access to user media devices globally. On browsers that support managing media permissions with Feature Policy, this error is returned if Feature Policy is not configured to allow access to the input source(s).
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. This can also happen if you try to call getUserMedia() in an insecure context, since navigator.mediaDevices is undefined in an insecure context.

プライバシーとセキュリティ

As an API that may involve significant privacy concerns, getUserMedia()'s specification lays out a wide array of privacy and security requirements that browsers are obligated to meet.

getUserMedia() is a powerful feature which can only be used in secure contexts; in insecure contexts, navigator.mediaDevices is undefined, preventing access to getUserMedia(). A secure context is, in short, a page loaded using HTTPS or the file:/// URL scheme, or a page loaded from localhost.

In addition, user permission is always required to access the user's audio and video inputs. Only a window's top-level document context for a valid origin can even request permission to use getUserMedia(), unless the top-level context expressly grants permission for a given <iframe> to do so using Feature Policy. Otherwise, the user will never even be asked for permission to use the input devices.

For additional details on these requirements and rules, how they are reflected in the context in which your code is running, and about how browsers manage user privacy and security issues, read on.

ユーザーのプライバシー

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.

For example in Firefox, 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.

Security

There are a number of ways security management and controls in a user agent can cause getUserMedia() to return a security-related error.

Note: The security model for getUserMedia() is still somewhat in flux. The originally-designed security mechanism is in the process of being replaced with Feature Policy, so various browsers have different levels of security support, using different mechanisms. You should test your code carefully on a variety of devices and browsers to be sure it is as broadly compatible as possible

Feature Policy

The Feature Policy security management feature of HTTP is in the process of being introduced into browsers, with support available to some extent in many browsers (though not always enabled by default, as in Firefox). getUserMedia() is one method which will require the use of Feature Policy, and your code needs to be prepared to deal with this. For example, you may need to use the allow attribute on any <iframe> that uses getUserMedia(), and pages that use getUserMedia() will eventually need to supply the Feature-Policy header.

The two permissions that apply to getUserMedia() are camera and microphone.

For example, this line in the HTTP headers will enable use of a camera for the document and any embedded <iframe> elements that are loaded from the same origin:

Feature-Policy: camera 'self'

This will request access to the microphone for the current origin and the specific origin https://developer.mozilla.org:

Feature-Policy: microphone 'self' https://developer.mozilla.org

If you're using getUserMedia() within an <iframe>, you can request permission just for that frame, which is clearly more secure than requesting a more general permission. Here, indicate we need the ability to use both camera and microphone:

<iframe src="https://mycode.example.net/etc" allow="camera;microphone">
</iframe>

Read our guide, Using Feature Policy, to learn more about how it works.

Encryption based security

The getUserMedia() method is only available in secure contexts. A secure context is one the browser is reasonably confident contains a document which was loaded securely, using HTTPS/TLS, and has limited exposure to insecure contexts. If a document isn't loaded in a secure context, the navigator.mediaDevices property is undefined, making access to getUserMedia() impossible.

Attempting to access getUserMedia() in this situation will result in a TypeError.

Document source security

Because of the obvious security concern associated with getUserMedia() if used unexpectedly or without security being carefully managed, it can only be used in secure contexts. There are a number of insecure ways to load a document that might, in turn, attempt to call getUserMedia(). The following are examples of situations in which getUserMedia() is not permitted to be called:

  • A document loaded into a sandboxed <iframe> element cannot call getUserMedia() unless the <iframe> has its sandbox attribute set to allow-same-origin.
  • A document loaded using a data:// or blob:// URL which has no origin (such as when one of these URLs is typed by the user into the address bar) cannot call getUserMedia(). These kinds of URLs loaded from JavaScript code inherit the script's permissions.
  • Any other situation in which there is no origin, such as when the srcdoc attribute is used to specify the contents of a frame.

幅と高さ

この例ではカメラの解像度の設定を与えて、結果の 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") } };

仕様書

仕様書 状態 備考
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 完全対応 6.0
Secure context requiredChrome 完全対応 ありEdge 未対応 なしFirefox 完全対応 68IE 未対応 なしOpera ? Safari ? WebView Android 完全対応 ありChrome Android 完全対応 ありFirefox Android 完全対応 68Opera Android ? Safari iOS ? Samsung Internet Android 完全対応 あり

凡例

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

関連情報