Audio & Video Capture
The Media Capture API allows authorized Web applications to access the streams from the device's audio and video capturing interfaces, i.e. to use the data available from the camera and the microphone. The streams exposed by the API can be bound directly to the HTML <audio>
or <video>
elements or read and manipulated in the code, including further more specific processing via Image Capture API, Media Recorder API or Real-Time Communication.
There is also a higher level alternative built-in into mobile operating systems like iOS and Android that doesn't require any JavaScript API - the basic HTML <input type="file" accept="image/*">
element allows launching any application that provides an image file, including camera.
API glimpse
navigator.mediaDevices.getUserMedia(constraints)
- Prompts user for an access to the media interface specified by the
constraints
and returns aPromise
that is resolved with the interface's stream handler. stream.getAudioTracks()
- Returns a collection of audio tracks objects being provided by the device's microphone.
stream.getVideoTracks()
- Returns a collection of video tracks objects being provided by the device's camera.
mediaElement.srcObject = stream
- Sets a stream to be rendered into the provided
<audio>
or<video>
DOM element.
Previous version of the standard, supported with vendor prefixes, contained the callback-based getUserMedia
method directly within the navigator
element:
navigator.webkitGetUserMedia(constraints, successCallback, errorCallback)
Live Demo
-
function getUserMedia(constraints) { // if Promise-based API is available, use it if (navigator.mediaDevices) { return navigator.mediaDevices.getUserMedia(constraints); } // otherwise try falling back to old, possibly prefixed API... var legacyApi = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia; if (legacyApi) { // ...and promisify it return new Promise(function (resolve, reject) { legacyApi.bind(navigator)(constraints, resolve, reject); }); } } function getStream (type) { if (!navigator.mediaDevices && !navigator.getUserMedia && !navigator.webkitGetUserMedia && !navigator.mozGetUserMedia && !navigator.msGetUserMedia) { alert('User Media API not supported.'); return; } var constraints = {}; constraints[type] = true; getUserMedia(constraints) .then(function (stream) { var mediaControl = document.querySelector(type); if ('srcObject' in mediaControl) { mediaControl.srcObject = stream; } else if (navigator.mozGetUserMedia) { mediaControl.mozSrcObject = stream; } else { mediaControl.src = (window.URL || window.webkitURL).createObjectURL(stream); } mediaControl.play(); }) .catch(function (err) { alert('Error: ' + err); }); }
-
<div class="columns"> <div class="column"> <p><button type="button" onclick="getStream('video')">Grab video</button></p> <video controls autoplay style="height:180px; width: 240px;"></video> </div> <div class="column"> <p><button type="button" onclick="getStream('audio')">Grab audio</button></p> <audio controls></audio> </div> </div>