One place for hosting & domains

      getUserMedia

      Cara Mengakses Kamera Depan dan Belakang dengan getUserMedia() dari JavaScript


      Pengantar

      Kehadiran HTML5 memperkenalkan API dengan akses ke peranti keras perangkat, termasuk API MediaDevices. API ini memberikan akses ke perangkat masukan media seperti audio dan video.

      Dengan bantuan API ini, pengembang dapat mengakses perangkat audio dan video untuk mengalirkan dan menampilkan umpan video langsung di peramban. Dalam tutorial ini, Anda akan mengakses umpan video dari perangkat pengguna dan menampilkannya di peramban menggunakan metode getUserMedia.

      API getUserMedia memanfaatkan perangkat masukan media untuk menghasilkan MediaStream. MediaStream ini berisi jenis media yang diminta, baik audio atau video. Menggunakan aliran yang dikembalikan dari API, umpan video dapat ditampilkan di peramban, yang berguna untuk komunikasi waktu nyata di peramban.

      Ketika digunakan bersama API Rekaman MediaStream, Anda dapat merekam dan menyimpan data media yang ditangkap di peramban. API ini hanya bekerja di asal yang aman seperti API lainnya yang baru diperkenalkan, tetapi API ini juga bekerja di localhost dan URL berkas.

      Prasyarat

      Tutorial ini pertama-tama akan menjelaskan konsep dan mendemonstrasikan contoh dengan Codepen. Di langkah terakhir, Anda akan menciptakan umpan video yang berfungsi untuk peramban.

      Langkah 1 — Memeriksa Dukungan Perangkat

      Pertama-tama, Anda akan melihat cara memeriksa apakah peramban pengguna mendukung API mediaDevices. API ini ada di dalam antarmuka navigator dan berisi keadaan dan identitas saat ini dari agen pengguna. Pemeriksaan dilakukan dengan kode berikut yang dapat ditempelkan ke Codepen:

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

      Pertama-tama, ini memeriksa apakah API mediaDevices ada di dalam navigator, lalu memeriksa apakah API getUserMedia tersedia di dalam mediaDevices. Jika ini menampilkan true, Anda dapat memulai.

      Langkah 2 — Meminta Izin Pengguna

      Setelah mengonfirmasi dukungan peramban untuk getUserMedia, Anda perlu meminta izin untuk menggunakan perangkat masukan media pada agen pengguna. Biasanya, setelah pengguna memberikan izin, Promise diberikan yang terselesaikan menjadi aliran media. Promise ini tidak diberikan ketika izin ditolak oleh pengguna, yang memblokir akses ke perangkat ini.

      Tempelkan baris berikut ke Codepen untuk meminta izin:

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

      Objek yang diberikan sebagai argumen untuk metode getUserMedia disebut constraints. Ini menentukan perangkat masukan media yang Anda minta izinnya untuk diakses. Misalnya, jika objek berisi audio: true, pengguna akan diminta memberikan akses ke perangkat masukan audio.

      Bagian ini akan membahas tentang konsep umum dari constraints. Objek constraints adalah suatu objek MediaStreamConstraints yang menentukan jenis media yang diminta dan persyaratan dari setiap jenis media. Anda dapat menentukan persyaratan untuk aliran yang diminta menggunakan objek constraints, seperti resolusi dari aliran yang digunakan (front, back).

      Anda harus menentukan baik audio atau video saat membuat permintaan. NotFoundError akan dihasilkan jika jenis media yang diminta tidak dapat ditemukan di peramban pengguna.

      Jika Anda berniat meminta aliran video dari resolusi 1280 x 720, Anda dapat memperbarui objek constraints agar terlihat seperti ini:

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

      Dengan pembaruan ini, peramban akan mencoba mencocokkan pengaturan kualitas yang ditentukan untuk aliran tersebut. Jika perangkat video tidak dapat memberikan resolusi ini, peramban akan memberikan resolusi lain yang tersedia.

      Untuk memastikan peramban memberikan resolusi yang tidak lebih rendah dari yang disediakan sebelumnya, Anda harus memastikan untuk menggunakan properti min. Berikut ini adalah cara Anda dapat memperbarui objek constraints untuk menyertakan properti min:

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

      Ini akan memastikan bahwa resolusi aliran tersebut setidaknya akan sebesar 1280 x 720. Jika persyaratan minimum ini tidak dapat terpenuhi, promise akan ditolak dengan OverconstrainedError.

      Dalam beberapa kasus, Anda mungkin khawatir tentang menyimpan data dan perlu membuat aliran tidak melampaui resolusi yang ditetapkan. Ini dapat menjadi berguna ketika pengguna berada dalam paket yang terbatas. Untuk mengaktifkan fungsionalitas ini, perbarui objek constraints untuk memuat bidang max:

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

      Dengan pengaturan ini, peramban akan memastikan bahwa aliran yang diberikan tidak lebih kecil dari 1280 x 720 dan tidak melebihi 1920 x 1080.

      Ketentuan lain yang dapat digunakan mencakup exact dan ideal. Pengaturan ideal biasanya digunakan bersama properti min dan max untuk menemukan kemungkinan pengaturan terbaik yang paling dekat dengan nilai ideal yang disediakan.

      Anda dapat memperbarui constraints untuk menggunakan kata kunci ideal:

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

      Untuk memberi tahu peramban agar menggunakan kamera depan atau belakang (di perangkat mobil) pada perangkat, Anda dapat menentukan properti facingMode dalam objek video:

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

      Pengaturan ini akan menggunakan kamera yang selalu menghadap depan di semua perangkat. Untuk menggunakan kamera belakang di perangkat mobil, Anda dapat mengubah properti facingMode menjadi environment.

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

      Langkah 4 — Menggunakan Metode enumerateDevices

      Ketika metode enumerateDevices digunakan, metode ini merespons dengan semua perangkat media masukan yang ada dan tersedia di PC pengguna.

      Dengan metode ini, Anda dapat memberi pengguna opsi-opsi tentang perangkat media yang digunakan untuk mengalirkan konten audio atau konten video. Metode ini menghasilkan Promise yang terselesaikan menjadi larik MediaDeviceInfo yang berisi informasi tentang setiap perangkat.

      Contoh cara menggunakan metode ini ditampilkan dalam cuplikan kode di bawah ini:

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

      Respons sampel untuk setiap perangkat akan terlihat seperti yang berikut:

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

      Catatan: Label tidak akan diberikan kecuali ada aliran yang tersedia, atau jika pengguna telah memberikan izin akses perangkat.

      Langkah 5 — Menampilkan Aliran Video di Peramban

      Anda telah melewati proses meminta dan mendapatkan akses ke perangkat media, mengonfigurasi constraints untuk menyertakan resolusi yang diperlukan, dan memilih kamera yang Anda perlukan untuk merekam video.

      Setelah melewati semua langkah ini, setidaknya Anda ingin melihat apakah aliran tersebut bekerja sesuai dengan pengaturan yang dikonfigurasi. Untuk memastikan ini, Anda akan menggunakan elemen <video> untuk menampilkan aliran video di peramban.

      Seperti disebutkan sebelumnya, metode getUserMedia memberikan Promise yang dapat diselesaikan menjadi aliran. Aliran yang dihasilkan dapat dikonversi menjadi URL objek dengan metode createObjectURL. URL ini akan diatur sebagai sumber video.

      Anda akan menciptakan demo singkat yang membiarkan pengguna memilih dari daftar perangkat video mereka yang tersedia, yang menggunakan metode enumerateDevices.

      Ini adalah metode navigator.mediaDevices. Ini membuat daftar perangkat media yang tersedia, seperti mikrofon dan kamera. Ini memberikan Promise yang dapat diselesaikan menjadi larik objek yang memerinci perangkat media yang tersedia.

      Ciptakan berkas index.html dan perbarui konten dengan kode di bawah ini:

      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>
      

      Dalam cuplikan kode di atas, Anda telah menyiapkan elemen yang Anda perlukan dan beberapa kontrol untuk video. Yang juga disertakan adalah tombol untuk mengambil tangkapan layar dari umpan video saat ini.

      Sekarang, mari kita hias komponen ini sedikit.

      Ciptakan berkas style.css dan salin gaya berikut ke dalamnya. Bootstrap disertakan untuk mengurangi jumlah CSS yang harus ditulis agar komponennya berjalan.

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

      Langkah selanjutnya adalah menambahkan fungsionalitas pada demo. Dengan menggunakan metode enumerateDevices, Anda akan mendapatkan perangkat video yang tersedia dan mengaturnya sebagai opsi di dalam elemen pilihan. Ciptakan berkas bernama script.js dan perbarui dengan cuplikan kode berikut:

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

      Dalam cuplikan kode di atas, ada beberapa hal yang terjadi. Mari kita uraikan:

      1. feather.replace(): metode ini memanggil instans feather, yang merupakan ikon yang diatur untuk pengembangan web.
      2. Variabel constraints menyimpan konfigurasi awal untuk aliran. Ini akan diperluas untuk menyertakan perangkat media yang dipilih pengguna.
      3. getCameraSelection: fungsi ini memanggil metode enumerateDevices. Kemudian, Anda memfilter larik dari Promise yang terselesaikan dan memilih perangkat masukan video. Dari hasil yang terfilter, Anda membuat <option> untuk elemen <select>.
      4. Memanggil metode getUserMedia terjadi di dalam pendengar onclick dari tombol play. Di sini, Anda akan memeriksa apakah metode ini didukung oleh peramban pengguna sebelum memulai aliran.
      5. Selanjutnya, Anda akan memanggil fungsi startStream yang mengambil argumen constraints. Ini memanggil metode getUserMedia dengan constraints yang disediakan. handleStream dipanggil menggunakan aliran dari Promise yang terselesaikan. Metode ini mengatur aliran yang diberikan ke srcObject dari elemen video.

      Selanjutnya, Anda akan menambahkan pendengar ke tombol kontrol pada laman untuk melakukan pause (jeda), stop (berhenti), dan mengambil screenshots (tangkapan layar). Juga, Anda akan menambahkan pendengar ke elemen <select> untuk memperbarui constraints aliran dengan perangkat video yang dipilih.

      Perbarui berkas script.js dengan kode di bawah ini:

      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;
      

      Sekarang, saat Anda membuka berkas index.html di peramban, mengeklik tombol Play akan memulai aliran.

      Berikut adalah demo yang lengkap:

      https://codepen.io/chrisbeast/pen/ebYwpX

      Kesimpulan

      Tutorial ini memperkenalkan API getUserMedia. Ini adalah tambahan yang menarik untuk HTML5 yang mempermudah proses penangkapan media di web.

      API menggunakan parameter (constraints) yang dapat digunakan untuk mengonfigurasi akses ke perangkat masukan audio dan video. Ini juga dapat digunakan untuk menentukan resolusi video yang diperlukan untuk aplikasi Anda.

      Anda dapat memperpanjang demo lebih lanjut untuk memberi pengguna dengan suatu opsi untuk menyimpan tangkapan layar yang diambil, begitu juga dengan merekam dan menyimpan data video serta audio dengan bantuan dari API Rekaman MediaStream.



      Source link

      JavaScriptの getUserMedia() を使用してフロントカメラとリアカメラにアクセスする方法


      はじめに

      HTML5 では、MediaDevices API など、デバイスハードウェアにアクセスできる API を導入しています。この API により、オーディオやビデオなどのメディア入力デバイスへのアクセスができます。

      この API によって、開発者はオーディオやビデオデバイスにアクセスし、ブラウザでライブビデオフィードをストリーミングして表示できます。このチュートリアルでは、ユーザーのデバイスからビデオフィードにアクセスし、getUserMedia メソッドを使用してブラウザに表示します。

      getUserMedia API は、メディア入力デバイスを利用して MediaStream を生成します。MediaStream は、オーディオかビデオであるかに関わらず、要求されたメディアタイプを含みます。API から返されたストリームを利用して、ブラウザ上にビデオフィードを表示させることができるので、ブラウザ上でのリアルタイム通信に便利です。

      MediaStream Recording API と一緒に使用する場合、ブラウザ上でキャプチャしたメディアデータを記録して保存することができます。この API は、新しく導入された他の API と同様にセキュアな発行元でのみ動作しますが、ローカルホストやファイル URL でも動作します。

      前提条件

      • JavaScript の基本知識。JavaScript が初めての方は、How To Code in JavaScript(JavaScriptを使ってコーディングする方法)シリーズをチェックしてみてください。

      このチュートリアルでは、最初に概念を説明し、CodePenを使った例のデモをします。最後のステップでは、ブラウザ用に動作するビデオフィードを作成します。

      ステップ1 — デバイスがサポートされているか確認する

      まず、ユーザーのブラウザが mediaDevices API をサポートしているか確認する方法を説明します。この API はnavigator インターフェイス内に存在し、ユーザーエージェントの現在の状態と ID を含んでいます。チェックは、CodePen に貼り付けることができる、次のコードを使用して行います。

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

      まず、mediaDevices API がナビゲーター内に存在するかどうかをチェックし、次に、getUserMedia API が mediaDevices 内で使用可能かどうかを確認します。trueを返す場合は、開始できます。

      ステップ2 — ユーザーの許可を要求する

      ブラウザによる getUserMedia のサポートを確認した後、ユーザーエージェントでメディア入力デバイスを使用するための許可を要求する必要があります。通常、ユーザーが許可した後、Promise が返され、メディアストリームへの解決をします。この Promise は、ユーザーによって許可が拒否された場合には返されず、これらのデバイスへのアクセスがブロックされます。

      次の行を Codepen に貼り付けして、許可を要求します。

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

      getUserMedia メソッドの引数として指定されたオブジェクトは、constraints(制約)と呼ばれます。これにより、アクセス許可を要求しているメディア入力デバイスのうち、どのデバイスにアクセスするかを決定します。例えば、オブジェクトに audio:true が含まれている場合、ユーザーはオーディオ入力デバイスへのアクセスを許可するように求められます。

      ステップ3 — メディアの Constraints (制約)を理解する

      このセクションでは、contraints(制約)の一般的な概念について説明します。constraints オブジェクトは、要求するメディアのタイプと各メディアタイプの要件を指定するMediaStreamConstraints オブジェクトです。constraints オブジェクトを使用して、(前面背面)を使用するストリームの解像度など、要求されたストリームの要件を指定できます。

      リクエストを行うときは、オーディオまたはビデオのいずれかを指定する必要があります。要求されたメディアタイプがユーザーのブラウザで見つからない場合、NotFoundError が返されます。

      1280 x 720 の解像度のビデオストリームをリクエストする場合は、constraints オブジェクトを次のように更新できます。

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

      このアップデートでは、ブラウザは、ストリームに指定された品質設定を一致させようとします。このビデオデバイスで、この解像度をサポートしていない場合、ブラウザは他の利用可能な解像度を返します。

      ブラウザがサポートする解像度以上の解像度を返すようにするには、min プロパティを使用する必要があります。constraints オブジェクトを更新して、min プロパティを含める方法は、次のとおりです。

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

      これにより、返されるストリーム解像度は、少なくとも1280 x720になります。この最小要件を満たせない場合、promise はOverconstrainedError で拒否されます。

      場合によっては、データの保存に配慮して、ストリームが設定された解像度を超えないようにする必要があります。これは、ユーザーが限定プランを利用している場合に便利です。この機能を有効にするには、constraints オブジェクトを更新してmaxフィールドを含めます。

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

      これらの設定により、ブラウザは、返されるストリームが 1280 x 720 を下回ったり、1920 x 1080 を超えたりしないようにします。

      使用できる他の条件には、exactideal があります。ideal の設定では、通常、minmax プロパティと共に使用され、指定された ideal 値に最も近い最良の設定を見つけます。

      この constraints を更新して、ideal キーワードを使用できます。

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

      ブラウザに、(モバイルの場合)デバイスの前面または背面カメラを使用するように指示するには、facingMode プロパティを、video オブジェクトで指定します。

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

      この設定では、すべてのデバイスで、常に前面カメラを使用するようになります。モバイルデバイスでバックカメラを利用するには、facingMode プロパティを environment に変更します。

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

      ステップ4 – enumerateDevices メソッドを使用する

      enumerateDevices メソッドが呼び出されると、ユーザーの PC で利用可能な入力メディアデバイスをすべて返します。

      この方法では、入力メディアデバイスのユーザオプションを指定して、オーディオまたはビデオコンテンツのストリーミングに使用することができます。このメソッドは、各デバイスに関する情報を含む MediaDeviceInfo 配列に対して解決された Promise を返します。

      最後のステップでは、ブラウザ用に動作するビデオフィードを作成します。

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

      各デバイスの応答例は次のようになります。

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

      注意:利用可能なストリームが利用可能でない限り、またはユーザーがデバイスアクセス許可を付与していない限り、ラベルは返されません。

      ステップ5 – ブラウザにビデオストリームを表示する

      メディアデバイスへのアクセスを要求して取得するプロセスを経て、必要な解像度などの constraints (制約)を設定し、ビデオ録画に必要なカメラを選択をします。

      これらのステップをすべて行った後、設定された構成に基づいてストリームが配信されているかどうかを確認することができます。これを確認するために、<video> 要素を使用してブラウザにビデオストリームを表示します。

      前述したように、getUserMedia メソッドは、ストリームへの解決ができる Promise を返します。返されたストリームは、createObjectURL メソッドを使用してオブジェクト URL に変換することができます。この URL は、ビデオソースとして設定されます。

      enumerateDevices メソッドを使用して、利用可能なビデオデバイスのリストからユーザーが選択できる短いデモを作成します。

      これは navigator.mediaDevices メソッドです。マイクやカメラなど、利用可能なメディアデバイスが一覧表示されます。使用可能なメディアデバイスの詳細を示すオブジェクトの配列に、解決可能な Promise を返します。

      index.html ファイルを作成し、次のコードでコンテンツを更新します。

      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>
      

      上記のスニペットでは、必要な要素とビデオのいくつかのコントロールを設定しました。現在のビデオフィードのスクリーンショットを撮るためのボタンも含まれています。

      それでは、これらのコンポーネントを少しスタイルアップしましょう。

      style.css ファイルを作成し、次のスタイルをそのファイルにコピーします。Bootstrap(ブートストラップ) が、コンポーネントを動作させるために作成する必要のある CSS の量を減らすために含まれていました。

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

      次のステップでは、デモに機能を追加します。enumerateDevices メソッドを使用して、使用可能なビデオデバイスを取得し、select 要素内のオプションとして設定します。script.js というファイルを作成し、次のスニペットで更新します。

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

      上記のスニペットでは、いくつかのことが起こっています。それらを分解しましょう。

      1. feather.replace():このメソッド呼び出しは、Web 開発用のアイコンセットである feather をインスタンス化します。
      2. constraints 変数は、ストリームの初期構成を保持します。これにより、ユーザーが選択したメディアデバイスを含むように拡張されます。
      3. getCameraSelection:この関数はenumerateDevices メソッドを呼び出します。次に、解決された Promise から配列をフィルタリングし、ビデオ入力デバイスを選択します。フィルタされた結果から、<select> 要素の<option> を作成します。
      4. getUserMedia メソッドの呼び出しは、再生ボタンの onclick リスナー内で行われます。ここでは、ストリームを開始する前に、このメソッドがユーザーのブラウザでサポートされているかどうかを確認します。
      5. 次に、constraints 引数を取る startStream 関数を呼び出します。提供されたconstraints を使用して getUserMedia メソッドを呼び出します。handleStream は、解決された Promise からのストリームを使用して呼び出されます。このメソッドは、返されたストリームをビデオ要素の srcObject に設定します。

      次に、ページのボタンコントロールに、クリックリスナーを追加して、一時停止停止スクリーンショットを撮ります。また、リスナーを <select> 要素に追加して、選択したビデオデバイスのストリーム constraints を更新します。

      次のコードで script.js ファイルを更新します。

      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;
      

      ここで、ブラウザで index.html ファイルを開いて、再生ボタンをクリックするとストリームが開始します。

      以下が完全なデモです。

      https://codepen.io/chrisbeast/pen/ebYwpX

      まとめ

      このチュートリアルでは、getUserMedia API を紹介しました。これは、Web 上のメディアをキャプチャするプロセスを容易にする、HTML5への興味深い追加機能です。

      API は、オーディオおよびビデオ入力デバイスへのアクセスを構成するために使用できるパラメーター(constraints)を取ります。また、アプリケーションに必要なビデオ解像度を指定するためにも使用できます。

      デモをさらに拡張して、MediaStream Recording API を使用して、撮影したスクリーンショットを保存したり、ビデオやオーディオデータを記録・保存したりするオプションをユーザーに提供できます。



      Source link

      Zugriff auf Front- und Rück-Kameras mit getUserMedia() von JavaScript


      Einführung

      Mit HTML5 kam die Einführung von APIs mit Zugriff auf die Geräte-Hardware, einschließlich der API MediaDevices. Diese API ermöglicht den Zugriff auf Medieneingabegeräte wie Audio und Video.

      Mit Hilfe dieser API können Entwickler auf Audio- und Videogeräte zugreifen, um Live-Video-Feeds zu streamen und im Browser anzuzeigen. In diesem Tutorial greifen Sie über das Gerät des Benutzers auf den Video-Feed zu und zeigen es mit der Methode getUserMedia im Browser an.

      Die API getUserMedia verwendet die Medieneingabegeräte, um einen Medien-Stream zu erstellen. Dieser Medien-Stream enthält die angeforderten Medientypen, egal ob Audio oder Video. Mit dem von der API zurückgegebenen Stream können Video-Feeds im Browser angezeigt werden, wobei dies für die Echtzeit-Kommunikation im Browser nützlich ist.

      Bei gemeinsamer Verwendung mit der API MediaStream Recording können Sie Mediendaten aufzeichnen und speichern, die im Browser erfasst wurden. Diese API funktioniert wie die übrigen neu eingeführten APIs nur mit sicherer Herkunft, aber sie funktioniert auch für localhost– und Datei-URLs.

      Voraussetzungen

      In diesem Tutorial werden zunächst Konzepte erklärt und Beispiele mit Codepen demonstriert. Im letzten Schritt erstellen Sie einen funktionierenden Video-Feed für den Browser.

      Schritt 1 — Überprüfen der Geräteunterstützung

      Zuerst erfahren Sie, wie Sie überprüfen können, ob der Browser des Benutzers die API mediaDevices unterstützt. Diese API ist innerhalb der Navigator-Schnittstelle vorhanden und enthält den aktuellen Status und die Identität des Benutzeragenten. Die Überprüfung wird mit dem folgenden Code durchgeführt, der in Codepen eingefügt werden kann:

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

      Zuerst wird geprüft, ob die API mediaDevices innerhalb des navigator vorhanden ist und dann wird geprüft, ob die API getUserMedia innerhalb der mediaDevices verfügbar ist. Wenn dies true zurückgibt, können Sie beginnen.

      Schritt 2 — Anfordern der Benutzerberechtigung

      Nachdem Sie die Unterstützung des Browsers für getUserMedia bestätigt haben, müssen Sie die Berechtigung zur Verwendung der Medieneingabegeräte auf dem Benutzeragenten anfordern. Normalerweise wird, nachdem ein Benutzer die Berechtigung erteilt hat, ein Promise zurückgegeben, das zu einem Medien-Stream aufgelöst wird. Dieses Promise wird nicht zurückgegeben, wenn die Berechtigung vom Benutzer verweigert wird, wodurch der Zugriff auf diese Geräte blockiert wird.

      Fügen Sie die folgende Zeile in Codepen ein, um die Berechtigung anzufordern:

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

      Das Objekt, das als Argument für die Methode getUserMedia bereitgestellt wurde, wird als constraints (Beschränkungen) bezeichnet. Dadurch wird festgelegt, für welche der Medieneingabegeräte Sie Zugriffsberechtigungen anfordern. Wenn das Objekt beispielsweise audio: true enthält, wird der Benutzer aufgefordert, Zugriff auf das Audio-Eingabegerät zu gewähren.

      Schritt 3 — Verstehen von Medienbeschränkungen

      Dieser Abschnitt behandelt das allgemeine Konzept von constraints. Das Objekt constraints ist ein MediaStreamConstraints-Objekt, das die anzufordernden Medientypen und die Anforderungen jedes Medientyps angibt. Mit dem Objekt constraints können Sie Anforderungen für den angeforderten Stream angeben, wie beispielsweise die Auflösung des zu verwendenden Streams (front, back).

      Sie müssen entweder audio oder video angeben, wenn Sie die Anfrage stellen. Ein NotFoundError wird zurückgegeben, wenn die angeforderten Medientypen im Browser des Benutzers nicht gefunden werden können.

      Wenn Sie beabsichtigen, einen Video-Stream mit einer Auflösung von 1280 × 720 anzufordern, können Sie das Objekt constraints so aktualisieren, dass es wie folgt aussieht:

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

      Mit dieser Aktualisierung versucht der Browser, die angegebenen Qualitätseinstellungen für den Stream zu übernehmen. Wenn das Videogerät diese Auflösung nicht liefern kann, gibt der Browser andere verfügbare Auflösungen zurück.

      Um sicherzustellen, dass der Browser eine Auflösung zurückgibt, die nicht niedriger als die vorgegebene Auflösung ist, müssen Sie die Eigenschaft min verwenden. Nachfolgend wird gezeigt, wie Sie das Objekt constraints aktualisieren können, um die Eigenschaft min einzuschließen:

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

      Dadurch wird sichergestellt, dass die zurückgegebene Stream-Auflösung mindestens 1280 × 720 beträgt. Wenn diese Mindestanforderungen nicht erfüllt werden kann, wird das Promise mit einem OverconstrainedError abgelehnt.

      In einigen Fällen haben Sie eventuell Bedenken hinsichtlich der Datenspeicherung und möchten, dass der Stream eine festgelegte Auflösung nicht überschreitet. Dies kann sich als nützlich erweisen, wenn der Benutzer einen begrenzten Datenplan verwendet. Um diese Funktionalität zu aktivieren, aktualisieren Sie das Beschränkungsobjekt, damit es ein Feld max enthält:

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

      Mit diesen Einstellungen stellt der Browser sicher, dass der zurückgegebene Stream nicht unter 1280 × 720 liegt und 1920 × 1080 nicht überschreitet.

      Andere Begriffe, die verwendet werden können, sind exact und ideal. Die Einstellung ideal wird typischerweise zusammen mit den Eigenschaften min und max verwendet, um die bestmögliche Einstellung zu finden, die den idealen Werten am nächsten kommt.

      Sie können die Beschränkungen zur Verwendung des Schlüsselworts ideal aktualisieren:

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

      Um den Browser anzuweisen, die vordere und hintere (bei mobilen Geräten) Kamera von Geräten verwenden, können Sie eine Eigenschaft facingMode im Objekt video angeben:

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

      Diese Einstellung verwendet die nach vorn gerichtete Kamera jederzeit bei allen Geräten. Um die Rückseitenkamera von mobilen Geräten zu verwenden, können Sie die Eigenschaft facingMode zu environment ändern.

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

      Schritt 4 — Verwenden der Methode enumerateDevices

      Wird die Methode enumerateDevices aufgerufen, gibt sie alle verfügbaren Eingabemediengeräte zurück, die auf dem PC des Benutzers verfügbar sind.

      Mit der Methode können Sie den Benutzern Optionen zur Verfügung stellen, welches Eingabemediengerät für das Streaming von Audio- oder Videoinhalten verwendet werden soll. Diese Methode gibt ein Promise aufgelöst an ein Array MediaDeviceInfo zurück, das Informationen zu jedem Gerät enthält.

      Ein Beispiel für die Verwendung dieser Methode wird im nachstehenden Ausschnitt gezeigt:

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

      Eine Beispielantwort für jedes der Geräte würde wie folgt aussehen:

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

      Anmerkung: Ein Label wird nur dann zurückgegeben, wenn ein verfügbarer Stream verfügbar ist oder wenn der Benutzer Zugriffsberechtigungen für Geräte erteilt hat.

      Schritt 5 — Anzeigen des Video-Streams im Browser

      Sie haben den Prozess der Anfrage und des Zugriffs auf die Mediengeräte durchlaufen, Einschränkungen für die erforderlichen Auflösungen konfiguriert und die Kamera ausgewählt, die Sie für die Videoaufzeichnung benötigen.

      Nach all diesen Schritten wollen Sie zumindest sehen, ob der Stream anhand der konfigurierten Einstellungen bereitgestellt wird. Um dies sicherzustellen, verwenden Sie das Element <video> zur Anzeige des Video-Streams im Browser.

      Wie bereits erwähnt, gibt die Methode getUserMedia ein Promise zurück, das in einen Stream aufgelöst werden kann. Der zurückgegebene Stream kann mit der Methode createObjectURL in eine Objekt-URL konvertiert werden. Diese URL wird als Videoquelle festgelegt.

      Sie werden eine kurze Demo erstellen, bei der wir den Benutzer mit der Methode enumerateDevices aus der Liste der verfügbaren Videogeräte auswählen lassen.

      Dies ist eine Methode navigator.mediaDevices. Sie listet die verfügbaren Mediengeräte wie Mikrofone und Kameras auf. Sie gibt ein auflösbares Promise an ein Array von Objekten zurück, das die verfügbaren Mediengeräte detailliert auflistet.

      Erstellen Sie eine Datei index.html und aktualisieren Sie den Inhalt mit dem nachstehenden Code:

      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>
      

      Im obigen Ausschnitt haben Sie die von Ihnen benötigten Elemente und einige Steuerelemente für das Video eingerichtet. Außerdem ist eine Schaltfläche für die Aufnahme von Screenshots des aktuellen Video-Feeds enthalten.

      Lassen Sie uns diese Komponenten ein wenig stylen.

      Erstellen Sie eine Datei style.css und kopieren Sie die folgenden Stile in sie. Bootstrap wurde hinzugefügt, um die Menge an CSS zu reduzieren, die Sie schreiben müssen, um die Komponenten in Gang zu bringen.

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

      Der nächste Schritt besteht darin, der Demo Funktionalität hinzuzufügen. Mit der Methode enumerateDevices erhalten Sie die verfügbaren Videogeräte und legen sie als Optionen innerhalb des Elements „select“ fest. Erstellen Sie eine Datei namens script.js und aktualisieren Sie sie mit dem folgenden Ausschnitt:

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

      Im obigen Ausschnitt sind einige Dinge zu erkennen. Schlüsseln wir diese auf:

      1. feather.replace(): dieser Methodenaufruf instanziiert feather, wobei es sich um einen Symbolsatz für die Webentwicklung handelt.
      2. Die Variable constraints enthält die anfängliche Konfiguration für den Stream. Diese wird erweitert, um das vom Benutzer gewählte Mediengerät einzubeziehen.
      3. getCameraSelection: diese Funktion ruft die Methode enumerateDevices auf. Dann filtern Sie durch das Array aus dem aufgelösten Promise und wählen Video-Eingabegeräte aus. Aus den gefilterten Ergebnissen erstellen Sie <option> für das Element <select>.
      4. Der Aufruf der Methode getUserMedia erfolgt innerhalb des Listeners onclick der Schaltfläche play. Hier überprüfen Sie vor dem Start des Streams, ob diese Methode vom Browser des Benutzers unterstützt wird.
      5. Als Nächstes rufen Sie die Funktion startStream auf, die ein Argument constraints benötigt. Sie ruft die Methode getUserMedia mit den angegebenen constraints auf. handleStream wird mit dem Stream aus dem aufgelösten Promise aufgerufen. Diese Methode setzt den zurückgegebenen Stream auf das srcObject des Videoelements.

      Als Nächstes fügen Sie den Schaltflächen-Steuerelementen auf der Seite Klick-Listener für pause, stop und zur Aufnahme von screenshots hinzu. Außerdem fügen Sie dem Element <select> einen Listener hinzu, um die Stream-Beschränkungen mit dem ausgewählten Videogerät zu aktualisieren.

      Aktualisieren Sie die Datei script.js mit dem nachstehenden Code:

      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;
      

      Wenn Sie jetzt die Datei index.html im Browser öffnen, wird das Anklicken der Schaltfläche Play den Stream starten.

      Hier ist eine vollständige Demo:

      Zusammenfassung

      In diesem Tutorial wurde die API getUserMedia vorgestellt. Sie ist eine interessante Ergänzung zu HTML5, die den Prozess der Erfassung von Medien im Web erleichtert.

      Die API verwendet einen Parameter (constraints), mit dem der Zugriff auf Audio- und Video-Eingabegeräte konfiguriert werden kann. Sie kann auch verwendet werden, um die für Ihre Anwendung erforderliche Videoauflösung anzugeben.

      Sie können die Demo weiter erweitern, um dem Benutzer eine Option zu geben, die aufgenommenen Screenshots zu speichern, sowie Video- und Audiodaten mit Hilfe der API MediaStream Recording aufzuzeichnen und zu speichern.



      Source link