이 번역은 완료되지 않았습니다. 이 문서를 번역해 주세요.

MediaDevices getUserMedia() 메소드는 사용자에게 미디어 장치 사용 권한을 요청하며, 요청 수락시 미디어 트랙을 포함한 MediaStream 을 반환합니다. 스트림에 포함 가능한 비디오 트랙들은 웹캠, 가상 비디오 장치(obs, xsplit 등등), 카메라 등이 있으며, 오디오 트랙들은 웹캠에 내장된 마이크, 가상 오디오 장치(asio4all 등등), 외부 입력장치 등이 있습니다. 이 외에도 기능으로서 충족한다면 스트림에 포함할 수 있습니다.

MediaStream 객체를 성공적으로 얻었다면 Promise 형태로 반환합니다. 만약 사용자가 권한요청에 거부하거나 사용할 수 있는 미디어 장치가 없다면 promise는 rejected 상태로 PermissionDeniedError 또는 NotFoundError 를 반환합니다.

알림: 사용자에게 권한요청시 수락 또는 거부할 수 있는 메시지가 뜨지만, 선택이 강제사항은 아니므로 사용자는 단순히 무시할 수도 있습니다. 그렇기에 이에 대한 예외처리가 필요합니다. (권한 재요청, 서비스 이용제한 알림 등등)

일반적으로 MediaDevices 객체는 싱글톤 패턴으로 사용하며, 아래와 같이 navigator.mediaDevices 를 사용해 장치 사용 권한을 요청하여 스트림을 반환받을 수 있습니다.

navigator.mediaDevices.getUserMedia(constraints)
.then(function(stream) {
  /* 반환된 스트림을 사용 */
})
.catch(function(err) {
  /* 반환된 에러에 맞게 예외처리 */
});

문법

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

매개변수

constraints

MediaStreamConstraints 객체는 요청할 미디어 타입을 지정하며, 각 타입의 세부사항도 지정할 수 있습니다. (비디오 해상도, 비디오 프레임 등등)

constraints 매개변수는 video 와 audio 를 멤버변수로 가진 MediaStreamConstraints 객체를 사용합니다.

별도의 세부사항 없이 오디오와 비디오를 요청하는 constraints 매개변수 예제:

{ audio: true, video: true }

미디어 타입에 true 가 지정된 경우 각 타입에 맞는 장치가 사용 준비된 상태이어야 하며, 만약 사용 준비가 안 된 상태에서 getUserMedia() 를 호출하면 오류를 반환합니다.

constraints 매개변수에 세부사항을 지정하여 카메라와 마이크에 세부적인 요청을 할 수 있습니다. 아래의 코드는 비디오의 해상도를 1280x720로 지정하는 예제입니다.

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

브라우저는 지정한 해상도의 비디오 트랙을 가져오기 위해 시도하지만, 어떤 이유로든 지정한 해상도의 트랙을 가져올 수 없다면 다른 해상도의 비디오 트랙을 반환합니다.

아래와 같이 minmax 키워드를 사용하여 최소 해상도를 1280x720으로 지정할 수도 있으며, exact (논리적으로 min == max 와 같음) 키워드를 사용하여 특정 해상도를 지정할 수도 있습니다.

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

만약 카메라에서 지원하는 해상도 중에서 1280x720해상도가 없거나 이 이상의 해상도 역시 없는 경우 promise는 rejected 상태로 OverconstrainedError 를 반환하며, 사용자에게 미디어 장치 사용 권한 요청을 하지 않습니다.

minmax 키워드만 사용한 경우 최소, 최대 해상도를 지정할 수는 있지만, 브라우저는 최솟값을 기준으로 제공할 수 있는 해상도를 찾아 미디어 스트림을 반환합니다.  일반적으로 이러한 동작은 우리의 의도와 다릅니다. 그래서 ideal 키워드를 사용하여 이상적인 해상도를 지정할 수 있습니다.

아래의 코드를 논리적으로 해석하면 1024x776 - 1120x800 - 1350x1020 - 1920x1080 와 같이 지원하는 여러 해상도가 있으면 브라우저는 ideal 해상도와 가장 근사하는 1120x800 해상도를 미디어 장치에 요청 후 반환합니다.

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

아래와 같이 최솟값 최댓값 지정 없이 ideal 해상도만 지정할 수도 있습니다.

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

모바일 장치의 전면 카메라를 요청하기 위한 코드:

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

모바일 장치의 후면 카메라를 요청하기 위한 코드:

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

반환 값

요청한 미디어를 성공적으로 얻었다면 MediaStream 을 수신하는 핸들러가 Promise 형태로 스트림을 반환합니다.

예외

promise 이행이 실패하면 실패 처리 핸들러로 DOMException 에러 객체가 전달됩니다. 발생 가능한 에러 종류:

AbortError
사용자와 운영체제에서 하드웨어 장치 사용 권한을 부여받고 NotReadableError 에러를 발생시키는 하드웨어 문제가 발생하지 않았지만, 다른 프로그램에서 해당 장치를 사용 중인 경우 이 에러가 발생합니다.
NotAllowedError
사용자가 브라우저 설정을 통해 장치에 대한 접근권한을 차단하였거나 장치 사용 권한 요청에 거부한 경우 이 에러가 발생합니다. 이 외에도 어떤 식으로든 장치에 대한 접근을 차단하였다면 이 에러가 발생합니다.
이전 버전의 규격에서는 이 에러와 SecurityError 를 동일한 의미로 사용하였지만, 현재 버전에서는 다른 의미로 사용하므로 혼용하여선 안 됩니다.
NotFoundError
constraints 매개변수 조건에 맞는 미디어 트랙이 없는 경우 이 에러가 발생합니다.
NotReadableError
사용자가 접근 권한을 부여했고 조건에 맞는 미디어 트랙도 있지만 어떤 이유로든 장치에 액세스 할 수 없어서 운영체제, 브라우저, 웹 페이지 레벨에서 하드웨어 에러가 발생하여 이 에러가 발생합니다.
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.

User privacy

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.

Examples

Width and height

This example gives a preference for camera resolution, and assigns the resulting MediaStream object to a video element.

// 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.

Using the new API in older browsers

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);
});

Frame rate

Lower frame-rates may be desirable in some cases, like WebRTC transmissions with bandwidth restrictions.

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

Front and back camera

On mobile phones.

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

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

Permissions

To use getUserMedia() in an installable app (for example, a Firefox OS app), you need to specify one or both of the following fields inside your manifest file:

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

See permission: audio-capture and permission: video-capture for more information.

Specifications

Specification Status Comment
Media Capture and Streams
The definition of 'MediaDevices.getUserMedia()' in that specification.
Candidate Recommendation Initial definition

Browser compatibility

FeatureChromeEdgeFirefoxInternet ExplorerOperaSafari
Basic support

52

47 — 521 2

Yes363 4 No

40

34 — 405 6

11
Secure context required Yes ? ? ? ? ?
FeatureAndroid webviewChrome for AndroidEdge mobileFirefox for AndroidOpera AndroidiOS SafariSamsung Internet
Basic support53

52

47 — 521 2

Yes363

40

34 — 405 6

11 ?
Secure context required ? Yes ? ? ? ? ?

1. Older versions of Chrome implement navigator.webkitGetUserMedia, a prefixed form of the legacy navigator.getUserMedia API.

2. 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.

3. Older versions of Firefox implement navigator.mozGetUserMedia, a prefixed form of the legacy navigator.getUserMedia API.

4. 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.

5. Older versions of Opera implement navigator.webkitGetUserMedia, a prefixed form of the legacy navigator.getUserMedia API.

6. From version 34 until version 40 (exclusive): this feature is behind the Experimental Web Platform features preference (needs to be set to Enabled).

See also

문서 태그 및 공헌자

이 페이지의 공헌자: sgim74528
최종 변경자: sgim74528,