Please don’t take this personally, but I respectfully disagree with your assessment that preload() should not be used for this problem. My assessment is that it is more a function of which browser plays nice with navigator.mediaDevices.enumerateDevices() and which ones do not. As long as the poster is happy that’s really all that counts for this thread. But for the sake of finding the truth, I think there is more to it than has been stated here. Please consider that the following code also runs without error in a Chrome browser running p5.js web editor. Both cameras on my system (Mac) are turned on simultaneously. Note that the demo uses preload() and does not try to hide setup() and draw().
var deviceList = [];
function preload(){
navigator.mediaDevices.enumerateDevices().then(getDevices);
}
function setup() {
var constraints = {
video: {
deviceId: {
exact: deviceList[0].id
},
}
};
var constraints1 = {
video: {
deviceId: {
exact: deviceList[1].id
},
}
};
canvas = createCanvas(width, height);
background(255);
video = createCapture(constraints);
video2 = createCapture(constraints1);
console.log(deviceList);
}
function draw () {
}
function getDevices(devices) {
for (let i = 0; i < devices.length; ++i) {
let deviceInfo = devices[i];
//Only get videodevices and push them into deviceList
if (deviceInfo.kind == 'videoinput') {
deviceList.push( {
label: deviceInfo.label,
id: deviceInfo.deviceId
}
);
}
}
}
Things aren’t what they seem.
I have repeatedly tested the above code by opening and closing the browser and p5.js web editor multiple times in succession. I concede that sometimes preload() fails. Sometimes it works ok, sometimes it fails to load the array even though it gets to the end of the getDevices() function before going to setup(). I have not tested the other technique as rigorously which I intend to do.