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...)?
Related
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 } } }
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).
I want to send audio signal coming from my audio interface (focusrite saffire) to my nodejs server. How should I go about doing this? The easiest way would be to access the audio interface from the browser (html5) like capturing microphone output with getUserMedia (https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia), but couldn't find a way to access my audio interface through that library. Otherwise, I'm planning on creating a desktop application, but don't know if there is a function/library to allow access to my usb-connected audio interface.
This probably has little to do with the Javascript or the MediaDevices API. On Linux, using Firefox, PulseAudio is required to interface with your audio hardware. Since your soundcard is an Input/Output interface, you should be able to test it pretty easily by simply playing any sound file in the browser.
Most of PulseAudio configuration can be achieved using pavucontrol GUI. You should check the "configuration" tab and both "input device" & "output device" tabs to make sure your Focusrite is correctly set up and used as sound I/O.
Once this is done, you should be able to access an audio stream using the following (only available if on a "secure context", ie localhost or served through HTTPS, as stated in the MDN page you mentionned):
navigator.mediaDevices.getUserMedia({ audio: true })
.then(function(stream) {
// do whatever you want with this audio stream
})
(code snippet taken from the MDN page about MediaDevices)
Sending audio to the server is a whole other story. Have you tried anything? Are you looking for a real-time communication with the server? If so, I'd start by having a look at the WebSockets API. The WebRTC docs might be worth reading too, but it is more oriented to client-to-client communications.
How to use exact device id
Use media device constrain to pass exact device id.
An sample would be
const preferedDeviceName = '<your_device_name>'
const deviceList = await navigator.mediaDevices.enumerateDevices()
const audio = devices.find((device) => device.kind === 'audioinput' && device.label === preferedDeviceName)
const {deviceId} = audio;
navigator.mediaDevices.getUserMedia({audio: { deviceId }}
How to process and send to the backend
Possible duplicate of this
Still not clear follow this
Chrome or CEF3 should not use the default speaker of the system to play the sound (audio out).
Is there any way that user or developer can set default speaker in chrome or CEF3 other than system default?
e.g during WebRTC call, (in current scenario) audio sound is used to play by default audio sound device (speaker).
But in my scenario it should be played by selected speaker not system default.
This feature is not available in Chrome/Chromium/CEF.
Also, in Windows there is no public API to set which sound card use for output (it is left to the user to choose that):
This is a deliberate design, since we do not want applications to override audio setting set by the user
...However, here are some workarounds:
https://stackoverflow.com/a/2216886/833188
https://stackoverflow.com/a/20270535/833188
You should be able to do this purely in the JavaScript side of your application without having to mess with the CEF side. First, find what device ID you want to output to:
const devices = await navigator.mediaDevices.enumerateDevices();
const audioDevices = devices.filter(device => device.kind === 'audiooutput');
audioDevices will now contain all outputs. Then, set your Audio object's sink:
const audio = document.querySelector('audio');
audio.setSinkId(audioDevices[0].deviceId);
For more information: https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/setSinkId
In a Nutshell: I'm trying to change the VideoTrack of a MediaStream object.
(Documentation: https://developer.mozilla.org/en-US/docs/WebRTC/MediaStream_API)
I have a MediaStream object __o_jsep_stream_audiovideo which is created by the sipml library.
__o_jsep_stream_audiovideo looks like this:
So it has one AudioTrack and one VideoTrack. At first the VideoTrack comes from the users camera (e.g label: "FaceTime Camera").
According to the Documentation:
A MediaStream consists of zero or more MediaStreamTrack objects, representing various audio or video tracks.
So we should be fine adding more Tracks to this Stream.
I'm trying to switch/exchange the VideoTrack with that from another stream. The other stream (streamB) originates from Chromes ScreenCapture api (label: "Screen")
I tried:
__o_jsep_stream_audiovideo.addTrack(streamB.getVideoTracks()[0])
which doesn't seem to have any effect.
I also tried assigning the videoTracks directly (which was desperate I know).
I must be missing something obvious could you point me in the right direction?
I'm running
Chrome (Version 34.0.1847.131) and
Canary (Version 36.0.1976.2 canary)
OSX 10.9.2
When you talk about change video track, we mean 2 areas:
change the remote video track (what the others can see from u)
WebRTC gets new version of doing that, since it deprecates addStream/removeStream.
However, the excelence is that they introduce new interface replaceTrack
stream.getTracks().forEach(function(track) {
// remote
qcClient.calls.values().forEach(function(call) {
var sender = call.pc.getSenders().find(function(s) {
return s.track.kind == track.kind;
});
sender.replaceTrack(track);
});
});
change your display video (You see yourself)
Better to just add a new video element (or using existing video element) But assign srcObject to the new captured stream
Adding and removing tracks on a MediaStream object do not signal a renegotiation and there are also issues with a MediaStream having two tracks of the same type in chrome.
You should probably just add the separate mediastream to the peer connection so that it can fire a re-negotiation and handle the streams. The Track add/remove functionality in chrome is very naive and not very granular and you should move away from it as much as you can.