Tutorial Javascript Membuat Youtube Loop Player

6 min read

Disclaimer
Saya bekerja di AWS, semua opini adalah dari saya pribadi. (I work for AWS, my opinions are my own.)
Tutorial Javascript Membuat Youtube Loop Player
Membuat Youtube Loop Player dengan Javascript

TeknoCerdas.com – Salam cerdas untuk kita semua. Pada tulisan kali ini TeknoCerdas akan memberikan tutorial Javascript yaitu membuat Youtube Loop player. Seperti namanya player ini akan otomatis mengulang video Youtube ketika telah berakhir.

Fitur yang akan dibangun pada Youtube Loop Player ini adalah:

  1. Otomatis mengulang video ketika video selesai.
  2. Otomatis mengulang video sesuai dengan waktu mulai dan waktu akhir yang ditentukan.

Fitur nomor 2 adalah fitur yang tidak disediakan oleh Youtube. Dimana fitur ini cukup berguna bagi yang ingin mengulang-ulang bagian tertentu dari video.

Youtube Loop Player yang dibangun adalah sebuah file HTML yang didalamnya terdapat kode Javascript. Kode yang dibuat memanfaatkan Youtube Iframe API.

Daftar Isi

Persiapan Javascript Youtube Loop Player

Sebelum mulai tutorial Javascript membuat Youtube Loop Player ada beberapa hal yang harus diperhatikan.

  • Memiliki pemahaman dasar tentang HTML/CSS
  • Memiliki pemahaman dasar tentang Javascript

Jika anda tidak memiliki pemahaman diatas tetap lanjutkan saja membaca karena mungkin ada informasi baru yang diperoleh.

Membuat Javascript Youtube Loop Player

Untuk menulis file HTML dan Javascript anda dapat menggunakan kode editor favorit anda. Buka kode editor anda lalu salin kode Youtube Loop Player berikut.

<!DOCTYPE html>
<html>
  <head>
  <style>
    body {
      width: 100%;
      position: relative;
      box-sizing: border-box;
      padding: 10px 20px;
    }
    .container {
      position: relative;
      width: 100%;
      margin: 0 auto;
      box-sizing: border-box;
      height: 0;
      padding-bottom: 56.25%; /* Aspect Ratio 16:9 */
    }
    .container iframe {
      position: absolute;
      left: 0;
      top: 120px;
      width: 100%;
      height: 100%;
    }
    .container input {
      font-size: 22px;
      padding: 4px;
      box-sizing: border-box;
    }
    .full-width { width: 100%; }
    .container #debug {
      font-family: monospace;
      padding: 4px;
      background-color: lightyellow;
    }
    .input-time { width: 180px; }
    .container #video-title {
      padding-top: 56.25%;
    }
    @media screen and (min-width: 960px) {
      .container {
        width: 920px;
        padding-bottom: 518px; /* Aspect Ratio 16:9 */
      }
      .container #video-title {
        padding-top: 518px;
      }
    }
  </style>
  </head>
  <body>
    <div class="container">
      <input class="full-width" id="video-url" disabled type="text" placeholder="Loading player, please wait..." value="https://www.youtube.com/watch?v=ZE3HoT5wnLs">
      <input class="input-time" id="video-start" type="text" placeholder="Mulai 00:00">
      <input class="input-time" id="video-end" type="text" placeholder="Berakhir 00:00">
      <div id="debug">
        REPLAY IF VIDEO_TIME: <span id="debug-video-time">0</span> >
        END_TIME: <span id="debug-end-time">0</span> |
        VIDEO_STATE: <span id="debug-video-state">0</span>
      </div>

      <!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
      <div id="player"></div>
      <h2 id="video-title"></h2>
    </div>
    <script>
      // jQuery style for accessing element
      var $ = function(el) { return document.querySelector(el); }

      var isVideoPaused = true;
      var timeCounterInterval = null;

      // 2. This code loads the IFrame Player API code asynchronously.
      var tag = document.createElement('script');

      tag.src = "https://www.youtube.com/iframe_api";
      var firstScriptTag = document.getElementsByTagName('script')[0];
      firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

      /**
       * 3. This function creates an <iframe> (and YouTube player)
       *    after the API code downloads. This function is required when
       *    using Youtube iframe API.
       *
       * We do not specify video id since we are going to get it from user
       * input.
       *
       * @return void
       */
      var player;
      function onYouTubeIframeAPIReady() {
        player = new YT.Player('player', {
          events: {
            'onReady': onPlayerReady,
            'onStateChange': onPlayerStateChange
          }
        });
      }

      /**
       * 4. The API will call this function when the video player is ready.
       * @return void
       */
      function onPlayerReady(event) {
        $('#video-url').disabled = false;
        $('#video-url').placeholder = 'Youtube URL';
        timeCounterInterval = setInterval(function() {
          if (isVideoPaused) { return; }

          var minuteEnd = getMinuteEnd();
          var currentVideoTime = Math.round(player.getCurrentTime());

          $('#debug-video-time').innerHTML = currentVideoTime;
          $('#debug-end-time').innerHTML = minuteEnd;

          if (minuteEnd > 0 && currentVideoTime > minuteEnd) {
            player.seekTo(getMinuteStart());
            return;
          }
        }, 1000);
      }

      /**
       * 5. The API calls this function when the player's state changes.
       *    Such as STOPPED, PLAYING, PAUSED, etc.
       * @return void
       */
      function onPlayerStateChange(event) {
        $('#debug-video-state').innerHTML = event.data;

        if (event.data == YT.PlayerState.ENDED) {
          player.seekTo(getMinuteStart());
          player.playVideo();
        }

        if (event.data == YT.PlayerState.PLAYING) {
          isVideoPaused = false;

          // Undocumented feature - getVideoData() and only available
          // during playing state
          $('#video-title').innerHTML = player.getVideoData().title;
        }

        if (event.data == YT.PlayerState.PAUSED) {
          isVideoPaused = true;
        }
      }

      /**
       * This function turn an query string on URL into an object.
       * We get the video ID using this function.
       *
       * @credit https://stackoverflow.com/a/13419367
       * @return Object of parsed query string.
       */
      function parseQuery(url) {
        var query = {};

        // Split the URL using '?' e.g: https://www.youtube.com/watch?v=VIDEO_ID
        // [0] => https://www.youtube.com/watch
        // [1] => v=VIDEO_ID

        // Then, split query string using '&' and turn it into objects using
        // query[VAR_KEY] = VAR_VALUE
        var pairs = url.split('?')[1].split('&');
        for (var i = 0; i < pairs.length; i++) {
            var pair = pairs[i].split('=');
            query[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1] || '');
        }
        return query;
      }

      /**
       * Function to get minute start by converting '00:00:00' format to seconds
       * @credit https://stackoverflow.com/a/45292588
       * @return Number
       */
      function getMinuteStart() {
        // + is used to convert string into Number. So +"" becomes 0
        // reduce used to loop of each element which splitted by ':'

        // Reduce without Initial value will start from index 1. Accumulator
        // will be equal to first array and "time" will be second array

        // Some examples
        // -------------
        // 02:30 => [2, 50] =>
        //   1 > { acc: "02", time: "30", math: "(60 * 02) + 30", nextAcc: 150 }
        //     > 150 secs
        // 01:02:30 => [1, 1, 30] =>
        //   1 > { acc: "01", time: "02", math: "(60 * 01) + 02", nextAcc: 62 }
        //   2 > { acc: 62, time: "30", math: "(60 * 62) + 30", nextAcc: 3750 }
        //     > 3750 secs
        return +$('#video-start').value.split(':').reduce(function(acc, time) {
          return (60 * acc) + +time;
        });
      }

      /**
       * Function to get minute end by converting '00:00:00' format to seconds
       * @return Number
       */
      function getMinuteEnd() {
        return +$('#video-end').value.split(':').reduce(function(acc, time) {
          return (60 * acc) + +time;
        });
      }

      /**
       * Cue (Prepare) by display a thumbnail of the video
       *
       * @return void
       */
      function cueVideo() {
        // Youtube URL should be in format https://www.youtube.com/watch?v=VIDEO_ID
        var query = parseQuery($('#video-url').value);
        var minuteStart = getMinuteStart();

        if (minuteStart > 0) {
          // Jump at specified seconds
          player.cueVideoById(query.v, minuteStart);
          return;
        }

        // No time provided
        player.cueVideoById(query.v);
      }

      // When each of these input lost the focus execute cueVideo() function
      $('#video-url').onblur = cueVideo;
      $('#video-start').onblur = cueVideo;
      $('#video-end').onblur = cueVideo;
    </script>
  </body>
</html>

Simpan file diatas dengan ekstensi html misalnya player.html. Untuk mencobanya anda tinggal membukanya melalui web browser.

Fungsi onYouTubeIframeAPIReady() diperlukan dan harus ada ketika menggunakan Youtube Iframe API. Karena setelah kode Javascript dari Youtube API selesai diambil maka otomatis fungsi ini akan dieksekusi. Pada fungsi ini objek player akan dibuat dengan new YT.Player().

Fungsi onPlayerReady() akan dipanggil ketika Youtube Player sudah siap dipakai. Pada fungsi ini inisialisasi awal dilakukan termasuk membuat kondisi pengecekan untuk mengulang video jika sudah pada durasi tertentu. Hal ini dicapai dengan menggunakan setInterval() yang dijalankan dengan interval per 1 detik.

Fungsi onPlayerStateChange() akan selalu dipanggil ketika ada perubahan status pada Player. Misal dari PLAYING ke PAUSED dan sebagainya. Pada blok fungsi ini juga akan dicek ketika video berakhir maka akan otomatis diulang. Hal penting lain yang dilakukan pada fungsi ini adalah menghentikan interval dengan mengubah status dari variabel isVideoPaused sehingga tidak perlu ada pengecekan video ketika sedang dipause.

Fungsi getMinuteStart() dan getMinuteEnd() akan mengubah format waktu dari 00:00 menjadi satuan detik. Jika inputan adalah 02:30 maka hasilnya adalah 150 detik. Hal ini karena API dari Youtube Iframe menerima argumen dalam bentuk durasi detik.

Fungsi cueVideo() digunakan untuk menyiapkan video yang akan diputar. Pada fungsi ini juga otomatis akan mengubah nilai awal dari waktu mulai dari sebuah video jika diisi. Fungsi ini mengambil video ID dengan melakukan ekstrak nilai dari query string v=VIDEO_ID pada URL.

Menjalankan Youtube Loop Player

Untuk menjalankan Youtube Loop Player cukup buka atau jalankan file tersebut menggunakan web browser seperti Chrome, Firefox, Safari atau lainnya. Tampilan dari Youtube Loop Player yang dibuat harusnya seperti berikut.

Tutorial Javascript Youtube Loop Player
Tampilan Javascript Youtube Loop Player

Sebagai contoh saya menggunakan video dari Alip_ba_ta dengan URL https://www.youtube.com/watch?v=ZE3HoT5wnLs.

Jika ingin mengulang semua dari awal hingga akhir maka kosongi inputan Mulai dan Akhir. Jika ingin mengulang pada bagian tertentu misal dari detik ke 30 sampai menit ke 1:10 maka isikan 00:30 pada Mulai dan 01:10 pada Akhir.

Semoga tutorial ini bermanfaat. Selamat mencoba.