seekTo vs. loadVideoById / Which is better to use to loop video between set start and end times?

Both of these ways work, but which is better to use?

seekTo

  let player
  const startSeconds = 36;
  const endSeconds = 39;

  function onPlayerStateChange(state) {
    if (state.data === YT.PlayerState.ENDED) {
      player.seekTo(startSeconds);
    }
  }

loadVideoById

  let player
  const videoId = 'M7lc1UVf-VE';
  const startSeconds = 36;
  const endSeconds = 39;

  function onPlayerStateChange(state) {
  if (state.data === YT.PlayerState.ENDED) {
    player.loadVideoById({
      videoId: videoId,
      startSeconds: startSeconds,
      endSeconds: endSeconds
    });
  }
}

I reckon seek is better because it would not load the video again, but perhaps I’m wrong, although logically it seems that way.

seekTo is better when the video is already playing, such as when you have a custom scrubber that someone can use.

start/end seems to be better as it more clearly informs the person looking at the code (you and me), what is supposed to occur.

No, on reflection, seekTo is the better solution for you there for the code clearly says that when you get to the end, go back to the desired start section.

That’s commonly called an A-B loop on video players, where it loops continuously from A to B.

1 Like

Would I be able to remove the ‘let player’ from it, or that has to stay?

  let player
  const startSeconds = 36;
  const endSeconds = 39;


  function onPlayerReady(event) {
    player = event.target;
    player.setVolume(50); // percent
  }

  function onPlayerStateChange(state) {
    if (state.data === YT.PlayerState.ENDED) {
      player.seekTo(startSeconds);
    }
  }

Yes, that’s easy to achieve. Where’s the full code?

Here:

I was originally using this in it:
const youtubePlayer


(function manageCover() {
  "use strict";
  const hide = (el) => el.classList.add("hide");

  function coverClickHandler(evt) {
    const cover = evt.currentTarget;
    hide(cover);
  }
  const cover = document.querySelector(".jacketc");
  cover.addEventListener("click", coverClickHandler);
}());

const videoPlayer = (function makeVideoPlayer() {
  "use strict";
  let player
  const startSeconds = 36;
  const endSeconds = 39;

  function loadPlayer() {
    const tag = document.createElement("script");
    tag.src = "https://www.youtube.com/player_api";
    const firstScriptTag = document.getElementsByTagName("script")[0];
    firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
  }

  function onPlayerReady(event) {
     //const youtubePlayer
     player = event.target;
     player.setVolume(50); // percent
  }

  function onPlayerStateChange(state) {
    if (state.data === YT.PlayerState.ENDED) {
      player.seekTo(startSeconds);
    }
  }

  window.onYouTubePlayerAPIReady = function() {
    const video = document.querySelector(".video");
    const videoId = video.getAttribute("data-id");
    new YT.Player(video, {
      width: 606,
      height: 344,
      videoId: videoId,
      playerVars: {
        autoplay: 1,
        controls: 1,
        showinfo: 1,
        rel: 0,
        iv_load_policy: 3,
        cc_load_policy: 0,
        fs: 0,
        disablekb: 1,
        start: startSeconds,
        end: endSeconds
      },
      events: {
        "onReady": onPlayerReady,
        "onStateChange": onPlayerStateChange
      }
    });
  };



  function init() {
    loadPlayer();
  }
  return {
    init
  };

}());


(function iife() {
  "use strict";
  const show = (el) => el.classList.remove("hide");

  function coverClickHandler(evt) {
    const wrapper = evt.currentTarget.nextElementSibling;
    show(wrapper);
    videoPlayer.init();
  }

  const cover = document.querySelector(".jacketc");
  cover.addEventListener("click", coverClickHandler);
}());

Good one, nothing else uses the player variable.

First we adjust the onPlayerStateChange function, because state is not a value like on or off, but is instead an event object that contains all sorts of interesting things.

On investigating the function parameter, I see that it has data and target, where the target is the player itself. Event is a good name that the youtube API uses, so we’ll go back to using that, and can get the player from the event.

  // function onPlayerStateChange(state) {
  function onPlayerStateChange(event) {
    const player = event.target;
    // if (state.data === YT.PlayerState.ENDED) {
    if (event.data === YT.PlayerState.ENDED) {
      player.seekTo(startSeconds);
    }
  }

Something similar can happen to the onPlayerReady function too.

  function onPlayerReady(event) {
    // player = event.target;
    const player = event.target;
    player.setVolume(50); // percent
  }

The original let player line can now be removed.

// let player;

Should I change it back to:
const youtubePlayer

  function onPlayerReady(event) {
    const youtubePlayer = event.target;
    youtubePlayer.setVolume(50); // percent
  }

  function onPlayerStateChange(event) {
    const youtubePlayer = event.target;
    if (event.data === YT.PlayerState.ENDED) {
      youtubePlayer.seekTo(startSeconds);
    }
  }

or leave it as player?
const player


  function onPlayerReady(event) {
    const player = event.target;
    player.setVolume(50); // percent
  }

  function onPlayerStateChange(event) {
    const player = event.target;
    if (event.data === YT.PlayerState.ENDED) {
      player.seekTo(startSeconds);
    }
  }

No, there’s no need for that, I think I was overzelous with that earlier recommendation there. It’s quite clear from things like YT.PlayerState and other surrounding context that it’s the youtube player. Using player as a variable is all that’s needed here.

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.