0

I'm trying to get a YouTube video to pause and play again using the YouTube API. I'm using some font awesome icon to toggleClass when clicked between a play icon and a pause icon. So far I can get the video to pause, but when clicking the play icon to resume playback it's not firing the event and I'm not totally sure why? I'm led to believe so far that it might have to do with onPlayerStateChange() but I'm not sure how it check for that event outright.

Here's what I have:

$( ".playback" ).click(function() {
   $(this).fadeOut("fast", function() {
    $(this).toggleClass('fa-play').fadeIn("fast");
    $(this).toggleClass('fa-pause').fadeIn("fast");
   });
 });

function onYouTubeIframeAPIReady() {
var player;
player = new YT.Player('yt-holder', {
videoId: 'BlahBlah',
width: "100%",
height: "100%",
playerVars: {
  autoplay: 1,
  controls: 0,
  showinfo: 0,
  modestbranding: 1,
  loop: 1,
  fs: 1,
  cc_load_policy: 1,
  iv_load_policy: 3,
  autohide: 1,
  rel:0,
  playlist: 'BlahBlah',
  enablejsapi: 1
   },
events: {
  onReady: function(e) {
    e.target.mute();
   }
  }
});
 $( ".fa-play" ).on('click', function() {
   player.playVideo();
});
  $( ".fa-pause" ).on('click', function() {
   player.pauseVideo();
 });
}

Not sure where and at what point I need to check for that player state change.

Here's a pen of what I am sorta trying to do: https://codepen.io/ultraloveninja/pen/gWmWRJ

ultraloveninja
  • 1,969
  • 5
  • 27
  • 56

3 Answers3

0

The issue with your code is that you are attaching the click event to a class that you are going to toggle, this will not work straight like that, since the attachment of the events happens when you execute the function onYouTubeIframeAPIReady

This means that at the moment of attaching the listener, you are only attaching the fa-play onclick method, which means your player.playVideo(); is run over and over again on the click event(even though the class changes, the listener stays the same)

To solve this you can read on event delegation (here is a good blog post about it), and check this pen i have created, where i have used an alternative solution which is to add two more divs inside the playback container, so we can attach different methods to different elements.

Carlos Valencia
  • 6,499
  • 2
  • 29
  • 44
  • Hmmm, ok. Well, I took a look at what you made in your pen, which makes sense. But I'm still not sure as to what specifically needs to be mapped in within the YT API events? – ultraloveninja Apr 28 '17 at 14:03
  • They seem to be fine, but refer to [this question](http://stackoverflow.com/questions/11283871/pause-youtube-video-youtube-api) for more details. – Carlos Valencia Apr 28 '17 at 15:03
  • I did look at that one, and that's kinda how I had it structured to begin with. I'll have to work with yours a bit and see what else I am missing. – ultraloveninja Apr 28 '17 at 17:01
  • yes, do go back to using that example, looking at your Pen, you have the event `onStateChange: onPlayerStateChange` and your function there adds an event listener, but that event is only triggered when the state has already changed (e.g. player.playVideo(); or player.pauseVideo(); has been already executed) so you are adding the event listener too late, sorry i can´t be of any more help right now but youtube is blocked at my office so i can't really test it. – Carlos Valencia Apr 28 '17 at 19:12
0

Try moving the .fa-play and .fa-pause outside of the onYouTubeIframeAPIReady function. I believe you're losing functionality once the "button" is clicked the first time.

CapnPamma
  • 25
  • 9
  • Tried that and nothing happened. – ultraloveninja Apr 28 '17 at 16:49
  • I went through the code over and over, and still don't see it, but it looks like the playback function toggles the class, then immediately toggles it back to what was. You might try setting autoplay to 0, setting the button to fa-play to start, and see if clicking gives you a clue. – CapnPamma Apr 28 '17 at 17:44
0

Ok, after hacking around with it some more and reading through the API docs, I finally figured it out.

I changed up the events and added:

 events: {
      onReady: onPlayerReady,
      onStateChange: onPlayerStateChange
    }

I then modified the functions for keeping the video muted on initial playback and then was able to conditionally check to see if the video was either playing or paused and process the logic out that way:

  function onPlayerReady(event) {
    event.target.playVideo();
    player.mute();
  }
  function onPlayerStateChange(event) {
    $(".fa-pause").on("click", function() {
      if (player.getPlayerState() == 1) {
        player.pauseVideo();
      } else {
        player.playVideo();
      }
    });
  }
  $(".fa-volume-off").on("click", function() {
    if (player.isMuted()) {
      player.unMute();
    } else {
      player.mute();
    }
  });

That way my other toggleClass items work and it just runs a check to see if the video is playing and if the audio is either muted or not.

Thanks for everyone's help!

Here's my updated pen for reference: https://codepen.io/ultraloveninja/pen/gWmWRJ

ultraloveninja
  • 1,969
  • 5
  • 27
  • 56