Browser permissions for GetUserMedia from different camera devices - javascript

In the site I am coding, I want the user to have the option of toggling between different video input devices and view the stream.
I am able to enumerate all the devices using navigator.mediaDevices.enumerateDevices() and filtering this by kind gives me the video input devices.
However, when I try to use
navigator.mediaDevices.getUserMedia({ video: { deviceId: deviceIdOfSelectedDevice }}), I notice that I only get the stream of the camera allowed by the browser irrespective of the deviceId. I want to prompt for browser permissions to allow a different camera.

The documentation says this about your code:
The above will return the camera you requested, or a different camera if that specific camera is no longer available.
The document also says that you can require a device with exact:
{ video: { deviceId: { exact: deviceIdOfSelectedDevice } } }

Related

Determine device ID of a camera with a specified facing mode

I am working on code to allow for an in-page select element to choose a camera. The default camera should be the "environment" camera while the rest should be listed after.
Using the following call I am able to stream video from an appropriate "environment"-facing camera:
navigator.mediaDevices.getUserMedia({ video: { facingMode: "environment"} }).then(function (stream) {
// display stream on web page
...
});
Similarly, I can get the list of available devices using the following:
navigator.mediaDevices.enumerateDevices().then(
devices => {
// build list of options
}
);
I store the deviceId for each option and use that to display the feed from that camera which works well.
However, the option selected by default is not necessarily the "environment" camera. And the stream object returned from getUserMedia doesn't seem to have an easy way to determine the deviceId of the device providing that stream. Nor can I seem to find any other way to determine the "environment"-facing camera.
Is this not possible or is there some kind of getDeviceIdForFacingMode function that I've just missed?
After digging through the objects a bit more I was ultimately able to find that the following works to get the deviceId from the stream:
stream.getVideoTracks()[0].getSettings().deviceId
I would assume that in other cases you may need to get careful about the [0] if for some reason your stream involved multiple video tracks but for my purposes this worked well. In general I would expect you could get whatever information you need between stream.getVideoTracks()[i] (MediaStreamTrack) and stream.getVideoTracks()[i].getSettings() (MediaTrackSettings).

getUserMedia not working for IOS, how to access microphone on IOS from website?

I have recently tried using the getUserMedia function from the navigator.mediaDevices.getUserMedia function. I am trying to access the microphone from a website that I created (www.speechbud.com) so that a speech to text transcription can be performed. This is working on PC and mobile(android) but doesn't seem to work for IOS. I have checked many previous articles and it says that from IOS 11 getUserMedia should work, however it is still not working. Is IOS still not compatible, and if that's the case, how am I supposed to access the microphone from a website?
I have checked previous articles and tried using different npm packages, with no luck.
getUserMedia({video: false, audio: true},function (err, stream) {
if (err) {
console.log('failed');
stream.end(); // end the stream
} else {
micStream.setStream(stream);
if (keepMic) {`enter code here`
preservedMicStream = micStream;
}
}
});
TLDR; I would like to basically be able to access the microphone from an IOS device upon a button click for live transcription.
THANKS!

getUserMedia() : get environment camera with wide enough field of view

I'm using rear smartphone camera using:
navigator.mediaDevices.getUserMedia({ video: { facingMode: "environment" }, audio: false })
.then((stream) => {...})
However, when using those constraints on a Huawei P30 (having 3 rear camera sensors),
the retrieved video stream has a very narrow field of view ; maybe the "zoom" sensor is used to retrieve the stream. For my app, I need a more "all purpose" field of view, not too narrow like that.
I found that I can get the stream from another sensor by using the constraint deviceId (value found using navigator.mediaDevices.enumerateDevices()), but I have to support as many smartphones as possible, so relying only on deviceId does not seems a viable option (deviceId even changes for each origin & browsing session).
Does any getUserMedia() constraint exists, allowing to get a camera stream with specific field of view angle (or any related characteristic such as focal length, zoom level...)?

What is a TrackStartError?

I am running audio only sessions using the constraints:
var constraints = {
audio: {
mandatory: {
echoCancellation: false
}, optional: [{
sourceId: audioSource
}]
},
video: false
};
I am noticing that in a very small number of sessions I am receiving a TrackStartError from the getUserMedia request. I cannot see any correlation between browser/browser version/OS/devices available. Some computers continually get this error, some once and then after a new getUserMedia request no problem and some don't experience this at all.
Is the TrackStartError documented fully as I have seen some issues around mandatory audio flags, but echoCancellation seems not to have this problem?
TrackStartError is a non-spec Chrome-specific version of NotReadableError:
Although the user granted permission to use the matching devices, a hardware error occurred at the operating system, browser, or Web page level which prevented access to the device.
Seems fitting, given that your constraints are non-spec and Chrome-specific as well. Instead, try:
var constraints = {
audio: {
echoCancellation: { exact: false },
deviceId: audioSource
},
};
I highly recommend the official adapter.js polyfill to deal with such browser differences.
Some systems (like Windows) give exclusive access to hardware devices, which can cause this error if other applications are currently using a mic or camera. It can also be a bug or driver issue.

getUserMedia with MediaStreamAudioSourceNode on Android Chrome

I am trying to use media streams with getUserMedia on Chrome on Android. To test, I worked up the script below which simply connects the input stream to the output. This code works as-expected on Chrome under Windows, but on Android I do not hear anything. The user is prompted to allow for microphone access, but no audio comes out of the speaker, handset speaker, or headphone jack.
navigator.webkitGetUserMedia({
video: false,
audio: true
}, function (stream) {
var audioContext = new webkitAudioContext();
var input = audioContext.createMediaStreamSource(stream);
input.connect(audioContext.destination);
});
In addition, the feedback beeps when rolling the volume up and down do not sound, as if Chrome is playing back audio to the system.
Is it true that this functionality isn't supported on Chrome for Android yet? The following questions are along similar lines, but neither really have a definitive answer or explanation.
HTML5 audio recording not woorking in Google Nexus
detecting support for getUserMedia on Android browser fails
As I am new to using getUserMedia, I wanted to make sure there wasn't something I was doing in my code that could break compatibility.
I should also note that this problem doesn't seem to apply to getUserMedia itself. It is possible to use getUserMedia in an <audio> tag, as demonstrated by this code (utilizes jQuery):
navigator.webkitGetUserMedia({
video: false,
audio: true
}, function (stream) {
$('body').append(
$('<audio>').attr('autoplay', 'true').attr('src', webkitURL.createObjectURL(stream))
);
});
Chrome on Android now properly supports getUserMedia. I suspect that this originally had something to do with the difference in sample rate between recording and playback (which exhibits the same issue on desktop Chrome). In any case, all started working some time on the latest stable around February 2014.

Categories