One place for hosting & domains

      accéder

      Cómo usar ViewChild en Angular para acceder a una directiva, un componente secundario o un elemento DOM


      Introducción

      Este artículo le introducirá el decorador ViewChild de Angular.

      Es posible que existan situaciones en las que desee acceder a una directiva, componente secundario o elemento DOM de una clase principal de componentes. El decorador ViewChild devuelve el primer elemento que coincide con una directiva, un componente o un selector de referencia de plantillas concreto.

      Uso de ViewChild con Directivas

      ViewChild hace que sea posible acceder a directivas.

      Digamos que tenemos una SharkDirective.

      Idealmente, usará @angular/cli para generar (generate) su directiva:

      • ng generate directive shark

      De lo contrario, es posible que necesite añadirlo manualmente a app.module.ts:

      app.module.ts

      import { SharkDirective } from './shark.directive';
      ...
      @NgModule({
        declarations: [
          AppComponent,
          SharkDirective
        ],
        ...
      })
      

      Nuestra directiva buscará elementos con el atributo appShark y preparará el texto en el elemento con la palabra Shark:

      shark.directive.ts

      import {
        Directive,
        ElementRef,
        Renderer2
      } from '@angular/core';
      
      @Directive(
        { selector: '[appShark]' }
      )
      export class SharkDirective {
        creature="Dolphin";
      
        constructor(elem: ElementRef, renderer: Renderer2) {
          let shark = renderer.createText('Shark ');
          renderer.appendChild(elem.nativeElement, shark);
        }
      }
      

      A continuación, añadiremos un Shark a Fin usándolo en la plantilla del componente:

      app.component.html

      <span appShark>Fin!</span>
      

      Cuando visualice la aplicación en un navegador, se mostrará como:

      Output

      Shark Fin!

      Ahora, podemos acceder a la variable de la instancia creature de SharkDirective y estableceremos una variable de instancia extraCreature con su valor:

      app.component.ts

      import {
        Component,
        ViewChild,
        AfterViewInit
      } from '@angular/core';
      import { SharkDirective } from './shark.directive';
      
      @Component({
        selector: 'app-root',
        templateUrl: './app.component.html',
        styleUrls: ['./app.component.css']
      })
      export class AppComponent implements AfterViewInit {
        extraCreature: string;
      
        @ViewChild(SharkDirective)
        set appShark(directive: SharkDirective) {
          this.extraCreature = directive.creature;
        };
      
        ngAfterViewInit() {
          console.log(this.extraCreature); // Dolphin
        }
      }
      

      Usamos un regulador aquí para establecer la variable extraCreature. Observe que esperamos que el enlace de ciclo de vida AfterViewInit acceda a nuestra variable, ya que es aquí cuando los componentes y directivas secundarios están disponibles.

      Cuando se visualice la aplicación en un navegador, veremos el mensaje "Shark Fin!" (¡funcionó!). Sin embargo, en el registro de la consola, se mostrará lo siguiente:

      Output

      Dolphin

      El componente principal pudo acceder al valor de la directiva.

      Uso de ViewChild con elementos DOM

      ViewChild permite acceder a elementos DOM nativos que tienen una variable de referencia de plantilla.

      Digamos que tenemos un <input> en nuestra plantilla con la variable de referencia #someInput:

      app.component.html

      <input #someInput placeholder="Your favorite sea creature">
      

      Ahora podemos acceder a <input> con ViewChild y establecer el valor:

      app.component.ts

      import {
        Component,
        ViewChild,
        AfterViewInit,
        ElementRef
      } from '@angular/core';
      
      @Component({
        selector: 'app-root',
        templateUrl: './app.component.html',
        styleUrls: ['./app.component.css']
      })
      export class AppComponent implements AfterViewInit {
        @ViewChild('someInput') someInput: ElementRef;
        ngAfterViewInit() {
          this.someInput.nativeElement.value="Whale!";
        }
      }
      

      Cuando ngAfterViewInit active el valor de nuestro <input> se establecerá a:

      Output

      Whale!

      El componente principal pudo establecer el valor del elemento DOM secundario.

      Usar ViewChild con componentes secundarios

      ViewChild hace que sea posible acceder a un componente secundario y a métodos de invocación o variables de instancia de acceso que están disponibles para el secundario.

      Digamos que tenemos un ChildComponent. Idealmente, usará @angular/cli para generar (generate) su componente:

      • ng generate component child --flat

      Si no es así, es posible que deba crear los archivos child.component.css y child.component.html y añadirlos manualmente a app.modul.ts:

      app.module.ts

      import { ChildComponent } from './child.component';
      ...
      @NgModule({
        declarations: [
          AppComponent,
          ChildComponent
        ],
        ...
      })
      

      Añadiremos un método whoAmI a ChildComponent, que devuelve un mensaje:

      child.component.ts

      whoAmI() {
        return 'I am a child component!';
      }
      

      A continuación, haremos referencia al componente en la plantilla de nuestra aplicación:

      app.component.html

      <app-child>child works!</app-child>
      

      Ahora podemos invocar el método whoAmI desde nuestra clase principal de componentes con ViewChild

      app.component.ts

      import {
        Component,
        ViewChild,
        AfterViewInit
      } from '@angular/core';
      import { ChildComponent } from './child.component';
      
      @Component({
        selector: 'app-root',
        templateUrl: './app.component.html',
        styleUrls: ['./app.component.css'],
      })
      export class AppComponent implements AfterViewInit {
        @ViewChild(ChildComponent) child: ChildComponent;
        ngAfterViewInit() {
          console.log(this.child.whoAmI()); // I am a child component!
        }
      }
      

      Cuando se visualiza la aplicación en un navegador, el registro de la consola mostrará:

      Output

      I am a child component!

      El componente principal pudo invocar el método whoAmI del componente secundario.

      Conclusión

      Ha aprendido a usar ViewChild para acceder a una directiva, componente secundario y a un elemento DOM desde una clase principal de componentes.

      Si la referencia cambia a un nuevo elemento dinámicamente, ViewChild actualizará automáticamente su referencia.

      En los casos es los que desee acceder a múltiples secundarios, usará ViewChildren.

      Si desea obtener más información sobre Angular, consulte nuestra página sobre el tema Angular para ver ejercicios y proyectos de programación.



      Source link

      Comment utiliser ViewChild dans Angular pour accéder à un composant enfant, à une directive ou un élément DOM


      Introduction

      Dans cet article, vous allons vous expliquer ce qu’est un décorateur ViewChild d’Angular.

      Il se peut que dans certaines situations vous souhaitiez accéder à une directive, un composant enfant ou un élément DOM à partir d’une catégorie de composants parent. Le décorateur ViewChild renvoie le premier élément qui correspond à un sélecteur de référence de directive, de composant ou de modèle donné.

      Utilisation de ViewChild avec des directives

      ViewChild permet d’accéder aux directives.

      Supposons que nous ayons une SharkDirective.

      L’idéal serez que vous puissiez utiliser @angular/cli pour générer votre directive :

      • ng generate directive shark

      Ou alors, il vous faudra l’ajouter manuellement à app.module.ts :

      app.module.ts

      import { SharkDirective } from './shark.directive';
      ...
      @NgModule({
        declarations: [
          AppComponent,
          SharkDirective
        ],
        ...
      })
      

      Notre directive recherchera les éléments avec l’attribut appShark et ajoutera le texte dans l’élément avec le terme Shark :

      shark.directive.ts

      import {
        Directive,
        ElementRef,
        Renderer2
      } from '@angular/core';
      
      @Directive(
        { selector: '[appShark]' }
      )
      export class SharkDirective {
        creature="Dolphin";
      
        constructor(elem: ElementRef, renderer: Renderer2) {
          let shark = renderer.createText('Shark ');
          renderer.appendChild(elem.nativeElement, shark);
        }
      }
      

      Ensuite, nous allons ajouter un Shark à Fin en l’utilisant dans le modèle de composant :

      app.component.html

      <span appShark>Fin!</span>
      

      Lorsque vous visualiserez l’application dans un navigateur, l’affichage sera le suivant :

      Output

      Shark Fin!

      Maintenant, nous pouvons accéder à la variable d’instance creature de SharkDirective. Elle configurera une variable extraCreature avec sa valeur :

      app.component.ts

      import {
        Component,
        ViewChild,
        AfterViewInit
      } from '@angular/core';
      import { SharkDirective } from './shark.directive';
      
      @Component({
        selector: 'app-root',
        templateUrl: './app.component.html',
        styleUrls: ['./app.component.css']
      })
      export class AppComponent implements AfterViewInit {
        extraCreature: string;
      
        @ViewChild(SharkDirective)
        set appShark(directive: SharkDirective) {
          this.extraCreature = directive.creature;
        };
      
        ngAfterViewInit() {
          console.log(this.extraCreature); // Dolphin
        }
      }
      

      Ici, nous avons utilisé une méthode de réglage pour configurer la variable extraCreature. Notez que nous attendons que le hook de cycle de vie AfterViewInit ait accès à notre variable, car c’est à ce moment-là que les composants et les directives enfant seront disponibles.

      Lorsque nous consultons l’application dans un navigateur, nous voyons encore apparaître "Shark Fin!" . Cependant, dans le journal de la console, il s’affichera de la manière suivante :

      Output

      Dolphin

      Le composant parent a pu accéder à la valeur depuis la directive.

      Utilisation de ViewChild avec les éléments DOM

      ViewChild permet d’accéder aux éléments DOM natifs qui ont une variable de référence de modèle.

      Supposons que nous ayons un <input> dans notre modèle avec la variable de référence #someInput :

      app.component.html

      <input #someInput placeholder="Your favorite sea creature">
      

      Maintenant, nous pouvons accéder à <input> avec ViewChild et configurer la value :

      app.component.ts

      import {
        Component,
        ViewChild,
        AfterViewInit,
        ElementRef
      } from '@angular/core';
      
      @Component({
        selector: 'app-root',
        templateUrl: './app.component.html',
        styleUrls: ['./app.component.css']
      })
      export class AppComponent implements AfterViewInit {
        @ViewChild('someInput') someInput: ElementRef;
        ngAfterViewInit() {
          this.someInput.nativeElement.value="Whale!";
        }
      }
      

      Lorsque ngAfterViewInit se déclenche, la valeur de notre <input> sera configurée :

      Output

      Whale!

      Le composant parent a réussi à configurer la valeur de l’élément DOM enfant.

      Utilisation de ViewChild avec des composants enfant

      ViewChild permet d’accéder à un composant enfant et appeler des méthodes ou d’accéder à des variables d’instance qui sont disponibles pour l’enfant.

      Supposons que nous ayons un ChildComponent. L’idéal serez que vous puissiez utiliser @angular/cli pour générer votre composant :

      • ng generate component child --flat

      Ou alors, il vous faudra créer les fichiers child.component.css et child.component.html et l’ajouter manuellement à app.module.ts :

      app.module.ts

      import { ChildComponent } from './child.component';
      ...
      @NgModule({
        declarations: [
          AppComponent,
          ChildComponent
        ],
        ...
      })
      

      Nous allons ajouter une méthode whoAmI à ChildComponent qui renverra le message suivant :

      child.component.ts

      whoAmI() {
        return 'I am a child component!';
      }
      

      Ensuite, nous allons référencer le composant dans notre modèle d’application :

      app.component.html

      <app-child>child works!</app-child>
      

      Maintenant, nous pouvons appeler la méthode whoAmI de notre catégorie de composants parent avec ViewChild de la manière suivante :

      app.component.ts

      import {
        Component,
        ViewChild,
        AfterViewInit
      } from '@angular/core';
      import { ChildComponent } from './child.component';
      
      @Component({
        selector: 'app-root',
        templateUrl: './app.component.html',
        styleUrls: ['./app.component.css'],
      })
      export class AppComponent implements AfterViewInit {
        @ViewChild(ChildComponent) child: ChildComponent;
        ngAfterViewInit() {
          console.log(this.child.whoAmI()); // I am a child component!
        }
      }
      

      Lorsque vous visualiserez l’application dans un navigateur, le journal de la console s’affichera :

      Output

      I am a child component!

      Le composant parent a réussi à appeler la méthode whoAmI du composant enfant.

      Conclusion

      Vous avez appris à utiliser ViewChild pour accéder à une directive, à un composant enfant et à un élément DOM dans une catégorie de composants parent.

      Si la référence est remplacée de manière dynamique par un nouvel élément, ViewChild mettra à jour automatiquement sa référence.

      Dans le cas où vous souhaitez accéder à plusieurs composants enfant, utilisez plutôt ViewChildren.

      Si vous souhaitez en savoir plus sur Angular, consultez notre page thématique Angular pour des exercices et des projets de programmation.



      Source link

      Cómo acceder a las cámaras delantera y trasera con getUserMedia() de JavaScript


      Introducción

      Con HTML5 llegó la introducción de las API con acceso al hardware del dispositivo, incluyendo la API MediaDevices. Esta API proporciona acceso a dispositivos de entrada multimedia como audio y video.

      Con la ayuda de esta API, los desarrolladores pueden acceder a dispositivos de audio y video para transmitir y mostrar entradas de video en vivo en el navegador. En este tutorial, accederá a la entrada de video desde el dispositivo del usuario y la mostrará en el navegador usando el método getUserMedia:

      La API getUserMedia utiliza los dispositivos de entrada multimedia para producir un MediaStream. Este MediaStream contiene los tipos de multimedia solicitados, se trate de audio o video. Usando el flujo devuelto desde la API, las entradas de video pueden mostrarse en el navegador, lo cual es útil para la comunicación en tiempo real en el navegador.

      Cuando se utiliza junto con la API MediaStream Recording, puede grabar y guardar los datos multimedia capturados en el navegador. Esta API solo funciona en orígenes seguros como el resto de las APIs recién introducidas, pero también funciona en URLs localhost y archivo.

      Requisitos previos

      Este tutorial primero explicará los conceptos y demostrará ejemplos con Codepen. En el paso final, creará una entrada de video funcional para el navegador.

      Paso 1: Comprobar la compatibilidad del dispositivo

      Primero, verá cómo comprobar si el navegador del usuario es compatible con la API mediaDevices. Esta API existe en la interfaz navigator y contiene el estado actual y la identidad del agente del usuario. La comprobación se realiza con el siguiente código que puede pegarse en Codepen:

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

      Primero, esto comprueba si la API mediaDevices existe en navigator y, luego, comprueba si la API getUserMedia está disponible en mediaDevices. Si esto devuelve true, puede comenzar.

      Paso 2: Solicitar el permiso del usuario

      Tras confirmar que el navegador es compatible con getUserMedia, debe solicitar permiso para usar los dispositivos de entrada multimedia en el agente del usuario. Normalmente, una vez que un usuario concede permiso, se devuelve una Promise que se resuelve a un flujo multimedia. Esta Promise no se devuelve cuando el usuario deniega el permiso, lo que bloquea el acceso a estos dispositivos.

      Pegue la siguiente línea en Codepen para solicitar permiso:

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

      El objeto proporcionado como argumento para el método getUserMedia se denomina constraints. Esto determina a qué dispositivos de entrada multimedia está solicitando permiso de acceso. Por ejemplo, si el objeto contiene audio: true, se pedirá al usuario que conceda acceso al dispositivo de entrada de audio.

      Esta sección cubrirá el concepto general de constraints. El objeto constraints es un objeto MediaScreamConstraints que especifica los tipos de multimedia a solicitar y los requisitos de cada uno de esos tipos. Puede especificar requisitos para el flujo solicitado usando el objeto constraints, como la resolución del flujo a usar (front, back).

      Debe especificar un audio o video cuando se realiza la solicitud. Un NotFoundError será devuelto si los tipos multimedia solicitados no pueden encontrarse en el navegador del usuario.

      Si desea solicitar un flujo de video con una resolución 1280 x 720, puede actualizar el objeto constraints para que tenga este aspecto:

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

      Con esta actualización, el navegador intentará hacer coincidir los ajustes de calidad especificados para el flujo. Si el dispositivo de video no puede proporcionar la resolución, el navegador devolverá otras resoluciones disponibles.

      Para garantizar que el navegador devuelve una resolución que no sea inferior a la proporcionada, tendrá que usar la propiedad min. Aquí tiene cómo podrá actualizar el objeto constraints para incluir la propiedad min:

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

      Esto garantizará que la resolución del flujo se devolvió con al menos 1280 x 720. Si no se puede cumplir este requisito mínimo, la promesa se rechazará con un OverconstrainedError.

      El algunos casos es posible que esté preocupado sobre guardar los datos y necesite que el flujo no supere una resolución establecida. Esto puede ser útil cuando el usuario esté en un plan limitado. Para habilitar esta funcionalidad, actualice el objeto constraints para que contenga el campo max:

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

      Con estos ajustes, el navegador garantizará que el flujo de retorno no está por debajo de 1280 x 720 y no supera 1920 x 1080.

      Otros términos que pueden usarse son exact e ideal. El ajuste ideal normalmente se utiliza junto con las propiedades min y max para buscar el mejor ajuste posible más cercano a los valores ideales proporcionados.

      Puede actualizar las restricciones para usar la palabra clave ideal:

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

      Para indicar al navegador que utilice la cámara frontal o trasera (en móvil) en los dispositivos, puede especificar una propiedad facingMode en el objeto video:

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

      Este ajuste usará la cámara delantera siempre en todos los dispositivos. Para usar la cámara trasera en dispositivos móviles, puede alterar la propiedad facingMode a environment.

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

      Paso 4: Usar el método enumerateDevices

      Cuando se invoca el método enumerateDevices, devuelve todos los dispositivos multimedia de entrada disponibles en la PC del usuario.

      Con el método, puede proporcionar las opciones del usuario sobre las cuales usar el dispositivo multimedia de entrada para transmitir contenido de audio o video. Este método devuelve una Promise resuelta a una matriz MediaDeviceInfo que contiene información sobre cada dispositivo.

      En el siguiente snippet se muestra un ejemplo de cómo usar este método:

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

      Una respuesta de muestra para cada uno de los dispositivos tendría este aspecto:

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

      Nota: Una etiqueta no se devolverá a menos que exista un flujo disponible, o si el usuario ha concedido permisos de acceso al dispositivo.

      Paso 5: Mostrar el flujo de video en el navegador

      Ha repasado el proceso de solicitar y obtener acceso a los dispositivos multimedia, configurado las restricciones para incluir las resoluciones requeridas y seleccionado la cámara que necesitará para grabar video.

      Tras realizar estos pasos, al menos querrá ver si el flujo está funcionando según los ajustes configurados. Para garantizar esto, usará el elemento <video> para mostrar el flujo de video en el navegador.

      Como se ha mencionado antes, el método getUserMedia devuelve una Promesa que puede resolverse a un flujo. El flujo devuelto puede convertirse a una URL de objeto usando el método createObjectURL. Esta URL se establecerá como una fuente de video.

      Creará una demostración breve donde dejaremos al usuario elegir de su lista de dispositivos de video disponibles usando el método enumerateDevices.

      Este es un método navigator.mediaDevices. Enumera los dispositivos multimedia disponibles, como micrófonos y cámaras. Devuelve una Promesa que puede resolverse a una matriz de objetos que detalla los dispositivos multimedia disponibles.

      Cree un archivo index.html y actualice el contenido con el siguiente código.

      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>
      

      En el anterior snippet, ha configurado los elementos que necesitará y un par de controles para el video. Además se ha incluido un botón para hacer capturas de pantalla de la entrada de video actual.

      Ahora, vamos a crear el estilo de estos componentes.

      Cree un archivo style.css y copie los siguientes estilos en él. Bootstrap se incluyó para reducir la cantidad de CSS que necesitará escribir para poner en marcha los componentes.

      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;
      }
      

      El siguiente paso es añadir funcionalidad a la demostración. Con el método enumerateDevices, obtendrá los dispositivos de video disponibles y establecerlo como las opciones en el elemento seleccionado. Cree un archivo llamado script.js y actualícelo con el siguiente snippet:

      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();
      

      En el snippet anterior, suceden un par de cuestiones. Vamos a verlas:

      1. feather.replace(): este método invoca las instancias feather, que es un icono configurado para el desarrollo web.
      2. La variable constraints tiene la configuración inicial del flujo. Esto se ampliará para incluir el dispositivo multimedia que elija el usuario.
      3. getCameraSelection: esta función invoca el método enumarateDevices. A continuación, filtrará a través de la matriz desde la Promesa resuelva y seleccionará los dispositivos de entrada de video. Desde los resultados filtrados, cree <option> para el elemento <select>.
      4. La invocación del método getUserMedia sucede en la escucha onclick del botón play. Aquí, comprobará si este método es compatible con el navegador del usuario que inicia el flujo.
      5. A continuación, invocará la función startStream que asume el argumento constraints. Invoca el método getUserMedia con las restrictions proporcionadas. handleStream se invoca usando el flujo de la Promesa resuelta. Este método establece el flujo devuelto al srcObject del elemento de video.

      A continuación, añadirá escuchas a los controles de botón en la página para pausar, detener y hacer capturas de pantalla. Además, añadirá una escucha al elemento <select> para actualizar las restricciones del flujo con el dispositivo de video seleccionado.

      Actualice el archivo script.js con el siguiente código:

      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;
      

      Ahora, cuando abra el archivo index.html en el navegador, al hacer clic en el botón Play se iniciará el flujo.

      Aquí está la demostración completa:

      Conclusión

      Este tutorial introdujo la API getUserMedia. Es una adición interesante a HTML5 que facilita el proceso de capturar multimedia en la web.

      La API asume un parámetro constraints que puede usarse para configurar el acceso a los dispositivos de entrada de audio y video. También puede usarse para especificar la resolución de video necesaria para su aplicación.

      Puede ampliar la demo para dar al usuario una opción de guardar las capturas de pantalla tomadas, y grabar y almacenar datos de video y audio con la ayuda de la API MediaStream Recording.



      Source link