Jon Jon - 1 month ago 16
Javascript Question

Youtube - YT Object Has No Method PauseVideo()

I have embedded iFrame Youtube videos onto my page and I want the video to pause when the user clicks on the 'next' button to cycle through the carousels of videos. Before I cycle to the next video, I create a YT Object for the active video and try to run the

pauseVideo()
function. The console reports the error:
Uncaught TypeError: Object #<S> has no method 'pauseVideo'
.

What is puzzling is that I have
console.log
the player before calling the
pauseVideo()
function and I do see the
pauseVideo()
method available in the object. Does anyone have any idea why I am able to see the method in the YT Object, but the console keeps reporting that the method does not exist?

JS-Fiddle: http://jsfiddle.net/7WPe9/

// Load the IFrame Player API code asynchronously on DOM load
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/player_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

// Triggered when user clicks 'next slide'
pauseActiveYoutubeVideos : function() {
var player = new YT.Player( $('#media .item.active iframe.ytplayer')[0] );
console.log( player ); //pauseVideo() is defined in this player object
player.pauseVideo(); //console reports 'Uncaught TypeError: Object #<S> has no method 'pauseVideo''
}

Answer

Lots of little things here adding up to your problem. First of all, you have to send in an ID as an argument rather than a jquery object (as pointed out in one of the comments). More importantly, the YT iframe API has trouble when you bind an iFrame to a player object and then remove it ... you can't then rebind to that same iFrame again. So your nested loops need to be replaced. One strategy that generally works is to set up a separate tracking object where you create a YT.Player object for each video right at the beginning, and then just keep track of which one should be the active one (so you know which one to pause). Try something like this (and it should just be in a <script> tag, rather than in a jQuery 'ready' function, so as to avoid problems with the iFrame API's asynchronous load):

// Load the IFrame Player API code asynchronously on DOM load
var tag = document.createElement('script');
tag.src = "http://www.youtube.com/player_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

// Sets up player tracker, and init the carousel
  var players={}, activePlayerId;
  function onYouTubeIframeAPIReady() {
        $('iframe.ytplayer').each(function() {
                players[$(this).attr('id')]=new YT.Player($(this).attr('id'));
        });
        activePlayerId=$('iframe.ytplayer').first().attr('id');
        $("#"+activePlayerId).addClass('active');

 // Click on carousel next button
        $('#next').on('click', function() {
                players[activePlayerId].pauseVideo();
                $("#"+activePlayerId).removeClass('active');
                if ($("#"+activePlayerId).next().is('iframe')) {
                        activePlayerId=$("#"+activePlayerId).next().attr('id');
                }
                else {
                        activePlayerId=$('iframe.ytplayer').first().attr('id');
                }
                $("#"+activePlayerId).addClass('active');
        });
   }
Comments