Cómo acceder a la cámara en una PWA

Publicado: 2020-08-19

Tabla de contenido

Anteriormente presentado en nuestro artículo que detalla las capacidades de hardware de PWA, el acceso a la cámara es una de las características más destacadas que estamos viendo cada vez más. Pero integrar adecuadamente esta capacidad en su PWA tampoco es una tarea fácil, por lo que en nuestro artículo de hoy, intentaremos guiarlo a través de todo este proceso:

requisitos previos

  • Una PWA básica que se puede crear fácilmente usando ReactJS y nuestra guía escrita
  • Una sólida comprensión de HTML y JavaScript.

Cómo acceder a la cámara en una PWA

Los basicos

Presentamos getUserMedia() , una API de webRTC

Para obtener acceso directo a una cámara y/o un micrófono, la Web usa una API llamada getUserMedia() que es ampliamente compatible con casi todos los navegadores modernos. Esta API, junto con RTCPeerConnection y RTCDataChannel , son partes de WebRTC, un marco integrado en los navegadores que permite la comunicación en tiempo real.

Básicamente, lo que hace la API ( navigator.mediaDevices.getUserMedia(constraints) ) es solicitar permiso al usuario para acceder a la entrada de audio y video del teléfono (por ejemplo, micrófono, cámara web, cámara, etc.). Con qué permiso, la API genera un objeto JavaScript de MediaStream llamado local que se puede manipular aún más.

Ejemplos

Digamos, por ejemplo, que tenemos un botón:

 <button>Mostrar mi cara</button>

Y al hacer clic en qué botón llama al método navigator.mediaDevices.getUserMedia() (sin entrada de audio):

 navigator.mediaDevices.getUserMedia({
 vídeo: cierto
})

Diablos, también podemos volvernos locos con las restricciones:

 navigator.mediaDevices.getUserMedia({
  video: {
    Relación de aspecto mínima: 1.333,
    minFrameRate: 30,
    ancho: 1280,
    altura: 720
  }
})

Además, podemos especificar una propiedad de modo de facingMode en el objeto de video que le dice al navegador qué cámara del dispositivo usar:

 {
  video: {
    ...
    modo de orientación: {
//Usa la cámara trasera
      exacto: 'ambiente'
    }
  }
}

O

 {
 video : {
  …
//Usar la cámara frontal
  modo de orientación: 'usuario'
 }
}

Notas :

  • La API solo está disponible en un origen seguro (HTTPS)
  • Para obtener una lista de las restricciones admitidas en el dispositivo actual, ejecute:
 navigator.mediaDevices.getSupportedConstraints()

la parte complicada

Ahora que tenemos una sólida comprensión de los conceptos básicos, pasemos a la parte avanzada. En esta parte, intentaremos crear un botón en nuestra PWA y, al hacer clic en él, abrirá nuestra cámara y nos permitirá seguir trabajando.

Creación del botón [Get access to camera]

Primero, comencemos con el <button> en nuestro index.html:

 <button>Obtener acceso a la cámara</button>
<reproducción automática de video></video>
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>

Nota :

  • La reproducción automática está ahí para decirle a la transmisión de medios que se reproduzca automáticamente y no se congele en el primer cuadro.
  • El adaptador-latest.js es una cuña para aislar las aplicaciones de los cambios de especificaciones y las diferencias de prefijo.

Transmita video en tiempo real haciendo clic en el botón

Para transmitir un video en tiempo real al hacer clic en el botón, necesitaremos agregar un EventListener que se llamará cuando se emita el evento de click :

 document.querySelector('#get-access').addEventListener('click', función asíncrona init(e) {
  probar {
 }
atrapar (error) {
 }
})

Luego, llama a navigator.mediaDevices.getUserMedia() y solicita una transmisión de video usando la cámara web del dispositivo:

 document.querySelector('#get-access').addEventListener('click', función asíncrona init(e) {
  probar {
    const stream = esperar navigator.mediaDevices.getUserMedia({
      sonido: falso,
      vídeo: cierto
    })
    const videoTracks = stream.getVideoTracks()
    pista const = pistas de vídeo[0]
    alert(`Obteniendo video de: ${track.label}`)
    document.querySelector('video').srcObject = corriente
    document.querySelector('#get-access').setAttribute('oculto', verdadero)
// El flujo de video es detenido por track.stop() después de 3 segundos de reproducción.
    setTimeout(() =&gt; { track.stop() }, 3 * 1000)
  } atrapar (error) {
    alerta(`${error.nombre}`)
    consola.error(error)
  }
})

Además, como se especificó anteriormente en la sección Básico , también puede especificar más requisitos para la transmisión de video:

 navigator.mediaDevices.getUserMedia({
  video: {
    obligatorio: { minAspectRatio: 1.333, maxAspectRatio: 1.334, modo de orientación: 'usuario'},
    opcional: [
      { minFrameRate: 60 },
      { ancho máximo: 640 },
      { altura máxima: 480 }
    ]
  }
}, devolución de llamada exitosa, devolución de llamada errónea);

Crear un lienzo

Con el elemento <video> combinado con un <canvas> , puede procesar aún más nuestra transmisión de video en tiempo real. Esto incluye la capacidad de realizar una variedad de efectos, como la aplicación de filtros personalizados, chroma-keying (también conocido como el "efecto de pantalla verde"), todo mediante el uso de código JavaScript.

En caso de que desee leer más sobre esto, Mozilla ha escrito una guía detallada sobre la manipulación de videos usando lienzo, ¡así que no olvide consultarla!

Capture una instantánea del lienzo usando takePhoto() y grabFrame()

Los nuevos métodos takePhoto y grabFrame de la API getUserMedia se pueden usar para capturar una instantánea del video que se está transmitiendo actualmente. Todavía hay diferencias significativas entre los dos métodos:

Básicamente, lo que hace grabFrame es simplemente tomar el siguiente cuadro de video, un método simplista y no tan eficiente para capturar fotos. El método takePhoto , por otro lado, utiliza un método mejor para capturar fotogramas que consiste en interrumpir el flujo de video actual para usar la "resolución de cámara fotográfica más alta disponible" de la cámara para capturar una imagen Blob.

En los siguientes ejemplos, dibujaremos el marco capturado en un elemento de canvas usando el método grabFrame :

 var grabFrameButton = document.querySelector('button#grabFrame');
var canvas = document.querySelector('canvas');

grabFrameButton.onclick = grabFrame;

función agarrarFrame() {
  captura de imagen.grabFrame()
  .then(función(imageBitmap) {
    console.log('Fotograma grabado:', imageBitmap);
    lienzo.ancho = imageBitmap.ancho;
    lienzo.altura = imageBitmap.altura;
    canvas.getContext('2d').drawImage(imageBitmap, 0, 0);
    canvas.classList.remove('oculto');
  })
  .catch(función(error) {
    console.log('grabFrame() error: ', error);
  });
}

Y en este ejemplo, usamos el método takePhoto() :

 var tomarFotoButton = document.querySelector('button#tomarFoto');
var canvas = document.querySelector('canvas');

tomarFotoButton.onclick = tomarFoto;

// Obtener un Blob de la fuente de cámara seleccionada actualmente y
// mostrar esto con un elemento img.
función tomarFoto() {
  imageCapture.takePhoto().then(function(blob) {
    console.log('Tomé una foto:', blob);
    img.classList.remove('oculto');
    img.src = URL.createObjectURL(blob);
  }).catch(función(error) {
    console.log('tomarFoto() error: ', error);
  });
}

Para tener una idea de cómo se ven los métodos anteriores en acción, recomendamos Captura de imagen simple; y, alternativamente, PWA Media Capture también es un buen ejemplo de cómo sería una función básica de captura de medios en PWA.

Conclusión

En este tutorial, le presentamos los conceptos básicos, así como algunos trucos avanzados para implementar funciones de cámara en su PWA. El resto depende solo de su imaginación para aprovechar al máximo esta característica.

Para los comerciantes de Magento que buscan desarrollar una tienda impulsada por PWA de próxima generación, aquí en SimiCart ofrecemos soluciones completas de PWA adaptadas a sus necesidades.

Explorar simicart PWA