• Stars
    star
    908
  • Rank 48,370 (Top 1.0 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 12 years ago
  • Updated almost 7 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Shim for getUserMedia(). Uses native implementation for modern browsers and a Flash fallback for everyone else.

getUserMedia.js!

getUserMedia.js is a cross-browser shim for the getUserMedia() API (a part of WebRTC) that supports accessing a local camera device from inside the browser. Where WebRTC support is detected, it will use the browser's native getUserMedia() implementation, otherwise a Flash fallback will be loaded instead.

Screenshot

Screenshot

Notes

firefox!

One-time permission requests

In previous versions, we created a getUserMedia() instance to check for feature support, then created a separate instance for usage. This caused permissions to use a device to be requested twice. In 1.x, we simply re-use the original instance so we require minimal action from the user.

bars!

Support for a new noFallback option

As more and more browsers begin landing stable implementations of getUserMedia, you may wish to have the option to turn off our Flash fallback feature. This can now easily be done by passing noFallback: true in our options. Check out face-detection-demo/js/demo.js for where to place this. Alternatively, feel free to use lib/getUserMedia.noFallback.js for a version of the library with Flash support stripped out.

Compatibility with the latest implementations

object!

Getting Started

As you can see in the demo, what the shim provides is more than enough to create interactive applications that can relay device pixel information on to other HTML5 elements such as the canvas. By relaying, you can easily achieve tasks like capturing images which can be saved, applying filters to the data, or as shown in the demo, even performing tasks like facial detection.

The shim currently works in all modern browsers and IE8+.

Walkthough

Getting the shim working is fairly straightforward, but you may be interested in checking out the sample application in face-detection-demo/demo.html for further information. First, include the getusermedia.js script in your page. Below we're using the minified version built by the grunt.js build process.

<script src="dist/getUserMedia.min.js"> </script>

Next, define mark-up that we can use as a container for the video stream. Below you'll notice that a simple div has been opted for (as per our demo). What will happen when we initialize the shim with it is we will either inject a video tag for use (if WebRTC is enabled) or alternatively an object tag if the Flash fallback needs to be loaded instead. Whilst most modern browsers will support the video tag, there is no reason to be using it here if your only interest is relaying the video data for further processing or use elsewhere.

<div id="webcam"></div>

Calling the shim is as simple as: getUserMedia(options, success, error); where options is an object containing configuration data, success is a callback executed when the stream is successfully streaming, and error is a callback for catching stream or device errors.

We use the configuration object (options in the above) to specify details such as the element to be used as a container, (e.g webcam), the quality of the fallback image stream (85) and a number of additional callbacks that can be further used to trigger behaviour. Callbacks beginning with on in the below example are Flash-specific callbacks. If you don't need to use Flash, feel free to exclude them from your code.

// options contains the configuration information for the shim.
// It allows us to specify the width and height of the video
// output we're working with, the location of the fallback swf,
// events that are triggered onCapture and onSave (for the fallback)
// and so on.
var options = {

	"audio": true,
	"video": true,

	// the element (by id) you wish to use for 
	// displaying the stream from a camera
	el: "webcam",

	extern: null,
	append: true,

	// height and width of the output stream container

	width: 320,
	height: 240,

	// the recommended mode to be used is 
	// 'callback', where a callback is executed 
	// once data is available
	mode: "callback",

	// the flash fallback URL
	swffile: "fallback/jscam_canvas_only.swf",

	// quality of the fallback stream
	quality: 85,

	// a debugger callback is available if needed
	debug: function () {},

	// callback for capturing the fallback stream
	onCapture: function () {
		window.webcam.save();
	},

	// callback for saving the stream, useful for
	// relaying data further.
	onSave: function (data) {},
	onLoad: function () {}
};

Below is a sample success callback taken from the demo application, where we update the video tag we've injected with the stream data. Note that it's also possible to capture stream errors by executing calls from within video.onerror() in the example.

success: function (stream) {
    if (App.options.context === 'webrtc') {

        var video = App.options.videoEl;
        var vendorURL = window.URL || window.webkitURL;
        video.src = vendorURL ? vendorURL.createObjectURL(stream) : stream;

        video.onerror = function () {
	    stream.getVideoTracks()[0].stop();
            streamError();
        };

    } else {
        // Flash context
    }
}

At present the error callback for getUserMedia() is fairly simple and should be used to inform the user that either WebRTC or Flash were not present or an error was experienced detecting a local device for use.

There are also a number of other interesting snippets in demo.js, such as getSnapshot() for capturing snapshots:

getSnapshot: function () {
    // If the current context is WebRTC/getUserMedia (something
    // passed back from the shim to avoid doing further feature
    // detection), we handle getting video/images for our canvas 
    // from our HTML5 <video> element.
    if (App.options.context === 'webrtc') {
        var video = document.getElementsByTagName('video')[0]; 
        App.canvas.width = video.videoWidth;
        App.canvas.height = video.videoHeight;
        App.canvas.getContext('2d').drawImage(video, 0, 0);

    // Otherwise, if the context is Flash, we ask the shim to
    // directly call window.webcam, where our shim is located
    // and ask it to capture for us.
    } else if (App.options.context === 'flash') {
        window.webcam.capture();
        App.changeFilter();
    } else {
        alert('No context was supplied to getSnapshot()');
    }
}

Performance

The shim has been tested on both single-frame captures and live video captures. As expected, native getUserMedia() works absolutely fine when pushing video content to canvas for real-time manipulation. The fallback works fine for single-frame, but as live frame manipulation requires capturing a frame from Flash and mapping it onto canvas every N milliseconds, an observable 'stutter' may be experienced here. I'm working on ways to optimize this further, but for now, as long as you aren't doing anything too intensive, the shim should work fine for a number of use cases.

Credits

  • getUserMedia() shim, demos: Addy Osmani
  • Workarounds for multi-bar issues, Firefox nightly support: Franz Enzenhofer
  • Flash webcam access implementation: Robert Eisele
  • Glasses positoning and filters for demo: Wes Bos
  • Little fix for IE9: Rodrigo Ferreira de Souza

Spec references

Alternatives

License

Copyright (c) 2012-2014 addyosmani
Licensed under the MIT license.

More Repositories

1

critical

Extract & Inline Critical-path CSS in HTML pages
JavaScript
9,959
star
2

backbone-fundamentals

📖 A creative-commons book on Backbone.js for beginners and advanced users alike
JavaScript
9,294
star
3

essential-js-design-patterns

Repo for my 'Learning JavaScript Design Patterns' book
HTML
4,254
star
4

es6-tools

An aggregation of tooling for using ES6 today
3,954
star
5

basket.js

A script and resource loader for caching & loading files with localStorage
JavaScript
3,362
star
6

es6-equivalents-in-es5

WIP - ES6 Equivalents In ES5
2,533
star
7

puppeteer-webperf

Automating Web Performance testing with Puppeteer 🎪
JavaScript
1,775
star
8

a11y

Accessibility audit tooling for the web (beta)
JavaScript
1,705
star
9

tmi

TMI (Too Many Images) - discover your image weight on the web
JavaScript
1,639
star
10

timing.js

Navigation Timing API measurement helpers
JavaScript
1,500
star
11

critical-path-css-tools

Tools to prioritize above-the-fold (critical-path) CSS
1,141
star
12

critical-path-css-demo

Above-the-fold CSS generation + inlining using Critical & Gulp
ApacheConf
532
star
13

backbone-boilerplates

Backbone.js stack boilerplates demonstrating integration with Express, Ruby, PHP, Grails and more.
JavaScript
488
star
14

webpack-lighthouse-plugin

A Webpack plugin for Lighthouse
JavaScript
290
star
15

sublime-fixmyjs

SublimeText package for FixMyJS
Python
250
star
16

learning-jsdp

Learning JavaScript Design Patterns: 2nd Edition - The Examples
HTML
240
star
17

predictive-fetching

Improve performance by predictively fetching pages a user is likely to need
238
star
18

storage-on-the-web

🗃 Comparing storage options for the open web in 2016
225
star
19

visibly.js

A cross-browser Page Visibility API shim
JavaScript
221
star
20

sublime-build-systems

Sublime Text build systems
202
star
21

yeoman-examples

A repo of up to date examples using Yeoman
JavaScript
202
star
22

oust

Extract URLs to stylesheets, scripts, links, images or HTML imports from HTML
JavaScript
176
star
23

cssprettifier-bookmarklet

A bookmarklet for prettifying your CSS
JavaScript
174
star
24

polymer-boilerplate

A Polymer.js template for building fast, robust web apps using Web Components
JavaScript
166
star
25

pubsubz

Another Pub/Sub implementation
JavaScript
164
star
26

backbone-mobile-search

A Backbone.js + jQuery Mobile sample app using AMD for separation of modules, Require.js for dependency management + template externalisation and Underscore for templating
JavaScript
154
star
27

prism-js

A Polymer element for syntax highlighting with Prism.js
HTML
149
star
28

starter

A simple, git-clone friendly starting point for personal projects.
JavaScript
145
star
29

memoize.js

A faster JavaScript memoizer
JavaScript
143
star
30

largescale-demo

Scalable JS architecture demo for #jqcon
JavaScript
138
star
31

psi-gulp-sample

Sample Gulp project using PSI
JavaScript
126
star
32

preact-hn

🗞 Preact Hacker News
JavaScript
121
star
33

network-emulation-conditions

Network emulation / throttling conditions (2G, 3G, 4G, Wifi etc) ☎️
JavaScript
108
star
34

bubblesort

Bubble Sort implementation with O(n^2) complexity.
JavaScript
106
star
35

polymer-filters

Polymer filters for formatting values of expressions.
JavaScript
105
star
36

angular1-dribbble-pwa

Angular 1 Dribbble Progressive Web App demo
JavaScript
102
star
37

ember-progressive-webapp

Ember.js Zuperkulblog PWA (built with FastBoot and ember-cli)
JavaScript
97
star
38

memory-mysteries

V8 memory mysteries (sample app)
CSS
84
star
39

smaller-pictures-app

Smaller Pics Progressive Web App
JavaScript
82
star
40

x-instagram

[Deprecated] A Polymer element for querying the Instagram API (Note: not yet updated to Polymer 0.5.x)
JavaScript
76
star
41

x-imager

Responsive images using Imager.js and Polymer
74
star
42

backbonejs-gallery

A Backbone, Underscore and jQuery Templates based image gallery (early early beta)
JavaScript
72
star
43

todomvc-angular-4

Angular 4.x TodoMVC implementation
TypeScript
66
star
44

socketchat

SocketChat - a beginners chat app using SocketStream
CSS
63
star
45

github-watchers-button

An Embeddable GitHub 'Watchers' Button For External Pages
JavaScript
63
star
46

gulp-uncss-task

[Deprecated] Use gulp-uncss instead please.
JavaScript
63
star
47

yt-jukebox

A YouTube Jukebox element built with Polymer & Yeoman
JavaScript
61
star
48

critical-path-angular-demo

Above-the-fold CSS generation + inlining using Critical, Gulp & Angular
JavaScript
60
star
49

native-media-resizing

Draft proposal for browser-level media resizing
59
star
50

catclock

Polymer + Material Timer/Countdown/Countdown app (alpha)
JavaScript
56
star
51

recursive-binarysearch

Recursive Binary Search with O(log N) complexity
JavaScript
56
star
52

selectionsort

Selection sort with O(n^2) time complexity
JavaScript
56
star
53

polymer-grunt-example

Polymer + Grunt
JavaScript
56
star
54

microtemplatez

Another compact micro-templating solution
JavaScript
55
star
55

page-er

A Polymer element for paginating model data
CSS
53
star
56

google-slides

⚡ An offline-enabled Polymer slide-deck
HTML
53
star
57

flickly-wireframe

The jQuery mobile wireframe for Flickly
52
star
58

grunt-uncss-sass-example

An example of using grunt-uncss on a Sass project
JavaScript
52
star
59

sparkle-trail

<sparkle-trail> Polymer element - useful as a pre-loader
CSS
51
star
60

cssdiet

(WIP) - A DevTools extension for multi-page unused CSS auditing
JavaScript
46
star
61

backbone-koans-qunit

Backbone Koans for QUnit
JavaScript
44
star
62

github-client

Angular GitHub client for Firefox OS
JavaScript
44
star
63

a11y-webapp

A11y WebApp built with Polymer (WIP)
JavaScript
44
star
64

video-js

A Polymer element for Video.js
CSS
42
star
65

generator-webapp-uncss

Yeoman generator with grunt-uncss
JavaScript
42
star
66

lottie-animation-demo

Network-aware adaptive loading with Lottie Web
JavaScript
41
star
67

spine.bitly

(Demo app) A Spine.js Bit.ly client for shortening URLs and archiving references to these links offline.
JavaScript
39
star
68

backbone-aura

Backbone Aura
38
star
69

es2015-todomvc-chrome

ES2015 TodoMVC app that works without a transpiler
JavaScript
38
star
70

critical-css-weather-app

Critical-path CSS optimized weather app
JavaScript
37
star
71

polymer-blog

A tutorial app for generator-polymer
JavaScript
33
star
72

generator-boilerplate

A simple Yeoman generator using Git submodules to clone over a boilerplate hosted elsewhere on GitHub
JavaScript
31
star
73

npm-and-polymer-demo

Demo of Polymer + Paper elements working off npm3
HTML
31
star
74

jquery-roundrr

A jQuery plugin for plotting interactive content galleries in a circle form
JavaScript
30
star
75

polymer-localforage

A Polymer element for Mozilla's localForage (async storage via IndexedDB or WebSQL)
HTML
30
star
76

devtools-timeline-model-browser

Browser-friendly helper for parsing DevTools Timeline traces into structured profiling data models
JavaScript
29
star
77

mustache-for-chromeapps

A special build of mustache that works in Chrome Apps under CSP
JavaScript
28
star
78

addyosmani

GitHub README
27
star
79

tmdb-viewer-load-more

Accessibility-friendly version of TMDB Viewer (load-more)
JavaScript
25
star
80

active-route

Active view routing for Polymer extending <template>
CSS
25
star
81

webapp-scaffold

Polymer webapp scaffold element
CSS
25
star
82

typeahead-country

A Polymer element for autocompleting country names
24
star
83

react-interop

React + Polymer + X-Tag interop
JavaScript
24
star
84

vue-cli-todomvc

TodoMVC built using the Vue.js 2.0 CLI 🍰
JavaScript
22
star
85

polymer-browserify-vulcanize

Polymer + Browserify + Vulcanize
JavaScript
22
star
86

es6-starter

A minimal starting point for using ES6 today.
JavaScript
21
star
87

faster-video

A Polymer element for <video> with playback speed controls
JavaScript
21
star
88

js-shapelib

A minimalist JavaScript library for drawing objects around a Circle or Ellipse
JavaScript
19
star
89

element-query

Element queries with Polymer (experimental fork)
CSS
19
star
90

clientside-sample-buildfile

A Client-side ANT Build File Example
19
star
91

parsely

A small utility for parsing URLs of all types.
JavaScript
18
star
92

video-player

A themeable Polymer video element
JavaScript
16
star
93

page-router

Declarative URL routing for Polymer elements.
CSS
16
star
94

polymer-eventemitter

A Polymer event emitter element with support for wildcards, many and once.
JavaScript
15
star
95

lighthouse-reports

Quick module for getting Lighthouse reports in JSON form
JavaScript
15
star
96

generator-es6

An ES6.now project generator for Yeoman.
JavaScript
14
star
97

aura

A scalable, event-driven JavaScript architecture for developing widget-based applications. Works with Backbone.js and other frameworks.
14
star
98

jquery-googleviewer-plugin

A compact Google Viewer plugin
14
star
99

medium-backups

HTML
13
star
100

css3-transition-fallbacks

CSS3 Transition Fallback demos
13
star