Estoy desarrollando una PWA basada en Vuejs. He implementado un componente para tomar fotografías usando la cámara incorporada del dispositivo. esta usando
navigator.mediaDevices.getUserMedia con un elemento de video para mostrar la transmisión desde la cámara.canva y sus getContext("2d").drawImage para obtener la imagen de la secuencia y mostrársela al usuarionavigator.mediaDevices.enumerateDevices para obtener una lista de las cámaras disponibles y el parámetro de restricción de getUserMedia para cambiar entre ellas.Todo esto funciona muy bien :)
Pero ahora me he topado con un nuevo problema: algunos teléfonos inteligentes recientes tienen múltiples cámaras traseras que el software de la cámara integrada combinaría para tomar una sola toma (una cámara sería buena con baja exposición, otra con alta exposición y otra más en algunas otras condiciones, etc.). En este caso, mi aplicación mostrará todas las cámaras y permitirá que el usuario las use de forma independiente. El comportamiento previsto sería combinarlos como el software integrado. ¿Cómo es eso posible?
Después de probar varios dispositivos que tienen 1 (frontal), 2 (trasero y frontal) y múltiples sensores de cámara (1 frontal, varios traseros), mi solución consiste en usar la propiedad de etiqueta del objeto MediaDeviceInfo devuelto por mediaDevices.enumerateDevices() :
Luego, mi código para obtener la identificación de la cámara frontal y de la cámara trasera combinada es el siguiente (se supone que siempre hay una y solo una cámara frontal):
return navigator.mediaDevices.enumerateDevices() .then(mediaDevices => { let cameras = mediaDevices.filter(mediaDevice => mediaDevice.kind === 'videoinput'); console.log("#potential camera=" + cameras.length); if(cameras.length<=2) return cameras.map(x => x.deviceId); else { let front = cameras.find(x => x.label.match(/\bfront\b/)); let back = cameras.filter(x => x.label.match(/\bback\b/) && x.label.match(/\b0\b/)) if(!front || back.length!=1) { console.log("no clear front and back, taking first and last one - cameras=", cameras); return [cameras[0].deviceId, cameras[cameras.length-1].deviceId]; } else { console.log("clear front and back"); return [front.deviceId, back[0].deviceId]; } } }