Hi i have been working on a webpage where webcam is in use. it works fine with the primary laptop camera but my client is using a secondary/external webcam. what should i do to the webpage to use the specific camera instead of using the main laptop camera? or can he set up from windows the secondary camera as the default camera from windows like printers? (i dont have a second webcam test or check this)
Try this function
function getConnectedDevices(type, callback) {
navigator.mediaDevices.enumerateDevices()
.then(devices => {
const filtered = devices.filter(device => device.kind === type);
callback(filtered);
});
}
getConnectedDevices('videoinput', cameras => console.log('Cameras found', cameras));
There are good examples on the webrtc.org webpage
webrtc.org, Getting started with media devices, Querying media devices
Related
The bounty expires in 2 days. Answers to this question are eligible for a +100 reputation bounty.
Basj is looking for a canonical answer.
I'm building a low-latency sampler in the browser (using Javascript, WASM, etc.).
How to choose, from Javascript, a specific audio output device for Chrome or Firefox?
I see there is Audio Output API but there are not many examples (and by the way navigator.mediaDevices.selectAudioOutput is undefined on my Chrome 109).
For example, how to make Chrome use Asio4All as main output device?
(Note: using an ASIO device such as the free Asio4All driver can make the latency drop from 30 milliseconds to 5 milliseconds, even on an old computer).
There is also Audio Output Devices API which can be used to achieved the similar functionality.
// First Create a new audio element
var audio = new Audio("https://samplelib.com/lib/preview/mp3/sample-3s.mp3");
// Get the list of available audio output devices
navigator.mediaDevices.enumerateDevices()
.then(function(devices) {
// Filter the devices to get only the audio output ones
var audioOutputDevices = devices.filter(function(device) {
return device.kind === "audiooutput";
});
// Log the devices to the console
console.log(audioOutputDevices);
// If there is at least one audio output device, use the first one as the output device
if (audioOutputDevices.length > 0) {
// Set the sink ID of the audio element to the device ID of the first audio output device
audio.setSinkId(audioOutputDevices[0].deviceId)
.then(function() {
// Play the audio
audio.play();
})
.catch(function(error) {
// Handle any errors
console.error(error);
});
}
})
The audioOutputDevices[] can be leveraged to choose between vaious output devices.
iPhone continuity camera not displaying in MediaDevices enumerateDevices()
I'm using the simple code to enumerate media devices on Safari
navigator.mediaDevices.getUserMedia({ audio: true, video: true })
.then(stream => {
if (!navigator.mediaDevices?.enumerateDevices) {
console.log("enumerateDevices() not supported.");
} else {
// List cameras and microphones.
navigator.mediaDevices.enumerateDevices()
.then((devices) => {
devices.forEach((device) => {
console.log(`${device.kind}: ${device.label} id = ${device.deviceId}`);
});
})
.catch((err) => {
console.error(`${err.name}: ${err.message}`);
});
}
})
.catch(err => console.error("queryMediaDevices:Error", err));
But I'm just getting the iPhone mic and not the camera. But when I enter another web app, or go to google meets, I can select the phone's camera and use it.
Currently on macOS 13.0, and iOS 16.2.
Is there anything I'm missing?
There's a "magic pose" your camera needs to be in for browsers to detect your continuity camera:
Due to privacy concern with unintended camera selection, browser based video apps only see the phone when it is in "magic pose" of landscape, screen off, locked, motionless (not handheld), and unobstructed camera. This pose is also used to trigger Automatic Camera Selection in supporting applications such as FaceTime and Photo Booth.
The issue was caused solved by updating macOS to 13.1 and safari to 16.2.
Now it's working just fine.
How to use iOS and macOS's latest feature of Continuity Camera feature with JavaScript, or how to avoid it from popping up in the process of requesting media devices, i.e. navigator.mediaDevices.getUserMedia({ video: true })? - as it actually breaks this code on Chrome whenever my iPhone is close to the laptop with the error Uncaught (in promise) DOMException: Could not start video source, even after I tried to set chrome://settings/content/camera to the original FaceTime HD Camera - seems Chrome just keeps trying to request iPhone as the webcam.
Update - To avoid Continuity Camera, I use this quick patch to prefer the FaceTime Camera if possible (while it would still be better and cool to be able to use iPhone whenever needed)
let preferredDeviceId = undefined
const availableDevices = await navigator.mediaDevices.enumerateDevices()
if (availableDevices.length > 1)
for (let d of availableDevices)
if (d.label.includes('FaceTime'))
preferredDeviceId = d.deviceId
await navigator.mediaDevices.getUserMedia({
video: {
deviceId: preferredDeviceId,
}
})
About a month ago, a Stackoverflow partner helped me with a big question, like changing the camera and the microphone during a conference. That question was answered in the following link:
Using WebRTC how to choose mic and camera?
After changing the camera and microphone, the previous media flow remains active. So the other people in the conference can not receive the new flow I have in some way.
I would like to know how to renegotiate this new flow, if necessary.
The library that I use for webRTC implementation in the project is "simplewebRTC" currently in disuse.
The code I use to change devices is based entirely on what was achieved in my previous question ...
I don't know about simpleWebRTC, but in plain WebRTC renegotiation is not necessary.
Just use sender.replaceTrack(). It's async, so to switch both camera and mic at the same time:
navigator.mediaDevices.getUserMedia(constraints)
.then(stream => {
video.srcObject = stream;
return Promise.all(stream.getTracks().map(track => {
const sender = pc.getSenders().find((s => s.track.kind == track.kind);
return sender.replaceTrack(track);
}));
})
.catch(err => console.log(err));
This should instantly cause the sender to switch to sending media from your new camera and microphone. The other side won't know the difference.
I am making a simple app with two webcams that needs to work only on latest Firefox. Locally it works fine:
the user is prompted for the access to the camera
the user selects one camera
the user is prompted again
the user selects the second camera
both streams work fine
However, when I upload it to the server which serves the page through HTTPS, the access from the first camera is remembered and I just get two of the same streams.
Is there a way to force re-prompting on HTTPS so that the user can select the other camera, as well?
This is my code:
function handleSuccess1(stream) {
video1.srcObject = stream;
navigator.mediaDevices.getUserMedia(constraints).
then(handleSuccess2).catch(handleError);
}
function handleSuccess2(stream) {
// this gets called automatically with the first stream
// without re-prompting the user
video2.srcObject = stream;
}
const constraints = {
video: true
};
function handleError(error) {
console.error(error);
}
navigator.mediaDevices.getUserMedia(constraints).
then(handleSuccess1).catch(handleError);
Use navigator.mediaDevices.enumerateDevices() to list the available cameras and/or microphones.
You can read about it in more detail here: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices