Marcos Pérez Gude
Marcos Pérez Gude

Reputation: 22158

WebRTC getUserMedia() works only on Firefox

I'm working on a mobile web project that needs to access the camera and take a photo and then manipulate it. The problem is that we need to take the photo directly from the browser, and not open the native camera app to take it.

Ok, I use WebRTC for this task. I access to getUserMedia() and play a "video" that is the real time camera view. This task is for Android and iOS.

This works perfectly on Firefox. I assume that in Safari this will be impossible to achieve since getUserMedia() is still not supported by this browser, but Google Chrome have support but I'm unable to make it work on Chrome.

The problem on Chrome seems to be a bug that user is unable to select rear or front camera, so the image never displays, it always is a black image.

My code is very simple, I take it from https://davidwalsh.name/browser-camera but theorically it works on all browsers, but I can't make it work on Chrome. This is the code:

<video id="video" width="480" height="640" autoplay controls></video>
<button id="snap">Capture</button>
<canvas id="canvas" width="480" height="740"></canvas>

<script>
// Grab elements, create settings, etc.
var video = document.getElementById('video');
var i = 0;
// Get access to the camera!
if(navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
    // Not adding `{ audio: true }` since we only want video now
    navigator.mediaDevices.getUserMedia({ video: true }).then(function(stream) {
        video.src = window.URL.createObjectURL(stream);
        video.play();
    });
}
else if(navigator.getUserMedia) { // Standard
    navigator.getUserMedia({ video: true }, function(stream) {
        video.src = stream;
        video.play();
    }, errBack);
} else if(navigator.webkitGetUserMedia) { // WebKit-prefixed
    navigator.webkitGetUserMedia({ video: true }, function(stream){
    alert(window.webkitURL);
    alert(window.webkitURL.createObjectURL(stream));
        video.src = window.webkitURL.createObjectURL(stream);
        video.play();
    }, errBack);
} else if(navigator.mozGetUserMedia) { // Mozilla-prefixed
    navigator.mozGetUserMedia({ video: true }, function(stream){
        video.src = window.URL.createObjectURL(stream);
        video.play();
    }, errBack);
}

// Elements for taking the snapshot
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var video = document.getElementById('video');

// Trigger photo take
document.getElementById("snap").addEventListener("click", function() {
    context.drawImage(video, 0, 0, 640, 480);
});
</script>

How can I make it work on Chrome? How can I make that Chrome ask to user what camera he needs to use (rear / front)? I've found over internet a user that tells Chrome has a bug selecting the camera, so I think this is the problem.

Note that on Chrome Desktop it works perfectly, since there is only one camera and has not to delegate on the user to choose what camera should use. But on mobile devices with two cameras is impossible to choose how.

Thank you.

I'm not using polyfills. The duplicate mark is not solving my issue. I need some help with this. I need a canonical answer with a solution to the problem. Thank you for your time! I offer a bounty.

Upvotes: 3

Views: 1458

Answers (2)

Walle Cyril
Walle Cyril

Reputation: 3247

To chose the camera add a constraint paramater with facingMode set to "user" or "environment". To let the user chose don't add these details.

var myConstraints = {
    audio: false, 
    video: {
        facingMode: "user"
    }
};

see https://w3c.github.io/mediacapture-main/#dom-mediadevices-getusermedia

The new API will become Promised based:

navigator.getUserMedia(myConstraints).then(function(stream) {
    video.srcObject = stream;
    video.play();
}).catch(errBack);

To use a future proof API and make it work now you can use a polyfill like https://github.com/webrtc/adapter

Upvotes: 3

Philipp Hancke
Philipp Hancke

Reputation: 17265

Are you deploying on https? Chrome does not allow getUserMedia on http pages for security reasons.

See also this sample for enumerating and selecting cameras. The facingmode constraint you're asking about is unfortunately broken right now.

Upvotes: 7

Related Questions