What Web Can Do Today?

Can I rely on the Web Platform features to build my app?

An overview of the device integration HTML5 APIs

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 a Promise 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>

Resources

Get in touch