One place for hosting & domains

      câmeras

      Comment accéder aux caméras Avant et Arrière avec getUserMedia() de JavaScript.


      Introduction

      Le HTML5 a permis l’introduction d’API donnant accès aux composants matériels des appareils, y compris de l’API MediaDevices. Cette API permet d’accéder à des périphériques d’entrée média comme l’audio et la vidéo.

      Avec l’aide de cette API, les développeurs peuvent accéder à des appareils audio et vidéo pour diffuser et afficher des flux vidéo en direct dans le navigateur. Dans ce tutoriel, vous accéderez au flux vidéo à partir de l’appareil de l’utilisateur et l’afficherez dans le navigateur à l’aide du getUserMedia méthode.

      L’API getUserMedia utilise les périphériques d’entrée média pour produire un MediaStream. Ce MediaStream contient les types de médias demandés, qu’ils soient audio ou vidéo. Grâce au flux renvoyé par l’API, les flux vidéo peuvent être affichés sur le navigateur, ce qui est utile pour la communication en temps réel sur le navigateur.

      Lorsqu’il est utilisé avec l’ API MediaStream Recording, vous pouvez enregistrer et stocker des données médias saisies sur le navigateur. Cette API ne fonctionne que sur les origines sécurisées (comme les autres API nouvellement introduites), mais elle fonctionne également sur localhost et sur les URL des fichiers.

      Conditions préalables

      • Une connaissance de base de JavaScript. Si vous ne connaissez pas JavaScript, essayez de consulter la série Comment coder en JavaScript.

      Ce tutoriel explique d’abord les concepts et présente des exemples avec Codepen. Dans la dernière étape, vous créerez un flux vidéo fonctionnel pour le navigateur.

      Étape 1 – Vérification de la prise en charge de l’appareil

      Tout d’abord, vous verrez comment vérifier si le navigateur de l’utilisateur prend en charge l’API mediaDevices. Cette API existe dans le navigateur et contient l’état actuel et l’identité de l’agent utilisateur. Le contrôle est effectué à l’aide du code suivant, qui peut être collé dans Codepen :

      if ('mediaDevices' in navigator && 'getUserMedia' in navigator.mediaDevices) {
        console.log("Let's get this party started")
      }
      

      Tout d’abord, cela permet de vérifier si l’API mediaDevices existe dans le navigateur et vérifie ensuite si l’API getUserMedia est disponible dans le mediaDevices. Si cela revient comme true, vous pouvez commencer.

      Étape 2 – Demander la permission de l’utilisateur

      Après avoir confirmé la prise en charge de getUserMedia par le navigateur, vous devez demander l’autorisation d’utiliser les périphériques de saisie des médias sur l’agent utilisateur. Généralement, après qu’un utilisateur ait accordé sa permission, une Promise est renvoyée, qui se transforme en flux média. Cette Promise n’est pas renvoyée lorsque la permission est refusée par l’utilisateur, ce qui bloque l’accès à ces appareils.

      Collez la ligne suivante dans le Codepen pour demander l’autorisation :

      navigator.mediaDevices.getUserMedia({video: true})
      

      L’objet fourni comme argument pour la méthode getUserMedia est appelé constraints. Cela permet de déterminer les périphériques d’entrée média auxquels vous demandez l’autorisation d’accéder. Par exemple, si l’objet contient audio : true, l’utilisateur(rice) sera invité(e) à accorder l’accès au dispositif d’entrée audio.

      Étape 3 – Comprendre les contraintes des médias

      Cette section couvrira le concept général de constraints. L’objet constraints est un objet MediaStreamConstraints qui spécifie les types de médias à demander et les exigences de chaque type de média. Vous pouvez spécifier les exigences pour le flux demandé en utilisant l’objet constraints comme la résolution du flux à utiliser (avant, arrière).

      Vous devez préciser soit audio ou vidéo lors de la demande. Une erreur NotFoundError sera renvoyée si les types de médias demandés ne peuvent être trouvés sur le navigateur de l’utilisateur.

      Si vous avez l’intention de demander un flux vidéo d’une résolution de 1280 x 720, vous pouvez mettre à jour l’objet constraints pour qu’il ressemble à ceci :

      {
        video: {
          width: 1280,
          height: 720,
        }
      }
      

      Avec cette mise à jour, le navigateur essaiera de correspondre aux paramètres de qualité spécifiés pour le flux. Si l’appareil vidéo ne peut pas fournir cette résolution, le navigateur renvoie les autres résolutions disponibles.

      Pour garantir que le navigateur renvoie une résolution qui ne soit pas inférieure à celle fournie, vous devrez utiliser la propriété min. Voici comment vous pourriez mettre à jour l’objet constraints pour inclure la propriété min :

      {
        video: {
          width: {
            min: 1280,
          },
          height: {
            min: 720,
          }
        }
      }
      

      Cela permettra de garantir que la résolution de flux renvoyée sera au moins 1280 x 720. Si cette exigence minimale ne peut pas être respectée, la Promise sera rejetée avec une OverconstrainedError.

      Dans certains cas, vous pouvez être préoccupé(e) par la sauvegarde des données et avoir besoin que le flux ne dépasse pas une résolution donnée. Cela peut s’avérer utile lorsque l’utilisateur est sur un plan limité. Pour activer cette fonctionnalité, mettez à jour l’objet constraints pour qu’il contienne un champ max :

      {
        video: {
          width: {
            min: 1280,
            max: 1920,
          },
          height: {
            min: 720,
            max: 1080
          }
        }
      }
      

      Avec ces paramètres, le navigateur veillera à ce que le flux de retour ne soit pas inférieur à 1280 x 720 et ne dépasse pas 1920 x 1080.

      D’autres termes peuvent être utilisés, notamment exact et ideal. Le paramètre ideal est généralement utilisé avec les propriétés min et max pour trouver le meilleur paramètre possible le plus proche des valeurs idéales fournies.

      Vous pouvez mettre à jour les constraints pour utiliser le mot-clé ideal :

      {
        video: {
          width: {
            min: 1280,
            ideal: 1920,
            max: 2560,
          },
          height: {
            min: 720,
            ideal: 1080,
            max: 1440
          }
        }
      }
      

      Pour indiquer au navigateur d’utiliser la caméra avant ou arrière (sur les appareils mobiles) sur les appareils, vous pouvez spécifier une propriété facingMode dans l’objet video :

      {
        video: {
          width: {
            min: 1280,
            ideal: 1920,
            max: 2560,
          },
          height: {
            min: 720,
            ideal: 1080,
            max: 1440
          },
          facingMode: 'user'
        }
      }
      

      Ce paramètre permet d’utiliser la caméra frontale à tout moment dans tous les appareils. Pour utiliser la caméra arrière sur les appareils mobiles, vous pouvez modifier la propriété facingMode à environment.

      {
        video: {
          ...
          facingMode: {
            exact: 'environment'
          }
        }
      }
      

      Étape 4 – Utiliser la méthode enumerateDevices

      Lorsque la méthode enumerateDevices est appelée, elle renvoie tous les supports d’entrée disponibles sur le PC de l’utilisateur.

      Avec cette méthode, vous pouvez fournir à l’utilisateur des options sur le périphérique d’entrée à utiliser pour la diffusion de contenu audio ou vidéo en continu. Cette méthode renvoie une Promise résolue en un tableau MediaDeviceInfo contenant des informations sur chaque appareil.

      Un exemple d’utilisation de cette méthode est présenté dans l’extrait ci-dessous :

      async function getDevices() {
        const devices = await navigator.mediaDevices.enumerateDevices();
      }
      

      Un exemple de réponse pour chacun des dispositifs ressemblerait à ce qui suit :

      {
        deviceId: "23e77f76e308d9b56cad920fe36883f30239491b8952ae36603c650fd5d8fbgj",
        groupId: "e0be8445bd846722962662d91c9eb04ia624aa42c2ca7c8e876187d1db3a3875",
        kind: "audiooutput",
        label: "",
      }
      

      Remarque : une étiquette ne sera pas renvoyée si un flux n’est pas disponible ou si l’utilisateur a accordé des autorisations d’accès au dispositif.

      Étape 5 – Afficher le flux vidéo sur le navigateur

      Vous êtes passé(e) par le processus de demande et d’obtention de l’accès aux appareils multimédias, vous avez configuré des contraintes pour inclure les résolutions requises et vous avez sélectionné la caméra dont vous aurez besoin pour enregistrer la vidéo.

      Après avoir parcouru toutes ces étapes, vous voudrez au moins voir si le flux est diffusé en fonction des paramètres configurés. Pour ce faire, vous utiliserez l’élément <vidéo> pour afficher le flux vidéo sur le navigateur.

      Comme mentionné précédemment, la méthode getUserMedia renvoie une Promise qui peut être résolue en un flux. Le flux renvoyé peut être converti en une URL objet en utilisant la méthode createObjectURL. Cette URL sera définie comme une source vidéo.

      Vous allez créer une courte démo dans laquelle nous laissons l’utilisateur choisir parmi la liste des appareils vidéo disponibles avec la méthode enumerateDevices.

      Ceci est une méthode navigateur.mediaDevices. Elle énumère les périphériques médias disponibles, tels que les microphones et les caméras. Elle renvoie une Promise résolvable à un ensemble d’objets détaillant les périphériques médias disponibles.

      Créez un fichier index.html et mettez à jour le contenu avec le code ci-dessous :

      index.html

      <!doctype html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <meta name="viewport"
                content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
          <meta http-equiv="X-UA-Compatible" content="ie=edge">
          <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
          <link rel="stylesheet" href="style.css">
          <title>Document</title>
      </head>
      <body>
      <div class="display-cover">
          <video autoplay></video>
          <canvas class="d-none"></canvas>
      
          <div class="video-options">
              <select name="" id="" class="custom-select">
                  <option value="">Select camera</option>
              </select>
          </div>
      
          <img class="screenshot-image d-none" alt="">
      
          <div class="controls">
              <button class="btn btn-danger play" title="Play"><i data-feather="play-circle"></i></button>
              <button class="btn btn-info pause d-none" title="Pause"><i data-feather="pause"></i></button>
              <button class="btn btn-outline-success screenshot d-none" title="ScreenShot"><i data-feather="image"></i></button>
          </div>
      </div>
      
      <script src="https://unpkg.com/feather-icons"></script>
      <script src="script.js"></script>
      </body>
      </html>
      

      Dans l’extrait ci-dessus, vous avez mis en place les éléments dont vous aurez besoin et quelques contrôles pour la vidéo. Un bouton permettant de prendre des captures d’écran du flux vidéo en cours est également inclus.

      Maintenant, mettons un peu de style dans ces éléments.

      Créez un fichier style.css et copiez les styles suivants dans celui-ci. Bootstrap a été inclus pour réduire la quantité de CSS que vous devrez écrire pour faire fonctionner les composants.

      style.css

      .screenshot-image {
          width: 150px;
          height: 90px;
          border-radius: 4px;
          border: 2px solid whitesmoke;
          box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.1);
          position: absolute;
          bottom: 5px;
          left: 10px;
          background: white;
      }
      
      .display-cover {
          display: flex;
          justify-content: center;
          align-items: center;
          width: 70%;
          margin: 5% auto;
          position: relative;
      }
      
      video {
          width: 100%;
          background: rgba(0, 0, 0, 0.2);
      }
      
      .video-options {
          position: absolute;
          left: 20px;
          top: 30px;
      }
      
      .controls {
          position: absolute;
          right: 20px;
          top: 20px;
          display: flex;
      }
      
      .controls > button {
          width: 45px;
          height: 45px;
          text-align: center;
          border-radius: 100%;
          margin: 0 6px;
          background: transparent;
      }
      
      .controls > button:hover svg {
          color: white !important;
      }
      
      @media (min-width: 300px) and (max-width: 400px) {
          .controls {
              flex-direction: column;
          }
      
          .controls button {
              margin: 5px 0 !important;
          }
      }
      
      .controls > button > svg {
          height: 20px;
          width: 18px;
          text-align: center;
          margin: 0 auto;
          padding: 0;
      }
      
      .controls button:nth-child(1) {
          border: 2px solid #D2002E;
      }
      
      .controls button:nth-child(1) svg {
          color: #D2002E;
      }
      
      .controls button:nth-child(2) {
          border: 2px solid #008496;
      }
      
      .controls button:nth-child(2) svg {
          color: #008496;
      }
      
      .controls button:nth-child(3) {
          border: 2px solid #00B541;
      }
      
      .controls button:nth-child(3) svg {
          color: #00B541;
      }
      
      .controls > button {
          width: 45px;
          height: 45px;
          text-align: center;
          border-radius: 100%;
          margin: 0 6px;
          background: transparent;
      }
      
      .controls > button:hover svg {
          color: white;
      }
      

      L’étape suivante consiste à ajouter des fonctionnalités à la démo. En utilisant la méthode enumerateDevices vous obtiendrez les appareils vidéo disponibles et vous les paramèterez comme options au sein de l’élément de sélection. Créez un fichier appelé script.js et mettez-le à jour avec l’extrait suivant :

      script.js

      feather.replace();
      
      const controls = document.querySelector('.controls');
      const cameraOptions = document.querySelector('.video-options>select');
      const video = document.querySelector('video');
      const canvas = document.querySelector('canvas');
      const screenshotImage = document.querySelector('img');
      const buttons = [...controls.querySelectorAll('button')];
      let streamStarted = false;
      
      const [play, pause, screenshot] = buttons;
      
      const constraints = {
        video: {
          width: {
            min: 1280,
            ideal: 1920,
            max: 2560,
          },
          height: {
            min: 720,
            ideal: 1080,
            max: 1440
          },
        }
      };
      
      const getCameraSelection = async () => {
        const devices = await navigator.mediaDevices.enumerateDevices();
        const videoDevices = devices.filter(device => device.kind === 'videoinput');
        const options = videoDevices.map(videoDevice => {
          return `<option value="${videoDevice.deviceId}">${videoDevice.label}</option>`;
        });
        cameraOptions.innerHTML = options.join('');
      };
      
      play.onclick = () => {
        if (streamStarted) {
          video.play();
          play.classList.add('d-none');
          pause.classList.remove('d-none');
          return;
        }
        if ('mediaDevices' in navigator && navigator.mediaDevices.getUserMedia) {
          const updatedConstraints = {
            ...constraints,
            deviceId: {
              exact: cameraOptions.value
            }
          };
          startStream(updatedConstraints);
        }
      };
      
      const startStream = async (constraints) => {
        const stream = await navigator.mediaDevices.getUserMedia(constraints);
        handleStream(stream);
      };
      
      const handleStream = (stream) => {
        video.srcObject = stream;
        play.classList.add('d-none');
        pause.classList.remove('d-none');
        screenshot.classList.remove('d-none');
        streamStarted = true;
      };
      
      getCameraSelection();
      

      Dans l’extrait ci-dessus, il y a deux choses qui se passent. Décomposons celles-ci :

      1. feather.replace() : cette méthode d’appel instancie feather qui est un ensemble d’icônes pour le développement web.
      2. La variable constraints contient la configuration initiale du flux. Elle sera étendue pour inclure le périphérique média choisi par l’utilisateur.
      3. getCameraSelection : cette fonction appelle la méthode enumerateDevices. Ensuite, vous filtrez le tableau à partir de la Promise résolue et sélectionnez les périphériques d’entrée vidéo À partir des résultats filtrés, vous créez <option> pour l’élément <select>.
      4. L’appel de la méthode getUserMedia se fait à l’intérieur de l’écouteur onclick du bouton de lecture. Ici, vous vérifierez si cette méthode est prise en charge par le navigateur de l’utilisateur avant de lancer le flux.
      5. Ensuite, vous appellerez la fonction startStream qui prend un argument constraints. Elle appelle la méthode getUserMedia avec les constraints fournies.handleStream est appelé en utilisant le flux de la Promise résolue Cette méthode fixe le flux renvoyé à l’élément vidéo srcObject.

      Ensuite, vous ajouterez des écouteurs de clics aux boutons de commande de la page pour faire une pause, arrêter et faire des captures d'écran. De plus, vous ajouterez un auditeur à l’élément <select> pour mettre à jour les contraintes de flux avec le périphérique vidéo sélectionné.

      Mettez à jour le fichier script.js avec le code ci-dessous :

      script.js

      ...
      cameraOptions.onchange = () => {
        const updatedConstraints = {
          ...constraints,
          deviceId: {
            exact: cameraOptions.value
          }
        };
        startStream(updatedConstraints);
      };
      
      const pauseStream = () => {
        video.pause();
        play.classList.remove('d-none');
        pause.classList.add('d-none');
      };
      
      const doScreenshot = () => {
        canvas.width = video.videoWidth;
        canvas.height = video.videoHeight;
        canvas.getContext('2d').drawImage(video, 0, 0);
        screenshotImage.src = canvas.toDataURL('image/webp');
        screenshotImage.classList.remove('d-none');
      };
      
      pause.onclick = pauseStream;
      screenshot.onclick = doScreenshot;
      

      Maintenant, lorsque vous ouvrez l’index.html dans le navigateur, cliquer le bouton Play permet de lancer le flux.

      Voici une démo complète :

      Conclusion

      Ce tutoriel a introduit l’API getUserMedia. C’est un ajout intéressant à HTML5, qui facilite le processus de capture des médias sur le web.

      L’API prend un paramètre (constraints) qui peut être utilisé pour configurer l’accès aux périphériques d’entrée audio et vidéo. Il peut également être utilisé pour spécifier la résolution vidéo requise pour votre application.

      Vous pouvez étendre la démo pour donner à l’utilisateur la possibilité de sauvegarder les captures d’écran réalisées, ainsi que d’enregistrer et de stocker des données vidéo et audio à l’aide de l’API MediaStream Recording.



      Source link

      Como acessar as câmeras frontal e traseira com o getUserMedia() do JavaScript


      Introdução

      Juntamente com o HTML5 foram introduzidas as APIs com acesso aos dispositivos de hardware, incluindo a API MediaDevices. Essa API fornece acesso aos dispositivos de entrada de mídia como áudio e vídeo.

      Com a ajuda dessa API, os desenvolvedores podem acessar dispositivos de áudio e vídeo para transmitir e exibir feeds de vídeo ao vivo no navegador. Neste tutorial, você irá acessar o feed de vídeo do dispositivo do usuário e exibi-lo no navegador usando o método getUserMedia.

      A API getUserMedia utiliza os dispositivos de entrada de mídia para produzir um MediaStream (transmissão de mídia). Esse MediaStream contém os tipos de mídia solicitados, seja áudio ou vídeo. Ao usar a transmissão retornada da API, é possível exibir os feeds de vídeo no navegador, o que é útil na comunicação em tempo real no navegador.

      Quando usado em conjunto com a API de gravação do MediaStream, é possível gravar e armazenar os dados de mídia capturados no navegador. Essa API só funciona em origens seguras assim como as APIs recentemente introduzidas, mas também funciona no localhost e URLs de arquivos.

      Pré-requisitos

      Este tutorial irá explicar inicialmente alguns conceitos e demonstrar exemplos com o Codepen. No passo final, você irá criar um feed de vídeo funcional para o navegador.

      Passo 1 — Verificando o suporte de dispositivos

      Primeiro, você verá como verificar se o navegador do usuário oferece suporte à API mediaDevices. Essa API existe dentra da interface do navegador e contém o estado atual e a identidade do agente do usuário. A verificação é realizada com o código a seguir que pode ser colado no Codepen:

      if ('mediaDevices' in navigator && 'getUserMedia' in navigator.mediaDevices) {
        console.log("Let's get this party started")
      }
      

      Primeiro, ele verifica se a API mediaDevices existe dentro de navigator (navegador) e então verifica se a API getUserMedia está disponível dentro dos mediaDevices. Se o comando retorna true, podemos iniciar.

      Passo 2 — Solicitando a permissão do usuário

      Depois de confirmar que o navegador dá suporte à getUserMedia, é necessário solicitar a permissão para utilizar os dispositivos de entrada de mídia no agente do usuário. Normalmente, depois que o usuário concede a permissão, uma Promise é retornada e resolve para uma transmissão de mídia. Essa Promise não é retornada quando a permissão é negada pelo usuário, bloqueando o acesso a esses dispositivos.

      Cole a linha a seguir no Codepen para solicitar a permissão:

      navigator.mediaDevices.getUserMedia({video: true})
      

      O objeto fornecido como um argumento para o método getUserMedia chama-se constraints (restrições). Ele determina quais os dispositivos de entrada de mídia os quais você está solicitando permissão para acessar. Por exemplo, se o objeto contém audio: true, o usuário será solicitado a conceder acesso ao dispositivo de entrada de áudio.

      Passo 3 — Compreendendo as restrições de mídia

      Esta seção irá abordar o conceito geral de contraints. O objeto constraints é um objeto MediaStreamConstraints que especifica os tipos de mídia para solicitar e os requisitos de cada tipo de mídia. É possível especificar os requisitos para a transmissão solicitada usando o objeto constraints, como a resolução da transmissão a ser usada (front, back).

      É necessário especificar audio ou video ao fazer a solicitação. Um NotFoundError será retornado caso os tipos de mídia solicitados não possam ser encontrados no navegador do usuário.

      Se você pretende solicitar uma transmissão de vídeo de resolução 1280 x 720, atualize o objeto constraints para que fique assim:

      {
        video: {
          width: 1280,
          height: 720,
        }
      }
      

      Com essa atualização, o navegador tentará utilizar as configurações de qualidade especificadas para a transmissão. Se o dispositivo de vídeo não puder entregar essa resolução, o navegador retornará outras resoluções disponíveis.

      Para garantir que o navegador retorne uma resolução que não seja inferior àquela fornecida, será necessário utilizar a propriedade min. Aqui está como atualizar o objeto constraints para incluir a propriedade min:

      {
        video: {
          width: {
            min: 1280,
          },
          height: {
            min: 720,
          }
        }
      }
      

      Isso irá garantir que a resolução da transmissão retornada seja de pelo menos 1280 x 720. Caso esse requisito mínimo não possa ser atendido, a promessa será rejeitada com um OverconstrainedError.

      Em alguns casos, você pode ter a preocupação de salvar dados e precisa que a transmissão não ultrapasse uma determinada resolução. Isso pode ser útil nos casos em que o usuário esteja em um plano limitado. Para habilitar essa funcionalidade, atualize o objeto de restrições para que contenha um campo max:

      {
        video: {
          width: {
            min: 1280,
            max: 1920,
          },
          height: {
            min: 720,
            max: 1080
          }
        }
      }
      

      Com essas configurações, o navegador irá garantir que a transmissão de retorno não tenha resolução inferior a 1280 x 720 nem superior a 1920 x 1080.

      Outros termos que podem ser utilizados incluem exact e ideal. A configuração ideal é normalmente usada juntamente com as propriedades min e max para encontrar a melhor resolução possível, o mais perto dos valores ideais fornecidos.

      Atualize as restrições para incluir a palavra-chave ideal:

      {
        video: {
          width: {
            min: 1280,
            ideal: 1920,
            max: 2560,
          },
          height: {
            min: 720,
            ideal: 1080,
            max: 1440
          }
        }
      }
      

      Para fazer o navegador usar a câmera frontal ou traseira (em portáteis) nos dispositivos, especifique uma propriedade facingMode no objeto video:

      {
        video: {
          width: {
            min: 1280,
            ideal: 1920,
            max: 2560,
          },
          height: {
            min: 720,
            ideal: 1080,
            max: 1440
          },
          facingMode: 'user'
        }
      }
      

      Essa configuração irá utilizar a câmera frontal o tempo todo em todos os dispositivos. Para utilizar a câmera traseira em dispositivos móveis, altere a propriedade facingMode para environment.

      {
        video: {
          ...
          facingMode: {
            exact: 'environment'
          }
        }
      }
      

      Passo 4 — Usando o método enumerateDevices

      Quando o método enumerateDevices é chamado, ele retorna todos os dispositivos de entrada de mídia disponíveis no PC do usuário.

      Com esse método, é possível oferecer opções ao usuário sobre qual dispositivo de entrada de mídia usar para a transmissão de conteúdo de áudio ou vídeo. Esse método retorna uma Promise resolvida para uma matriz MediaDeviceInfo contendo informações sobre cada dispositivo.

      Um exemplo de como utilizar esse método é mostrado no trecho abaixo:

      async function getDevices() {
        const devices = await navigator.mediaDevices.enumerateDevices();
      }
      

      Uma amostra de resposta para cada um dos dispositivos se pareceria com a seguinte:

      {
        deviceId: "23e77f76e308d9b56cad920fe36883f30239491b8952ae36603c650fd5d8fbgj",
        groupId: "e0be8445bd846722962662d91c9eb04ia624aa42c2ca7c8e876187d1db3a3875",
        kind: "audiooutput",
        label: "",
      }
      

      Nota: um rótulo não será retornado a menos que uma transmissão esteja disponível, ou se o usuário tenha concedido permissões de acesso ao dispositivo.

      Passo 5 — Exibindo a transmissão de vídeo no navegador

      Até aqui, você passou pelo processo de solicitar e ganhar acesso aos dispositivos de mídia, configurou restrições para incluir as resoluções necessárias e selecionou a câmera que será utilizada para gravar o vídeo.

      Depois de todos esses passos, você irá pelo menos querer ver se a transmissão está sendo realizada com base nas configurações definidas. Para garantir isso, o elemento <video> será usado para exibir a transmissão de vídeo no navegador.

      Como mencionado anteriormente, o método getUserMedia retorna uma Promise que pode ser resolvida para uma transmissão. A transmissão retornada pode ser convertida em uma URL de objeto usando o método createObjectURL. Essa URL será definida como uma fonte de vídeo.

      Você irá criar uma pequena demonstração na qual deixamos o usuário escolher de sua lista de dispositivos de vídeo disponíveis usando o método enumerateDevices.

      Este é um método navigator.mediaDevices. Ele lista os dispositivos de mídia disponíveis, como microfones e câmeras. Depois retorna uma Promise resolvida para uma matriz de objetos detalhando os dispositivos de mídia disponíveis.

      Crie um arquivo index.html e atualize o conteúdo com o código abaixo:

      index.html

      <!doctype html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <meta name="viewport"
                content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
          <meta http-equiv="X-UA-Compatible" content="ie=edge">
          <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
          <link rel="stylesheet" href="style.css">
          <title>Document</title>
      </head>
      <body>
      <div class="display-cover">
          <video autoplay></video>
          <canvas class="d-none"></canvas>
      
          <div class="video-options">
              <select name="" id="" class="custom-select">
                  <option value="">Select camera</option>
              </select>
          </div>
      
          <img class="screenshot-image d-none" alt="">
      
          <div class="controls">
              <button class="btn btn-danger play" title="Play"><i data-feather="play-circle"></i></button>
              <button class="btn btn-info pause d-none" title="Pause"><i data-feather="pause"></i></button>
              <button class="btn btn-outline-success screenshot d-none" title="ScreenShot"><i data-feather="image"></i></button>
          </div>
      </div>
      
      <script src="https://unpkg.com/feather-icons"></script>
      <script src="script.js"></script>
      </body>
      </html>
      

      No trecho acima, foram configurados os elementos que serão necessários e alguns controles para o vídeo. Também foi incluído um botão para tirar capturas de tela do feed de vídeo atual.

      Agora, vamos adicionar um pouco de estilo a esses componentes.

      Crie um arquivo style.css e copie os estilos a seguir nele. O Bootstrap foi incluído para reduzir a quantidade de CSS que você precisará escrever para que os componentes sejam iniciados.

      style.css

      .screenshot-image {
          width: 150px;
          height: 90px;
          border-radius: 4px;
          border: 2px solid whitesmoke;
          box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.1);
          position: absolute;
          bottom: 5px;
          left: 10px;
          background: white;
      }
      
      .display-cover {
          display: flex;
          justify-content: center;
          align-items: center;
          width: 70%;
          margin: 5% auto;
          position: relative;
      }
      
      video {
          width: 100%;
          background: rgba(0, 0, 0, 0.2);
      }
      
      .video-options {
          position: absolute;
          left: 20px;
          top: 30px;
      }
      
      .controls {
          position: absolute;
          right: 20px;
          top: 20px;
          display: flex;
      }
      
      .controls > button {
          width: 45px;
          height: 45px;
          text-align: center;
          border-radius: 100%;
          margin: 0 6px;
          background: transparent;
      }
      
      .controls > button:hover svg {
          color: white !important;
      }
      
      @media (min-width: 300px) and (max-width: 400px) {
          .controls {
              flex-direction: column;
          }
      
          .controls button {
              margin: 5px 0 !important;
          }
      }
      
      .controls > button > svg {
          height: 20px;
          width: 18px;
          text-align: center;
          margin: 0 auto;
          padding: 0;
      }
      
      .controls button:nth-child(1) {
          border: 2px solid #D2002E;
      }
      
      .controls button:nth-child(1) svg {
          color: #D2002E;
      }
      
      .controls button:nth-child(2) {
          border: 2px solid #008496;
      }
      
      .controls button:nth-child(2) svg {
          color: #008496;
      }
      
      .controls button:nth-child(3) {
          border: 2px solid #00B541;
      }
      
      .controls button:nth-child(3) svg {
          color: #00B541;
      }
      
      .controls > button {
          width: 45px;
          height: 45px;
          text-align: center;
          border-radius: 100%;
          margin: 0 6px;
          background: transparent;
      }
      
      .controls > button:hover svg {
          color: white;
      }
      

      O próximo passo é adicionar funcionalidade à demonstração. Usando o método enumerateDevices, você irá obter os dispositivos de vídeo disponíveis e os definirá como opções dentro do elemento selecionado. Crie um arquivo chamado script.js e atualize-o com o seguinte trecho:

      script.js

      feather.replace();
      
      const controls = document.querySelector('.controls');
      const cameraOptions = document.querySelector('.video-options>select');
      const video = document.querySelector('video');
      const canvas = document.querySelector('canvas');
      const screenshotImage = document.querySelector('img');
      const buttons = [...controls.querySelectorAll('button')];
      let streamStarted = false;
      
      const [play, pause, screenshot] = buttons;
      
      const constraints = {
        video: {
          width: {
            min: 1280,
            ideal: 1920,
            max: 2560,
          },
          height: {
            min: 720,
            ideal: 1080,
            max: 1440
          },
        }
      };
      
      const getCameraSelection = async () => {
        const devices = await navigator.mediaDevices.enumerateDevices();
        const videoDevices = devices.filter(device => device.kind === 'videoinput');
        const options = videoDevices.map(videoDevice => {
          return `<option value="${videoDevice.deviceId}">${videoDevice.label}</option>`;
        });
        cameraOptions.innerHTML = options.join('');
      };
      
      play.onclick = () => {
        if (streamStarted) {
          video.play();
          play.classList.add('d-none');
          pause.classList.remove('d-none');
          return;
        }
        if ('mediaDevices' in navigator && navigator.mediaDevices.getUserMedia) {
          const updatedConstraints = {
            ...constraints,
            deviceId: {
              exact: cameraOptions.value
            }
          };
          startStream(updatedConstraints);
        }
      };
      
      const startStream = async (constraints) => {
        const stream = await navigator.mediaDevices.getUserMedia(constraints);
        handleStream(stream);
      };
      
      const handleStream = (stream) => {
        video.srcObject = stream;
        play.classList.add('d-none');
        pause.classList.remove('d-none');
        screenshot.classList.remove('d-none');
        streamStarted = true;
      };
      
      getCameraSelection();
      

      No trecho acima, algumas coisas estão acontecendo. Vamos dividi-las:

      1. feather.replace(): essa chamada de método cria uma instância de feather, que é um ícone definido para o desenvolvimento Web.
      2. A variável constraints contém a configuração inicial para a transmissão. Ela será estendida para incluir o dispositivo de mídia escolhido pelo usuário.
      3. getCameraSelection: essa função chama o método enumerateDevices. Em seguida, você filtra a matriz gerada a partir da Promise resolvida e seleciona os dispositivos de entrada de vídeo. A partir dos resultados filtrados, você cria <option> para o elemento <select>.
      4. Chamar o método getUserMedia acontece dentro do ouvinte onclick do botão play. Aqui, você irá verificar se esse método é suportado pelo navegador do usuário antes de iniciar a transmissão.
      5. Em seguida, você irá chamar a função startStream que recebe um argumento constraints. Ela chama o método getUserMedia com as constraints fornecidas. O handleStream é chamado usando a transmissão da Promise resolvida. Esse método define a transmissão retornada para o srcObject do elemento de vídeo.

      Em seguida, você irá adicionar um listener de clique aos controles dos botões na página para pause, stop e tirar screenshots. Além disso, você irá adicionar um listener ao elemento <select> para atualizar as restrições da transmissão com o dispositivo de vídeo selecionado.

      Atualize o arquivo script.js com o código abaixo:

      script.js

      ...
      cameraOptions.onchange = () => {
        const updatedConstraints = {
          ...constraints,
          deviceId: {
            exact: cameraOptions.value
          }
        };
        startStream(updatedConstraints);
      };
      
      const pauseStream = () => {
        video.pause();
        play.classList.remove('d-none');
        pause.classList.add('d-none');
      };
      
      const doScreenshot = () => {
        canvas.width = video.videoWidth;
        canvas.height = video.videoHeight;
        canvas.getContext('2d').drawImage(video, 0, 0);
        screenshotImage.src = canvas.toDataURL('image/webp');
        screenshotImage.classList.remove('d-none');
      };
      
      pause.onclick = pauseStream;
      screenshot.onclick = doScreenshot;
      

      Agora, quando ao se abrir o arquivo index.html no navegador, clicar no botão Play irá iniciar a transmissão.

      Aqui está uma demonstração completa:

      Conclusão

      Esse tutorial introduziu a API getUserMedia. É uma adição interessante ao HTML5 que facilita o processo de captura de mídia na Web.

      A API recebe um parâmetro (constraints) que pode ser usado para configurar o acesso aos dispositivos de entrada de áudio e vídeo. Ela também pode ser usada para especificar a resolução de vídeo necessária para o seu aplicativo.

      É possível estender a demonstração ainda mais para dar ao usuário uma opção para salvar as capturas de tela feitas, bem como gravar e armazenar dados de vídeo e áudio com a ajuda da API MediaStream Recording.



      Source link