One place for hosting & domains

      JavaScript

      JavaScript の配列項目から反復するための .map() の使用方法


      はじめに

      古典的な forloop からforEach()メソッドまで、JavaScript のデータセットから反復するためにさまざまなテクニックとメソッドを使用します。最も一般的なメソッドの1つは、.map() メソッドです。.map() は、親配列内の各項目に特定の関数を呼び出すことから配列を作成します。配列の呼び出しだけを変化させる非変異メソッドに反するものとして、.map( ) は新しい配列を作成する非変異メソッドです。

      このメソッドには、配列で作業するときに多くの用途がある場合があります。このチュートリアルでは、JavaScript の .map() の 4 つの注目に値する使用を見てみましょう。配列要素の呼び出し、文字列を配列に変換、ライブラリのレンダリングリスト、配列オブジェクトの再フォーマットを行います。

      前提条件

      このチュートリアルではコーディングは必要ありませんが、例とともに次のものに興味がある場合、Node.js REPL またはブラウザ開発者ツールを使用することもできます。

      ステップ 1 — 配列内の各項目の関数を呼び出す

      .map() はコールバック関数を引数の 1 つとして受け入れ、その関数の重要なパラメータは関数によって処理される項目の現在の値です。これは必要なパラメータです。このパラメータにより、配列内の各項目を変更し、新しい関数を作成できます。

      次に例を示します。

      const sweetArray = [2, 3, 4, 5, 35]
      const sweeterArray = sweetArray.map(sweetItem => {
          return sweetItem * 2
      })
      
      console.log(sweeterArray)
      

      この出力はコンソールにログインします。

      Output

      [ 4, 6, 8, 10, 70 ]

      これにより、さらに簡素化できます。

      // create a function to use
      const makeSweeter = sweetItem => sweetItem * 2;
      
      // we have an array
      const sweetArray = [2, 3, 4, 5, 35];
      
      // call the function we made. more readable
      const sweeterArray = sweetArray.map(makeSweeter);
      
      console.log(sweeterArray);
      

      同様の出力はコンソールにログインします。

      Output

      [ 4, 6, 8, 10, 70 ]

      sweetArray.map(makeSweeter) のようなコードがあなたのコードを少し読みやすくします。

      ステップ 2 — 文字列を配列に変換

      .map() は配列プロトタイプに属することが知られています。このステップでは、文字列を使用して配列に変換します。ここでは文字列の機能のメソッドを開発しません。むしろ、特別な.call() メソッドを使用します。

      JavaScript のすべてはオブジェクトであり、メソッドはこうしたオブジェクトに付随する関数です。.call() により、別のオブジェクトのコンテキストを使用できます。したがって、配列の .map() のコンテキストを文字列にコピーします。

      .call() は、使用するコンテキストの引数と元の関数の引用のパラメータを渡すことができます。

      次に例を示します。

      const name = "Sammy"
      const map = Array.prototype.map
      
      const newName = map.call(name, eachLetter => {
          return `${eachLetter}a`
      })
      
      console.log(newName)
      

      この出力はコンソールにログインします。

      Output

      • [ "Sa", "aa", "ma", "ma", "ya" ]

      ここでは、文字列の .map() のコンテキストを使用して、.map() が予期する関数の引数を渡しています。

      この関数は、文字列の .split() メソッドのようなもので、配列に戻す前に各文字列の文字が変更できるだけです。

      ステップ 3 — JavaScript ライブラリのレンダリングリスト

      React のような JavaScript ライブラリは、リストの項目をレンダリングするために .map() を使用します。しかし、.map() メソッドは JSX 構文に含まれるため、これは JSX 構文を必要とします。

      React コンポーネントの例は次のとおりです。

      import React from "react";
      import ReactDOM from "react-dom";
      
      const names = ["whale", "squid", "turtle", "coral", "starfish"];
      
      const NamesList = () => (
        <div>
          <ul>{names.map(name => <li key={name}> {name} </li>)}</ul>
        </div>
      );
      
      const rootElement = document.getElementById("root");
      ReactDOM.render(<NamesList />, rootElement);
      

      これは、React のステートレスなコンポーネントであり、リストにより div をレンダリングします。各リスト項目は、最初に作成された名前の配列を繰り返すため、.map() を使用してレンダリングされます。このコンポーネントは、rootID を使用して DOM 要素の ReactDOM を使用します。

      ステップ 4 — 配列オブジェクトの再フォーマット

      .map() は、配列のオブジェクトを反復するために使用し、従来の配列に似た方法で、各オブジェクトの内容を変更し新しい配列を戻します。この変更は、コールバック関数で戻されるものに基づいて行われます。

      次に例を示します。

      const myUsers = [
          { name: 'shark', likes: 'ocean' },
          { name: 'turtle', likes: 'pond' },
          { name: 'otter', likes: 'fish biscuits' }
      ]
      
      const usersByLikes = myUsers.map(item => {
          const container = {};
      
          container[item.name] = item.likes;
          container.age = item.name.length * 10;
      
          return container;
      })
      
      console.log(usersByLikes);
      

      この出力はコンソールにログインします。

      Output

      [ {shark: "ocean", age: 50}, {turtle: "pond", age: 60}, {otter: "fish biscuits", age: 50} ]

      ここでは、ブラケットとドット表記を使用して、配列の各オブジェクトを修正します。このユースケースは、フロントエンドアプリケーションで保存または解析する前に、受信したデータを処理または縮約するために使用できます。

      まとめ

      このチュートリアルでは、JavaScript の .map() メソッドの 4 つの使用を見てきました。他のメソッドと組み合わせて、.map() の機能は拡張できます。詳しくは、JavaScript: 反復メソッドの記事にある配列メソッドの使用方法を参照してください。



      Source link

      Empat Metode untuk Mencari di Dalam Larik di JavaScript


      Dalam JavasScript, ada banyak cara yang berguna untuk menemukan item di Larik (Array). Anda selalu dapat kembali menggunakan perulangan for dasar, tetapi dengan ES6+, ada banyak metode untuk mengulang data larik dan menemukan apa yang Anda perlukan dengan mudah.

      Dengan begitu banyak metode berbeda, manakah yang Anda gunakan dan dalam kasus apa? Misalnya, saat mencari di dalam larik, apakah Anda ingin tahu jika elemennya ada di dalam larik? Apakah Anda memerlukan indeks dari elemen atau elemennya itu sendiri?

      Dengan setiap metode berbeda yang akan kita bahas, penting untuk memahami bahwa semua itu adalah metode bawaan pada Array.prototype. Itu berarti Anda hanya perlu menambatkannya ke larik apa pun dengan notasi titik. Itu juga berarti metode ini tidak tersedia pada objek atau hal lainnya selain Larik (meskipun ada tumpang tindih dengan String).

      Kita akan membahas metode-metode Larik berikut:

      includes

      const alligator = ["thick scales", 80, "4 foot tail", "rounded snout"];
      
      alligator.includes("thick scales"); // returns true
      

      Metode .includes() menghasilkan nilai boolean dan sempurna untuk memberi tahu Anda jika suatu elemen ada di dalam larik atau tidak. Ini memberikan jawaban true atau false yang sederhana. Ini adalah sintaks dasarnya:

      arr.includes(valueToFind, [fromIndex]);
      

      Kini, seperti yang Anda lihat dalam contoh, kita hanya memiliki satu parameter – valueToFind. Ini adalah nilai untuk dicocokkan dalam larik. fromIndex opsional adalah angka, yang mengindikasikan dari indeks apa Anda ingin untuk memulai pencarian (asali adalah 0, yang berarti keseluruhan larik akan dicari). Jadi, karena dalam contoh kita item ‘thick scales’ berada di indeks 0, yang berikut ini akan menjadi salah: alligator.includes('thick scales', 1); karena pencarian dimulai dari indeks 1 dan seterusnya.

      Sekarang, ada beberapa hal penting yang harus diperhatikan. Metode .includes() ini menggunakan perbandingan yang ketat. Itu berarti, dari contoh di atas, yang berikut ini akan menghasilkan false: alligator.includes('80'); Itu karena meskipun 80 == '80' adalah benar, 80 === '80' adalah salah – jenis berbeda tidak akan berhasil melewati perbandingan yang ketat.

      find

      Bagaimana .find() berbeda dari metode includes()? Jika dalam contoh kita hanya mengubah teks “includes” menjadi “find”, kita akan mendapat pesan kesalahan ini:

      Uncaught TypeError: thick scales is not a function
      

      Itu karena metode pencarian ini membutuhkan fungsi yang harus dimasukkan. Itu karena metode pencarian tidak hanya akan menggunakan operator perbandingan sederhana seperti yang dilakukan “includes()”. Alih-alih, ini akan memasukkan setiap elemen ke dalam fungsi dan melihat apakah itu menghasilkan true atau false. Jadi, meskipun ini berfungsi: alligator.find(() => 'thick scales');, Anda mungkin ingin menempatkan operator perbandingan Anda di dalam fungsi agar mendapatkan hasil yang relevan.

      const alligator = ["thick scales", 80, "4 foot tail", "rounded snout"];
      
      alligator.find(el => el.length < 12); // returns '4 foot tail'
      

      Fungsi sederhana dalam metode pencarian kita ini mencari setiap elemen dari larik, dengan alias dari ‘el’ yang kita berikan, dan berhenti ketika menemukan elemen pertama yang benar. Dalam kasus kita, true (benar) berarti memiliki properti panjang kurang dari 12 (angka tidak memiliki properti panjang). Anda tentu dapat membuat fungsi ini serumit mungkin sesuai keperluan, yang membuat kondisi benar memenuhi kebutuhan Anda.

      Perhatikan juga, ini tidak menghasilkan true. Metode pencarian tidak menghasilkan boolean, tetapi menghasilkan elemen yang cocok pertama. Jika tidak ada elemen yang cocok – yang berarti tidak ada elemen yang memenuhi kriteria yang didefinisikan dalam fungsi – maka hasilnya adalah undefined.. Juga perhatikan bahwa yang dihasilkan adalah elemen yang pertama, jadi jika ada lebih dari satu elemen di dalam larik yang memenuhi kriteria, metode ini hanya akan mengambil instans pertama. Dalam contoh kita, jika ada string lainnya dengan panjang kurang dari 12 setelah ‘4 feet tall’, ini tidak akan mengubah hasil kita.

      Dalam contoh ini, kita hanya menggunakan pemanggilan kembali dengan satu parameter. Anda juga dapat menambahkan parameter untuk merujuk ke indeks elemen saat ini. Parameter lain dapat menjadi keseluruhan larik itu sendiri, tetapi saya menemukan hal ini jarang digunakan. Berikut adalah contoh penggunaan indeks:

      alligator.find((el, idx) => typeof el === "string" && idx === 2); // returns '4 foot tall'
      

      Kita tahu dalam larik kita ada 3 elemen berbeda yang memenuhi kondisi pertama (typeof el === ‘string’). Jika ini adalah satu-satunya kondisi kita, hasil yang muncul adalah yang pertama, ‘thick scales’. Namun, perbedaannya adalah hanya satu yang memiliki indeks 2 dan itu adalah ‘4 foot tall’.

      Berbicara tentang indeks, metode larik yang mirip adalah .findIndex(). Metode ini juga menerima fungsi, tetapi seperti yang Anda duga, metode ini menghasilkan indeks elemen alih-alih elemen itu sendiri.

      indexOf

      const alligator = ["thick scales", 80, "4 foot tail", "rounded snout"];
      
      alligator.indexOf("rounded snout"); // returns 3
      

      Seperti metode .includes(), .indexOf() menggunakan perbandingan ketat, bukan fungsi seperti yang kita lihat pada metode .find(). Namun, tidak seperti includes(), metode ini menghasilkan indeks dari elemen, alih-alih boolean. Anda juga dapat mengindikasikan pencarian akan dimulai di indeks yang berada dalam larik.

      Saya merasa indexOf() sangat berguna. Ini cepat dan mudah, dapat memberi tahu Anda lokasi elemen di dalam larik, dan dapat memberi tahu Anda jika elemen ada di dalam larik. Bagaimana metode ini memberi tahu Anda ketika elemen itu ada? Pada dasarnya, kita dapat mengetahui bahwa elemen ada jika hasil yang diberikan adalah angka positif, dan jika hasilnya adalah -1, kita tahu bahwa elemen itu tidak ada.

      alligator.indexOf("soft and fluffy"); // returns -1
      alligator.indexOf(80); // returns 1
      alligator.indexOf(80, 2); // returns -1
      

      Seperti yang Anda dapat lihat, meskipun kita dapat menemukan metode find() atau findIndex() untuk memberikan informasi yang sama, metode ini memerlukan penulisan yang jauh lebih sedikit. Kita tidak perlu menulis fungsi untuk perbandingan, karena itu sudah ada dalam metode indexOf.

      Sekarang, seperti yang lain, indexOf() juga mengembalikan indeks dari elemen cocok pertama yang ditemukan. JavaScript memberi kita metode larik alternatif .lastIndexOf(). Seperti yang Anda tebak, ini melakukan hal yang sama seperti indexOf() tetapi dimulai dari indeks larik terakhir dan bekerja ke arah belakang. Anda juga dapat menentukan parameter kedua, tetapi ingat bahwa indeks tidak berubah hanya karena Anda menggunakan metode yang berbeda.

      const alligator = ["thick scales", 80, "4 foot tail", "rounded snout", 80];
      
      alligator.indexOf(80); // returns 1
      alligator.lastIndexOf(80); // returns 4
      alligator.indexOf(80, 2); // returns 4
      alligator.lastIndexOf(80, 4); // returns 4
      alligator.lastIndexOf(80, 3); // returns 1
      

      Bonus: filter

      const alligator = ["thick scales", 80, "4 foot tail", "rounded snout", 80];
      
      alligator.filter(el => el === 80); //returns [80, 80]
      

      Metode filter() mirip seperti metode find(), dalam hal mengharuskan fungsi dimasukkan dan kondisi yang dihasilkan. Perbedaan utamanya adalah, filter() selalu menghasilkan suatu larik, bahkan jika hanya ada satu elemen yang cocok. Namun, metode ini akan menghasilkan semua elemen yang cocok, sedangkan find() hanya mengembalikan yang cocok.

      Hal penting tentang filter adalah metode ini menghasilkan semua elemen yang cocok dengan kriteria Anda. Mungkin ini pendapat saya saja, tetapi saya dapat bingung, memikirkan “ini adalah elemen yang saya inginkan untuk filter out”, padahal sebenarnya Anda mengindikasikan elemen yang Anda inginkan untuk filter in.

      Kesimpulan

      Menurut saya, metode termudah untuk digunakan ketika mencari sesuatu adalah metode find(), tetapi seperti yang Anda lihat bahwa ini tergantung kasus Anda.

      • Apakah Anda hanya perlu mengetahui jika elemennya ada? Gunakan .includes().
      • Apakah Anda perlu mendapatkan elemen itu sendiri? Gunakan .find(), atau .filter() untuk beberapa item.
      • Apakah Anda perlu mencari indeks dari elemen? Gunakan .indexof() atau findIndex() untuk pencarian yang lebih kompleks.

      Larik dalam contoh di sini sangatlah sederhana. Anda mungkin menemukan larik dari banyak objek. Berikut adalah beberapa contoh sederhana di bawah ini untuk bernavigasi di hutan dari begitu banyak objek yang disangkarkan:

      const jungle = [
        { name: "frog", threat: 0 },
        { name: "monkey", threat: 5 },
        { name: "gorilla", threat: 8 },
        { name: "lion", threat: 10 }
      ];
      
      // break the object down in order to use .includes() or .indexOf()
      const names = jungle.map(el => el.name); // returns ['frog', 'monkey', 'gorilla', 'lion']
      console.log(names.includes("gorilla")); // returns true
      console.log(names.indexOf("lion")); // returns 3 - which corresponds correctly assuming no sorting was done
      
      // methods we can do on the array of objects
      console.log(jungle.find(el => el.threat == 5)); // returns object - {name: "monkey", threat: 5}
      console.log(jungle.filter(el => el.threat > 5)); // returns array - [{name: "gorilla", threat: 8}, {name: 'lion', threat: 10}]
      



      Source link

      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