Cómo cambiar de la cámara frontal a la cámara trasera con JavaScript (HTML5) en el navegador

Cómo cambiar de la cámara frontal a la cámara trasera con JavaScript (HTML5) en el navegador

Cuando trabajes con WebRTC, deberás hacer muchas cosas que ofrezcan la funcionalidad más básica para que los usuarios interactúen con tu aplicación. Una de esas características es la posibilidad de seleccionar una fuente de transmisión de audio o video diferente manualmente. Por ejemplo, al ver la demostración en este sitio web , en el Samsung Galaxy S10 +, verás las siguientes opciones disponibles (el Galaxy S10 tiene tres cámaras en la parte posterior: una principal de 12 megapíxeles con una apertura que cambia entre f / 1.5 yf /2,4 dependiendo de la luz. Una unidad ultra ancha de 16 megapíxeles y un teleobjetivo de 12 megapíxeles para hacer zoom):

List Front and Back Camera Mobile Device JavaScript

Aunque el ejemplo parece que puede requerir una lógica complicada para que funcione, en realidad no lo es. Debes comprender los conceptos básicos de la interacción con la API de MediaStream en el navegador y estará listo y funcionando en unos minutos. Este artículo explicará cómo enumerar fácilmente todos los dispositivos multimedia en tu dispositivo para usar tu transmisión.

Requisitos

El navegador en el que trabajarás debe ser compatible con la API NavigatorUserMedia. Puedes verificar esto con un simple condicional en tu código:

if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {
    console.log("enumerateDevices is not supported.");
}

Si es compatible, puedes continuar.

1. Listado de dispositivos multimedia sin permiso del usuario

Nota: este enfoque solo funciona en Chrome y Firefox. Está destinado a funcionar solo para verificar si el usuario tiene un micrófono o una cámara conectada, ya que no enumerará los detalles sobre el dispositivo, como la etiqueta, el ID del dispositivo, etc.

Lo primero que debes aprender es cómo enumerar todos los dispositivos de entrada de audio y video disponibles de la computadora. En este ejemplo, usaremos un enfoque muy simple de enumerarlos todos en 2 campos desplegable, uno de ellos contendrá la lista de los dispositivos audioinput (micrófonos) y el otro enumerará todos los dispositivos videoinput (cámaras). El marcado se verá así:

<label>Select Video Source (Camera)</label>

<select id="video-source"></select>

<label>Select Audio Source (Microphone)</label>

<select id="audio-source"></select>

Y el JavaScript que se ejecutará para listar los dispositivos será el siguiente:

navigator.mediaDevices.enumerateDevices().then((devices) => {
    let videoSourcesSelect = document.getElementById("video-source");
    let audioSourcesSelect = document.getElementById("audio-source");

    // Iterar sobre toda la lista de dispositivos (InputDeviceInfo y MediaDeviceInfo)
    devices.forEach((device) => {
        let option = new Option();
        option.value = device.deviceId;

        // Según el tipo de dispositivo multimedia
        switch(device.kind){
            // Agregar dispositivo a la lista de cámaras
            case "videoinput":
                option.text = device.label || `Camera ${videoSourcesSelect.length + 1}`;
                videoSourcesSelect.appendChild(option);
                break;
            // Agregar dispositivo a la lista de micrófonos
            case "audioinput":
                option.text = device.label || `Microphone ${videoSourcesSelect.length + 1}`;
                audioSourcesSelect.appendChild(option);
                break;
        }

        console.log(device);
    });
}).catch(function (e) {
    console.log(e.name + ": " + e.message);
});

Usando la API de Promises obtenida de navigator.mediaDevices.enumerateDevices, obtendremos un arreglo que contiene las instancias InputDeviceInfo y MediaDeviceInfo de cada uno de ellos. Los iteraremos y agregaremos un nuevo elemento de opción a las selecciones definidas, donde cada uno de ellos tendrá una etiqueta simple si está disponible como texto o el número del dispositivo y como valor la propiedad deviceId, que contiene el ID del dispositivo que puede utilizarce para cambiar de fuente más tarde.

El problema con este enfoque es que no obtendrás la información real acerca de los dispositivos e incluso si se han conectado varios dispositivos, siempre obtendrás un solo elemento para cada categoría ( audioinputvideoinputaudiooutput):

List Cameras and Microphone JavaScript

2. Listado de dispositivos multimedia con permiso del usuario

Si deseas información detallada sobre todos los dispositivos disponibles en la computadora / móvil del usuario, deberás solicitar los permisos del usuario:

User's Permissions for Access the Microphone and Camera

Esto se puede solicitar a través del método MediaDevices.getUserMedia() que solicitará el permiso del usuario para usar una entrada de medios que produce un MediaStream con pistas que contienen los tipos de medios solicitados. En este ejemplo, vamos a crear un ayudante que nos permita ejecutar todo con un flujo de trabajo comprensible. Como marcado para este ejemplo, tendremos 2 selects y un elemento de video que reproducirá la transmisión:

<label>Select Video Source (Camera)</label>

<select id="video-source"></select>

<label>Select Audio Source (Microphone)</label>

<select id="audio-source"></select>

<label>Live Preview:</label>
<!-- Es importante establecer la reproducción automática en verdadero, de lo contrario, el video no reproducirá nada al principio. -->
<video autoplay="true" id="player" controls></video>

El ayudante que usaremos para solicitar permisos será el siguiente:

let videoSourcesSelect = document.getElementById("video-source");
let audioSourcesSelect = document.getElementById("audio-source");
let videoPlayer = document.getElementById("player");

// Crear Helper para pedir permiso y listar dispositivos
let MediaStreamHelper = {
    // Propiedad del objeto para almacenar el flujo actual
    _stream: null,
    // Este método devolverá la promesa de enumerar los dispositivos reales
    getDevices: function() {
        return navigator.mediaDevices.enumerateDevices();
    },
    // Solicita permisos de usuario para acceder a la cámara y al video
    requestStream: function() {
        if (this._stream) {
            this._stream.getTracks().forEach(track => {
                track.stop();
            });
        }

        const audioSource = audioSourcesSelect.value;
        const videoSource = videoSourcesSelect.value;
        const constraints = {
            audio: {
                deviceId: audioSource ? {exact: audioSource} : undefined
            },
            video: {
                deviceId: videoSource ? {exact: videoSource} : undefined
            }
        };
    
        return navigator.mediaDevices.getUserMedia(constraints);
    }
};

Con este ayudante, deberías poder solicitar permiso al usuario con el método MediaStreamHelper.requestStream como este:

// Solicite transmisiones (audio y video), solicite permiso y muestre transmisiones en el elemento de video
MediaStreamHelper.requestStream().then(function(stream){
    // Almacenar transmisión actual
    MediaStreamHelper._stream = stream;

    // Seleccione los items actuales en la lista de dispositivos
    audioSourcesSelect.selectedIndex = [...audioSourcesSelect.options].findIndex(option => option.text === stream.getAudioTracks()[0].label);
    videoSourcesSelect.selectedIndex = [...videoSourcesSelect.options].findIndex(option => option.text === stream.getVideoTracks()[0].label);

    videoPlayer.srcObject = stream;

    // Ahora puedes enumerar los dispositivos aqui
    // MediaStreamHelper.getDevices().then(...);
}).catch(function(err){
    console.error(err);
}); 

En este ejemplo, mostraremos la secuencia de audio y video en un elemento de video del documento (reproductor). Después de obtener la transmisión, ahora tendrás acceso a la lista de dispositivos con la promesa de MediaStreamHelper.getDevices:

// Solicite transmisiones (audio y video), solicite permiso y muestre transmisiones en el elemento de video
MediaStreamHelper.requestStream().then(function(stream){
    console.log(stream);
    // Almacenar transmisión actual
    MediaStreamHelper._stream = stream;

    // Seleccione las corrientes actuales en la lista de dispositivos
    audioSourcesSelect.selectedIndex = [...audioSourcesSelect.options].findIndex(option => option.text === stream.getAudioTracks()[0].label);
    videoSourcesSelect.selectedIndex = [...videoSourcesSelect.options].findIndex(option => option.text === stream.getVideoTracks()[0].label);

    // Reproducir la transmisión actual en el elemento Video
    videoPlayer.srcObject = stream;
    
    // Ahora puedes enumerar los dispositivos que utilizan el Asistente
    MediaStreamHelper.getDevices().then((devices) => {
        // Iterar sobre toda la lista de dispositivos (InputDeviceInfo y MediaDeviceInfo)
        devices.forEach((device) => {
            let option = new Option();
            option.value = device.deviceId;

            // Según el tipo de dispositivo multimedia
            switch(device.kind){
                // Agregar dispositivo a la lista de cámaras
                case "videoinput":
                    option.text = device.label || `Camera ${videoSourcesSelect.length + 1}`;
                    videoSourcesSelect.appendChild(option);
                    break;
                // Agregar dispositivo a la lista de micrófonos
                case "audioinput":
                    option.text = device.label || `Microphone ${videoSourcesSelect.length + 1}`;
                    audioSourcesSelect.appendChild(option);
                    break;
            }

            console.log(device);
        });
    }).catch(function (e) {
        console.log(e.name + ": " + e.message);
    });
}).catch(function(err){
    console.error(err);
}); 

Esto mostrará una lista de los dispositivos a los que no teníamos acceso anteriormente:

List Microphones and Cameras in JavaScript

3. Manejo del cambio de fuente de audio y video

Hasta este punto, el código le permite al usuario ver la lista de dispositivos disponibles, ahora es necesario manejar el cambio de flujo cuando el usuario selecciona una nueva fuente de video o audio en las selecciones. Esto se puede hacer fácilmente adjuntando un detector de eventos a selects. Cuando se activa el cambio, el ayudante debe solicitar la transmisión una vez más utilizando las fuentes seleccionadas actualmente y ¡listo! Asegúrate de actualizar también la transmisión del elemento de video:

let videoSourcesSelect = document.getElementById("video-source");
let audioSourcesSelect = document.getElementById("audio-source");
let videoPlayer = document.getElementById("player");

videoSourcesSelect.onchange = function(){
    MediaStreamHelper.requestStream().then(function(stream){
        MediaStreamHelper._stream = stream;
        videoPlayer.srcObject = stream;
    });
};

audioSourcesSelect.onchange = function(){
    MediaStreamHelper.requestStream().then(function(stream){
        MediaStreamHelper._stream = stream;
        videoPlayer.srcObject = stream;
    });
};

Que te diviertas ❤️!

Esto podria interesarte

Conviertete en un programador más sociable