Como acessar a câmera em um PWA

Publicados: 2020-08-19

Índice

Anteriormente apresentado em nosso artigo detalhando os recursos de hardware do PWA, o acesso à câmera é um dos recursos mais proeminentes que estamos vendo cada vez mais. Mas integrar adequadamente esse recurso ao seu PWA também não é uma tarefa fácil, e é por isso que, em nosso artigo de hoje, tentaremos guiá-lo por todo esse processo:

Pré-requisitos

  • Um PWA básico que pode ser facilmente criado usando ReactJS e nosso guia escrito
  • Uma sólida compreensão de HTML e JavaScript

Como acessar a câmera em um PWA

O básico

Apresentando o getUserMedia() — uma API do webRTC

Para obter acesso direto a uma câmera e/ou microfone, a Web usa uma API chamada getUserMedia() que é amplamente suportada em quase todos os navegadores modernos. Essa API, juntamente com RTCPeerConnection e RTCDataChannel , fazem parte do WebRTC — uma estrutura incorporada aos navegadores que permite a comunicação em tempo real.

Basicamente, o que a API ( navigator.mediaDevices.getUserMedia(constraints) ) faz é solicitar ao usuário permissão para acessar a entrada de áudio e vídeo do telefone (por exemplo, microfone, webcam, câmera, etc). Usando essa permissão, a API gera um objeto JavaScript MediaStream chamado local que pode ser manipulado posteriormente.

Exemplos

Digamos, por exemplo, que temos um botão:

 <button>Mostrar meu rosto</button>

E clicando em qual botão chama o método navigator.mediaDevices.getUserMedia() (sem entrada de áudio):

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

Heck, podemos enlouquecer com as restrições também:

 navigator.mediaDevices.getUserMedia({
  vídeo: {
    minAspectRatio: 1,333,
    minFrameRate: 30,
    largura: 1280,
    altura: 720
  }
})

Além disso, podemos especificar uma facingMode no objeto de vídeo que informa ao navegador qual câmera do dispositivo usar:

 {
  vídeo: {
    ...
    enfrentandoModo: {
//Usa a câmera traseira
      exato: 'ambiente'
    }
  }
}

Ou

 {
 vídeo : {
  …
//Usa a câmera frontal
  enfrentandoMode: 'usuário'
 }
}

Observações :

  • A API está disponível apenas em uma origem segura (HTTPS)
  • Para obter uma lista das restrições suportadas no dispositivo atual, execute:
 navigator.mediaDevices.getSupportedConstraints()

A parte complicada

Agora que temos uma compreensão sólida do básico, vamos passar para a parte avançada. Nesta parte, tentaremos criar um botão em nosso PWA e, ao clicar nele, ele abrirá nossa câmera e nos permitirá trabalhar mais.

Criando o botão [Get access to camera]

Primeiro, vamos começar com o <button> em nosso index.html :

 <button>Acessar a câmera</button>
<reprodução automática de vídeo></vídeo>
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>

Notas :

  • A reprodução automática existe para dizer ao fluxo de mídia para reprodução automática e não congelar no primeiro quadro.
  • O adapter-latest.js é um shim para isolar os aplicativos de alterações de especificações e diferenças de prefixo.

Transmita vídeo em tempo real clicando no botão

Para transmitir um vídeo em tempo real ao clicar no botão, precisaremos adicionar um EventListener que será chamado quando o evento de click for emitido:

 document.querySelector('#get-access').addEventListener('click', async function init(e) {
  tentar {
 }
pegar (erro) {
 }
})

Em seguida, ele chama navigator.mediaDevices.getUserMedia() e solicita um fluxo de vídeo usando a webcam do dispositivo:

 document.querySelector('#get-access').addEventListener('click', async function init(e) {
  tentar {
    const stream = await navigator.mediaDevices.getUserMedia({
      áudio: falso,
      vídeo: verdade
    })
    const videoTracks = stream.getVideoTracks()
    const faixa = videoTracks[0]
    alert(`Obtendo vídeo de: ${track.label}`)
    document.querySelector('video').srcObject = stream
    document.querySelector('#get-access').setAttribute('hidden', true)
//O fluxo de vídeo é interrompido por track.stop() após 3 segundos de reprodução.
    setTimeout(() =&gt; { track.stop() }, 3 * 1000)
  } pegar (erro) {
    alert(`${error.name}`)
    console.error(erro)
  }
})

Além disso, conforme especificado acima na seção Básico , você também pode especificar mais requisitos para o fluxo de vídeo:

 navigator.mediaDevices.getUserMedia({
  vídeo: {
    obrigatório: { minAspectRatio: 1.333, maxAspectRatio: 1.334,facingMode: 'user'},
    opcional: [
      { minFrameRate: 60},
      {maxWidth: 640},
      { maxHeigth: 480 }
    ]
  }
}, successCallback, errorCallback);

Criando uma tela

Com o elemento <video> combinado com um <canvas> , você pode processar ainda mais nosso fluxo de vídeo em tempo real. Isso inclui a capacidade de executar uma variedade de efeitos, como aplicar filtros personalizados, chroma-keying (também conhecido como “efeito de tela verde”) – tudo usando código JavaScript.

Caso você queira ler mais sobre isso, a Mozilla escreveu um guia detalhado sobre Manipulação de vídeo usando tela, então não se esqueça de conferir!

Capture um instantâneo da tela usando takePhoto() e grabFrame()

Os novos métodos takePhoto e grabFrame da API getUserMedia podem ser usados ​​para capturar um instantâneo do vídeo atualmente em streaming. Existem, ainda, diferenças significativas entre os dois métodos:

Basicamente, o que o grabFrame faz é simplesmente capturar o próximo quadro de vídeo - um método simplista e não tão eficiente de capturar fotos. O método takePhoto , por outro lado, usa um método melhor de captura de quadros que é interromper o fluxo de vídeo atual para usar a “maior resolução de câmera fotográfica disponível” da câmera para capturar uma imagem Blob.

Nos exemplos abaixo, desenharemos o quadro capturado em um elemento de canvas usando o método grabFrame :

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

grabFrameButton.onclick = grabFrame;

função pegarFrame() {
  imageCapture.grabFrame()
  .then(function(imagemBitmap) {
    console.log('Quadro capturado:', imageBitmap);
    canvas.width = imageBitmap.width;
    tela.altura = imagemBitmap.altura;
    canvas.getContext('2d').drawImage(imageBitmap, 0, 0);
    canvas.classList.remove('hidden');
  })
  .catch(função(erro) {
    console.log('grabFrame() erro: ', erro);
  });
}

E neste exemplo, usamos o método takePhoto() :

 var takePhotoButton = document.querySelector('button#takePhoto');
var canvas = document.querySelector('canvas');

takePhotoButton.onclick = tirarFoto;

// Obtém um Blob da fonte de câmera selecionada no momento e
// exibe isso com um elemento img.
função tirarFoto() {
  imageCapture.takePhoto().then(function(blob) {
    console.log('Tirou foto:', blob);
    img.classList.remove('hidden');
    img.src = URL.createObjectURL(blob);
  }).catch(função(erro) {
    console.log('takePhoto() erro: ', erro);
  });
}

Para ter uma ideia de como os métodos acima se parecem em ação, recomendamos o Simple Image Capture; e, alternativamente, o PWA Media Capture também é um bom exemplo de como seria um recurso básico de captura de mídia no PWA.

Conclusão

Neste tutorial, apresentamos o básico e alguns truques avançados para implementar os recursos da câmera em seu PWA. O resto depende apenas da sua imaginação para tirar o melhor proveito desse recurso.

Para os comerciantes Magento que desejam desenvolver uma loja PWA de última geração, aqui no SimiCart fornecemos soluções completas de PWA adaptadas às suas necessidades.

Explore o simicart PWA