Coder Social home page Coder Social logo

addyosmani / getusermedia.js Goto Github PK

View Code? Open in Web Editor NEW
903.0 57.0 159.0 582 KB

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

License: MIT License

ActionScript 28.21% CSS 1.37% JavaScript 67.42% Makefile 0.27% HTML 2.73%

getusermedia.js's Introduction

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.

getusermedia.js's People

Contributors

addyosmani avatar dandv avatar franzenzenhofer avatar giles-v avatar pablocubico avatar rodfersou avatar sillevl avatar someyoungideas avatar wong2 avatar yueranyuan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

getusermedia.js's Issues

Supporting audio in the fallback

As far as I understand, the flash fallback doesn't support audio. It would be great if we could also use it for audio, because Safari

multiple allowbars

hi

the repetitive call to navigator.getUserMedia_ just to find out which options syntax it supports is a UX no go, as it leads to multiple "allowbars" in google chrome.

why is this needed? if you could elaborate i will try to find a solution.

thx and cheers
franz

Safari not working. Tested on demo too.

Hello,

At first I thought it was an issue with my code, but after testing the library demo on multiple different devices using Safari I can confirm it doesn't work. If you could send me a fix that'd be great.

Thanks :)
Leon

some solid documentation and examples

hello, i don't mean to hate but there is no documentation about the options and the example file demo.js is a complete mess. i think this is what this project really needs

demo.js assumes that unprefixed MediaStream is Firefox-only

if ((typeof MediaStream !== "undefined" && MediaStream !== null) && stream instanceof MediaStream) {

This code uses (typeof MediaStream !== "undefined" && MediaStream !== null) && stream instanceof MediaStream as the guard for a Firefox-only code path, where either video.mozSrcObject must be supported or one must support assigning a MediaStream instance to video.src. Neither on a path to standardization, only srcObject is.

This has broken the demo in Chrome 55, where I exposed the unprefixed MediaStream interface:
https://bugs.chromium.org/p/chromium/issues/detail?id=674608
https://bugs.chromium.org/p/chromium/issues/detail?id=649331

@alvestrand @henbos @guidou FYI

TYPE_MISMATCH_ERROR for options['video'] = true and options['audio'] = false

I get:

Uncaught Error: TYPE_MISMATCH_ERR: DOM Exception 17 getUserMedia.js:112

in Chrome 21 (and 20, though i can't test that anymore, sorry) - Version 21.0.1180.57

and then:

Uncaught TypeError: Not an object.

for my statement "getUserMedia(this.options, this.success, this.deviceError)"

However, after banging my head against the keyboard for a few days, and tracing the options format detection, i found that the version which works in your demo asks for both video and audio -- so when i did video=true and audio=true (the latter was false before), it works!

I would keep chasing the bug past this point but i'm kind of desperate to return to coding my app (http://spectralworkbench.org/capture). But if you have specific questions, i'd love to help; this library is rad.

Record webcam in a video file

Hello,

I am looking for some way to record the video and audio stream captured by getUserMedia.js and write it in a video file (.mp4 for example).

I don't find an easy way to do it, google results are somewhat tricky... Have somebody ever experienced with it? Have a beginning of solution?

My first idea was to get a frame every X milliseconds, and put it somewhere. But... where? How to build the final result? How to put audio and video together in a single output file? So many questions :(

Thank you for the help

Firefox updates

Hey @codepo8. At Fronteers you mentioned that there were some changes made to FF nightlies that we should get updated in this project. Do you remember what those were? :)

Error in Chrome Canary (20.0.1132.1)

I'm getting the following error in Chrome Canary in the call to getUserMedia():

Uncaught Error: TYPE_MISMATCH_ERR: DOM Exception 17

I think this is because getUserMedia() in Chrome Canary now takes an object.

(I think the problem is as described below, but apologies if my diagnosis is wrong...)

In the code that sets getUserMediaOptions, you check the value of optionStyle.string. This defaults to true, so if getUserMedia() takes an object, this will be true. As far as I can see, this means that the else block will never be called. In other words, options will be set to a string.

I think the first if should be if (optionStyle.string && !optionStyle.object).

if (optionStyle.string) {
if (options.video && options.audio) {
getUserMediaOptions = 'video, audio';
} else if (options.video) {
getUserMediaOptions = 'video';
} else if (options.audio) {
getUserMediaOptions = 'audio';
}
} else if (optionStyle.object) {
if (options.video) {
getUserMediaOptions.video = true;
}
if (options.audio) {
getUserMediaOptions.audio = true;
}
}

Improve usability

I was hacking away at this this evening and discovered that at least for the demo, there are far too many configuration points needed for dimensions. If the shim can simplify this at all it should.

Flash data interpretation.

Hi, what kind of data do I get on "webcam.onSave" from flash fallback?

I just guess, there are rows with pixels of image. But how can I transform those numbers to RGB?

Thanks, Lukas

Flash callback for allow button?

When the Flash fallback is activated, how can I know when the user has pressed the "Allow" button under the Adobe Flash Player Settings dialogue that pops in every time?

Because I cannot save a webcam image unless the user has allowed so. Hence I wonder if there is a fallback to listen to that allow button?

IE 12/Edge in Windows 10 Beta

Obviously, this may not be relevant for long since it's a beta build, but currently getUserMedia.js doesn't work on Windows 10/IE in Edge document mode. If I change to IE 11 document mode then it works fine.

image

The problem seems to be that the Flash file doesn't load properly (after the fourth try calling register(), it gives up "Flash movie not yet registered"). Is the control possibly checking for a user agent as part of launching?

Also, there's a bug in demo.js:

deviceError: function (error) {
  alert('No camera available.');
  console.error('An error occurred: [CODE ' + error.code + ']');
},

The error object has no property when thrown from getUserMedia.js register() method. It should either be fixed by setting a code property for the error object, or not looking for that property in the demo class.

Mobile getUserMedia

I think it would be cool to add mobile support for phoneGap. It would be awesome to use one function that worked on every device! Do you think that is even feasible? If so, I will start looking into it.

test

testing this http restriction

Demo is not working on Chrome, Firefox, Safari!

The demo link mentioned in the README.md is not woring on Chrome, Firefox, Safari. Please see the attached screen shots! It's working properly on IE!

On Chrome specifically for MAC OS, it's showing the error apply of undefined!

screen shot 2018-03-23 at 1 03 09 pm

On other browsers(including Chrome in Linux OS), video's src attribute doesn't get the proper value!

screen shot 2018-03-23 at 1 05 33 pm

Object doesn't support property or method 'setTimeout' on IE

Hello,

I'm trying to use the fallback on IE (version 11), but I have a strange error :

Object doesn't support property or method setTimeout

It happens on line 129 of the unminified version, which is the following :

window.setTimeout(register, 1000 * (4 - run), run - 1);

Here is how I instanciate getUserMedia :

getUserMedia(_this.options.webcam, _this.initWebcamSuccess, _this.initWebcamError);
window.webcam = _this.options.webcam;

Here is my _this.options.webcam object :

{
    'audio': false,
    'video': true,
    el: 'webcam-preview',
    extern: null,
    append: true,
    noFallback: false,
    swffile: '/jscam_canvas_only.swf',
    width: 640,
    height: 480,
    mode: 'callback',
    quality: 85,
    context: 'webrtc',
    debug: function() {},
    onCapture: function() {},
    onTick: function() {},
    onSave: function(data) {},
    onLoad: function() {}
}

Can somebody guess what is happening ? Your help is precious !

Flash Fallback in IE11 - no higher resolution

i´ve tried to use the demo in IE11 with 640x480 instead of 320x240, but it seems that the video is still 320x240, scaled to 640x480. You can see it when you hit the "take a picture" button. is there any possibility to make it work with 640x480? or did anyone fix the code already so it at least prints out in 640x480 with the scaled low res picture?

Recent Chrome Version 47.0.2526.73 Breaks

Recently upgrade to Chrome Version 47.0.2526.73 and this library is no longer asking for permissions to use device, and instead does not recognize camera device. I looked up the change log compared to my previous version if that will help at all.

https://chromium.googlesource.com/chromium/src/+log/46.0.2490.0..47.0.2526.0?pretty=fuller&n=10000

Did some more research in the change log and it looks like they depricated MediaStream stop() method and changed it to use stream.getVideoTracks()[0].stop(). I think this will just need to be a change in the docs for success callback and nothing fixed in the library itself from what I can tell.

Thoughts on providing visual prompts

I wonder if you have any thoughts on providing visual prompts to the browser "Allow/Deny" buttons?

A lot of the time you might execute a video call in the middle of the page but there is no real visual cue to tell the user that a new drop down has clicked that they need to click on.

Could this be part of this library/shim or does it need to be a separate project?

An example of how this could work is an overlay over the page with a prompt to tell the user to click Allow (or whatever that browsers behavior is)

add PeerConnection flash fallback

It would be great if this shim also instantiated the PeerConnection API though the flash fallback. This could lead to building more robust applications that would work seamlessly when all browsers finally support WebRTC.

Getting audio and video (question)

hello i wanted to test your code, but i have a little question first, can i get audio aswell?

i ask since on your demo project i see the audio: false option with comment
//OTHERWISE FF nightlxy throws an NOT IMPLEMENTED error

what i want to acomplish is to get a solid "webrtc" connection trhough IE. Thanks!

choose front/back camera in IE11

I am using the library in a surface pro 3 with the IE11 and i would like to know how to change from the front camera to the rear camera.
I have tried the function setCamera with the parameter from the getCameraList or with and index but nothing have change.

Is it possible to use the rear camera with the library?

Thank you in advance

Fallback Image Capture With Larger Window

if changing the width to 640 and height to 480 and trying to take a picture with the flash fallback the image is not drawn to the canvas.

i am not sure if this is because of the size or the resolution of my webcam not matching.

Not working in IE 11

getting this error while running in IE 11 Unable to get property 'code' of undefined or null reference.

Configuring with joomla

Hi im using this getusermedia to configure in joomla.

This working fine after configuring in Chrome and firefox but not in IE.
I found issue was that in demo.js the path given is
swffile: "../dist/fallback/jscam_canvas_only.swf" which will be different when I navigate thro Joomla.

So i gave full path with http and now i can see the video in IE also.

But now im unable to take pic. So is there any other place where path is given similarly like this so that there also i can give fully classified path. (Only for take pic now its not working oly in IE).

If I try this demo without Joomla even in IE its works f9.
Kindly help me on this.

Thanks, and Regards
Kishan

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.