It keeps using the front facing camera instead of the back camera This is my code: I added the facingMode: {exact:"environment"}, but it doesn't work
const constraints = {
video: true,
facingMode: { exact: 'environment' }
};
if ('mediaDevices' in navigator && 'getUserMedia' in navigator.mediaDevices) {
console.log("Let's get this party started")
}
navigator.mediaDevices.getUserMedia(constraints).
then((stream) => {video.srcObject = stream});
function displayImage()
{
const selectedFile = document.getElementById('fileinput')
//var image =document.getElementById('output')
//image.src = URL.createObjectURL(selectedFile.files[0]);
//selectedFile.files[0]
const img = new Image()
img.src = URL.createObjectURL(selectedFile.files[0])
canvas.width = video.videoWidth
canvas.height = video.videoHeight
video.style.display="none"
canvas.style.display ="inline"
console.log(img)
console.log("image uploaded")
img.onload = function() {
canvas.getContext('2d').drawImage(img, 0, 0,video.videoWidth,video.videoHeight);
console.log('the image is drawn');
}
}
It keeps using the front facing camera instead of the back camera This is my code: I added the facingMode: {exact:"environment"}, but it doesn't work
const constraints = {
video: true,
facingMode: { exact: 'environment' }
};
if ('mediaDevices' in navigator && 'getUserMedia' in navigator.mediaDevices) {
console.log("Let's get this party started")
}
navigator.mediaDevices.getUserMedia(constraints).
then((stream) => {video.srcObject = stream});
function displayImage()
{
const selectedFile = document.getElementById('fileinput')
//var image =document.getElementById('output')
//image.src = URL.createObjectURL(selectedFile.files[0]);
//selectedFile.files[0]
const img = new Image()
img.src = URL.createObjectURL(selectedFile.files[0])
canvas.width = video.videoWidth
canvas.height = video.videoHeight
video.style.display="none"
canvas.style.display ="inline"
console.log(img)
console.log("image uploaded")
img.onload = function() {
canvas.getContext('2d').drawImage(img, 0, 0,video.videoWidth,video.videoHeight);
console.log('the image is drawn');
}
}
Share
Improve this question
edited Oct 27, 2020 at 12:14
Sayd Fuad
3242 silver badges14 bronze badges
asked Oct 27, 2020 at 11:07
Wannes Van der PerrenWannes Van der Perren
611 gold badge1 silver badge7 bronze badges
5 Answers
Reset to default 5Your constraints are not set correctly.
facingMode
is a member of the video
constraint, so it should be
const constraints = {
video: {
facingMode: {
exact: "environment"
}
}
};
Live Fiddle to be ran from a device with a back camera.
The facingMode
constraint is inpletely implemented, especially in mobile devices.
I have found that the label
member of the device
object contains the string back
for an environment-facing camera and front
for a user-facing camera in a wide range of mobile devices, android and iOS. (Sometimes those strings are partially in upper case.) So you could do something like this. It's a bit of a hairball pared to facingMode
, but it works.
/* get user's permission to muck around with video devices */
const tempStream = await navigator.mediaDevices.getUserMedia({video:true})
const devices = navigator.mediaDevices.enumerateDevices()
let frontDeviceId
let backDeviceId
if (devices.length > 0) {
/* defaults so all this will work on a desktop */
frontDeviceId = devices[0].deviceId;
backDeviceId = devices[0].deviceId;
}
/* look for front and back devices */
devices.forEach (device => {
if( device.kind === 'videoinput' ) {
if( device.label && device.label.length > 0 ) {
if( device.label.toLowerCase().indexOf( 'back' ) >= 0 )
backDeviceId = device.deviceId
else if( device.label.toLowerCase().indexOf( 'front' ) >= 0 )
frontDeviceId = device.deviceId
}
}
}
/* close the temp stream */
const tracks = tempStream.getTracks()
if( tracks )
for( let t = 0; t < tracks.length; t++ ) tracks[t].stop()
/* open the device you want */
const constraints = {
video: true,
deviceId: {exact: backDeviceId }
}
const stream = navigator.mediaDevices.getUserMedia(constraints)
The best way for me is to use "ideal" so it will work both on a pc both on a phone:
const constraints = {
video: {
facingMode: {
ideal: "environment"
}
}
};
btn.onclick = e => {
navigator.mediaDevices.getUserMedia(constraints)
.then((stream) => {video.srcObject = stream})
.catch( console.error );
};
https://jsfiddle/Zibri/pk7en85u/
I don't know why this works for me, but supporting both desktop and phone conditions works if I also define width
and height
properties on the constraints:
const constraints = {
video: {
width: { ideal: 4096 },
height: { ideal: 2160 },
facingMode: "environment",
},
}
Why this works? I have no idea, but on Chrome on iOS it does as well as Chrome on desktop.
What worked for me on Safari Iphone 6s (I think) was to pass the constraints directly to getUserMedia:
const mediaStream = await navigator.mediaDevices.getUserMedia(
{
video: { facingMode: { ideal: "environment" } },
audio: false
}
);