MediaDevices: getUserMedia() method
BaselineWidely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2017.
Secure context: This feature is available only insecure contexts (HTTPS), in some or allsupporting browsers.
ThegetUserMedia()
method of theMediaDevices
interface prompts the user for permission to use a media input which produces aMediaStream
with tracks containing the requested types of media.
That stream can include, for example, a video track (produced by either a hardware or virtual video source such as a camera, video recording device, screen sharing service, and so forth), an audio track (similarly, produced by a physical or virtual audio source like a microphone, A/D converter, or the like), and possibly other track types.
It returns aPromise
that resolves to aMediaStream
object.If the user denies permission, or matching media is not available, then the promise is rejected withNotAllowedError
orNotFoundError
DOMException
respectively.
Note:It's possible for the returned promise toneither resolve nor reject, as the user is not required to make a choice at all and may ignore the request.
Syntax
getUserMedia(constraints)
Parameters
constraints
An object specifying the types of media torequest, along with any requirements for each type.
The
constraints
parameter is an object with two members:video
andaudio
, describing the media types requested. Either or both must bespecified. If the browser cannot find all media tracks with the specified types thatmeet the constraints given, then the returned promise is rejected withNotFoundError
DOMException
.For both
video
andaudio
, its value is either a boolean or an object. The default value isfalse
.- If
true
is specified for a media type, the resulting stream isrequired to have that type of track in it. If one cannot be included for any reason, the returned promise will reject. - If
false
is specified for a media type, the resulting streammust not have that type of track, or the returned promise will reject. Because bothvideo
andaudio
default tofalse
, if theconstraints
object contains neither property or if it's not present at all, the returned promise will always reject. - If an object is specified for a media type, the object is read as a
MediaTrackConstraints
dictionary.
- If
Return value
APromise
whose fulfillment handler receives aMediaStream
object when the requested media has successfully been obtained.
Exceptions
AbortError
DOMException
Although the user and operating system both granted access to the hardware device,and no hardware issues occurred that would cause a
NotReadableError
DOMException
, throw if someproblem occurred which prevented the device from being used.InvalidStateError
DOMException
Thrown if current document is not fully active.
NotAllowedError
DOMException
Thrown if one or more of the requested source devices cannot be used at this time. This willhappen if the browsing context is insecure (that is, the page was loaded using HTTPrather than HTTPS). It also happens if the user has specified that the currentbrowsing instance is not permitted access to the device, the user has denied accessfor the current session, or the user has denied all access to user media devicesglobally. On browsers that support managing media permissions withPermissions Policy, this error isreturned if Permissions Policy is not configured to allow access to the input source(s).
Note:Older versions of the specification used
SecurityError
for this instead;SecurityError
has taken on a new meaning.NotFoundError
DOMException
Thrown if no media tracks of the type specified were found that satisfy the given constraints.
NotReadableError
DOMException
Thrown if, although the user granted permission to use the matching devices, a hardware erroroccurred at the operating system, browser, or Web page level which prevented access tothe device.
OverconstrainedError
DOMException
Thrown if the specified constraints resulted in no candidate devices which met the criteriarequested. The error is an object of type
OverconstrainedError
, and has aconstraint
property whose string value is the name of a constraint whichwas impossible to meet, and amessage
property containing ahuman-readable string explaining the problem.Note:Because this error can occur even when the user has not yet grantedpermission to use the underlying device, it can potentially be used as afingerprinting surface.
SecurityError
DOMException
Thrown if user media support is disabled on the
Document
on whichgetUserMedia()
was called. The mechanism by which user media support isenabled and disabled is left up to the individual user agent.TypeError
Thrown if the list of constraints specified is empty, or has all constraints set to
false
. This can also happen if you try to callgetUserMedia()
in an insecure context, sincenavigator.mediaDevices
isundefined
in an insecurecontext.
Privacy and security
As an API that may involve significant privacy concerns,getUserMedia()
'sspecification lays out a wide array of privacy and security requirements that browsersare obligated to meet.
getUserMedia()
is a powerful feature that can only be used insecure contexts; in insecurecontexts,navigator.mediaDevices
isundefined
, preventingaccess togetUserMedia()
. A secure context is, in short, a page loadedusing HTTPS or thefile:///
URL scheme, or a page loaded fromlocalhost
.
In addition, user permission is always required to access the user's audio and videoinputs. Only a window's top-level document context for a valid origin can even requestpermission to usegetUserMedia()
, unless the top-level context expresslygrants permission for a given<iframe>
to do so usingPermissions Policy. Otherwise, the userwill never even be asked for permission to use the input devices.
For additional details on these requirements and rules, how they are reflected in thecontext in which your code is running, and about how browsers manage user privacy andsecurity issues, read on.
User privacy
As an API that may involve significant privacy concerns,getUserMedia()
isheld by the specification to very specific requirements for user notification andpermission management. First,getUserMedia()
must always get userpermission 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 thefirst time, and the user must specifically grant ongoing permission if they choose to doso.
Of equal importance are the rules around notification. Browsers are required to displayan indicator that shows that a camera or microphone is in use, above and beyond anyhardware indicator that may exist. They must also show an indicator that permission hasbeen granted to use a device for input, even if the device is not actively recording atthe moment.
For example in Firefox, the URL bar displays a pulsing red icon to indicate thatrecording is underway. The icon is gray if the permission is in place but recording isnot currently underway. The device's physical light is used to indicate whether or notrecording 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 activelyrecording you, without discarding the permission to resume using the camera once mutingis over.
Security
There are a number of ways security management and controls in auser agent can causegetUserMedia()
to return a security-related error.
Permissions Policy
The twoPermissions Policy directives that apply togetUserMedia()
arecamera
andmicrophone
.
For example, this HTTP header will enable use of a camera by the documentand any embedded<iframe>
elements that are loaded from the sameorigin:
Permissions-Policy: camera=(self)
This will request access to the microphone for the current origin and the specificoriginhttps://developer.mozilla.org
:
Permissions-Policy: microphone=(self "https://developer.mozilla.org")
If you're usinggetUserMedia()
within an<iframe>
, youcan request permission just for that frame, which is clearly more secure than requestinga more general permission. Here, indicate we need the ability to use both camera andmicrophone:
<iframe src="https://mycode.example.net/etc" allow="camera; microphone"></iframe>
Encryption based security
ThegetUserMedia()
method is only available insecure contexts. A secure contextis one the browser is reasonably confident contains a document which was loadedsecurely, using HTTPS/TLS, and has limited exposure to insecure contexts. If a documentisn't loaded in a secure context, thenavigator.mediaDevices
property isundefined
, making access togetUserMedia()
impossible.
Attempting to accessgetUserMedia()
in this situation will result in aTypeError
.
Document source security
Because of the obvious security concern associated withgetUserMedia()
ifused unexpectedly or without security being carefully managed, it can only be used insecure contexts. There are a number of insecure ways to load a document that might, inturn, attempt to callgetUserMedia()
. The following are examples ofsituations in whichgetUserMedia()
is not permitted to be called:
- A document loaded into a sandboxed
<iframe>
element cannot callgetUserMedia()
unless the<iframe>
has itssandbox
attribute set toallow-same-origin
. - A document loaded using a
data://
orblob://
URL which hasno origin (such as when one of these URLs is typed by the user into the address bar)cannot callgetUserMedia()
. These kinds of URLs loaded from JavaScriptcode 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 aframe.
Examples
Using getUserMedia()
Generally, you will access theMediaDevices
singleton object usingnavigator.mediaDevices
, like this:
async function getMedia(constraints) { let stream = null; try { stream = await navigator.mediaDevices.getUserMedia(constraints); /* use the stream */ } catch (err) { /* handle the error */ }}
Similarly, using the raw promises directly, the code looks like this:
navigator.mediaDevices .getUserMedia(constraints) .then((stream) => { /* use the stream */ }) .catch((err) => { /* handle the error */ });
Note:If the current document isn't loaded securely,navigator.mediaDevices
will beundefined
, and you cannot usegetUserMedia()
. SeeSecurity for more information on this andother security issues related to usinggetUserMedia()
.
Below are some examples of theconstraints
parameter.
The following requests both audio and video without any specific requirements:
getUserMedia({ audio: true, video: true,});
While information about a user's cameras and microphones are inaccessible forprivacy reasons, an application can request the camera and microphone capabilitiesit needs and wants, using additional constraints. The following expresses apreference for 1280x720 camera resolution:
getUserMedia({ audio: true, video: { width: 1280, height: 720 },});
The browser will try to honor this, but may return otherresolutions if an exact match is not available, or the user overrides it.
Torequire a capability, use the keywordsmin
,max
, orexact
(a.k.a.min === max
). Thefollowing demands a minimum resolution of 1280x720:
getUserMedia({ audio: true, video: { width: { min: 1280 }, height: { min: 720 }, },});
If no camera exists with this resolution or higher, then the returned promise willbe rejected withOverconstrainedError
, and the user will not beprompted.
The reason for the difference in behavior is that the keywordsmin
,max
, andexact
are inherently mandatory — whereas plainvalues and a keyword calledideal
are not. Here's a full example:
getUserMedia({ audio: true, video: { width: { min: 1024, ideal: 1280, max: 1920 }, height: { min: 576, ideal: 720, max: 1080 }, },});
Anideal
value, when used, has gravity — which means that the browserwill try to find the setting (and camera, if you have more than one), with thesmallestfitness distance from the ideal values given.
Plain values are inherently ideal, which means that the first of our resolutionexamples above could have been written like this:
getUserMedia({ audio: true, video: { width: { ideal: 1280 }, height: { ideal: 720 }, },});
Not all constraints are numbers. For example, on mobile devices, the following willprefer the front camera (if one is available) over the rear one:
getUserMedia({ audio: true, video: { facingMode: "user" },});
Torequire the rear camera, use:
getUserMedia({ audio: true, video: { facingMode: { exact: "environment" }, },});
Another non-number constraint is thedeviceId
constraint. If you haveadeviceId
frommediaDevices.enumerateDevices()
, you canuse it to request a specific device:
getUserMedia({ video: { deviceId: myPreferredCameraDeviceId, },});
The above will return the camera you requested, or a different camera if thatspecific camera is no longer available. Again, torequire the specificcamera, you would use:
getUserMedia({ video: { deviceId: { exact: myExactCameraOrBustDeviceId, }, },});
Width and height
This example gives a preference for camera resolution, and assigns the resultingMediaStream
object to a video element.
// Prefer camera resolution nearest to 1280x720.const constraints = { audio: true, video: { width: 1280, height: 720 },};navigator.mediaDevices .getUserMedia(constraints) .then((mediaStream) => { const video = document.querySelector("video"); video.srcObject = mediaStream; video.onloadedmetadata = () => { video.play(); }; }) .catch((err) => { // always check for errors at the end. console.error(`${err.name}: ${err.message}`); });
Frame rate
Lower frame-rates may be desirable in some cases, like WebRTC transmissions withbandwidth restrictions.
const constraints = { video: { frameRate: { ideal: 10, max: 15 } },};
Front and back camera
On mobile phones.
let front = false;document.getElementById("flip-button").onclick = () => { front = !front;};const constraints = { video: { facingMode: front ? "user" : "environment" },};
Note:In certain cases, it may be necessary to release the current camera facing mode before you can switch to a different one. To ensure the camera switch, it is advisable to free up the media resources by invoking the "stop()" method on the track before requesting a different facing mode.
Specifications
Specification |
---|
Media Capture and Streams # dom-mediadevices-getusermedia |
Browser compatibility
See also
- The older
Navigator.getUserMedia()
legacy API MediaDevices.enumerateDevices()
: Listing available media devices- WebRTC API
- Media Capture and Streams API
- Screen Capture API: Capturing screen contents as a
MediaStream
MediaDevices.getDisplayMedia()
: Getting a stream containing screen contents- Taking webcam photos: A tutorial on using
getUserMedia()
to take still photos rather than video