如何通过getPlayerState()等功能获取当前的YouTube播放器状态?

时间:2014-04-16 20:59:44

标签: javascript api video youtube

我正在创建一个包含多个嵌入式YouTube视频的网页。我正在尝试编写代码,以便在页面上的另一个视频启动时停止播放一个视频。

我查看过YouTube API文档,我可以找到测试“播放”状态的最佳方法是getPlayerState()。

但是,当我在下面的代码中使用 getPlayerState()时,我得到一个“未捕获的TypeError:undefined不是函数”异常。这可能是因为该方法是事件对象成员。因为我试图测试特定播放器的“播放”状态,所以没有为该特定播放器实例化事件对象。

我的代码如下。要检查的功能是“ stateChanged()”,其中我检查特定玩家的状态。目前我使用的是硬编码的iFrame ID。在那里有一个“调试器”语句来强制断点。

请不要判断代码!这是我发现的几个Stack Overflow示例的实验性混搭。一旦预期的功能正常工作,我将在以后对其进行改进。

谢谢! 克里斯S。

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Embedded YouTube</title>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>

  <script>
    $(document).ready( function() {
      //------------------------------------------------
      // Assign a unique id to each iframe ...
      $('iframe[src*="http://www.youtube.com/embed/"]').each( function(i) {
        $(this).attr('id', 'vid' + i);
        console.log( $(this).attr('id') );
      })

      //------------------------------------------------
      // Is another video is already playing? If so stop it
      function stateChanged(event) {
        if (event.data == YT.PlayerState.BUFFERING) {
          debugger; 
          var player = new YT.Player('vid0');
          var sStatus = player.getPlayerState();
          // The error occurs here...
          if (sStatus == YT.PlayerState.PLAYING)
            player.stopVideo();
        }
      };

      //------------------------------------------------
      // Add function to execute when the API is ready ...
      YT_ready( function() {
        $('iframe[src*="http://www.youtube.com/embed/"]').each( function(i) {
          var frameID = getFrameID( $(this).attr('id') );
          if (frameID) { //If the frame exists
            player = new YT.Player(frameID, {
              events: { "onStateChange" : stateChanged }
            });
          }
        })
      });

    });


    //------------------------------------------------
    // Load YouTube IFrame API
    //------------------------------------------------
    (function() { // Closure, to not leak to the scope
      var s = document.createElement("script");
      s.src = (location.protocol == 'https:' ? 'https' : 'http') + "://www.youtube.com/player_api";
      var before = document.getElementsByTagName("script")[0];
      before.parentNode.insertBefore(s, before);
    })();

    //------------------------------------------------
    //Define a player object, to enable later function calls, without
    // having to create a new class instance again.
    var player; 

    //------------------------------------------------
    // This function will be called when the API is fully loaded
    function onYouTubePlayerAPIReady() {
      YT_ready(true);
    }

    //------------------------------------------------
    function getFrameID(id){
      var elem = document.getElementById(id);

      if (elem) {
          if(/^iframe$/i.test(elem.tagName)) 
            return id; //Frame, OK

          // else: Look for frame
          var elems = elem.getElementsByTagName("iframe");
          if (!elems.length) 
            return null; //No iframe found, FAILURE

          for (var i=0; i<elems.length; i++) {
             if (/^https?:\/\/(?:www\.)?youtube(?:-nocookie)?\.com(\/|$)/i.test(elems[i].src)) break;
          }

          elem = elems[i]; //The only, or the best iFrame
          if (elem.id) 
            return elem.id; //Existing ID, return it

          // else: Create a new ID
          do { //Keep postfixing `-frame` until the ID is unique
              id += "-frame";
          } while (document.getElementById(id));

          elem.id = id;
          return id;
      }
      // If no element, return null.
      return null;
    }

    //------------------------------------------------
    // Define YT_ready function.
    //------------------------------------------------
    var YT_ready = (function() {
        var onReady_funcs = [], api_isReady = false;
        /* @param func function     Function to execute on ready
         * @param func Boolean      If true, all qeued functions are executed
         * @param b_before Boolean  If true, the func will added to the first
                                     position in the queue*/
        return function(func, b_before) {
            if (func === true) {
                api_isReady = true;
                while (onReady_funcs.length) {
                    // Removes the first func from the array, and execute func
                    onReady_funcs.shift()();
                }
            } else if (typeof func == "function") {
                if (api_isReady) func();
                else onReady_funcs[b_before?"unshift":"push"](func); 
            }
        }
    })();
  </script>
</head>

<body>
  <div style="height:40px">&nbsp;</div>
  <iframe src="http://www.youtube.com/embed/LsqzXbJMj94?rel=0&enablejsapi=1" width="240" height="135" frameborder="0" allowfullscreen></iframe>
  <iframe src="http://www.youtube.com/embed/HuCaWjfWVx0?rel=0&enablejsapi=1" width="240" height="135" frameborder="0" allowfullscreen></iframe>
  <iframe src="http://www.youtube.com/embed/vbbQn_-9nlg?rel=0&enablejsapi=1" width="240" height="135" frameborder="0" allowfullscreen></iframe>
  <iframe src="http://www.youtube.com/embed/-MIaggsdTS0?rel=0&enablejsapi=1" width="240" height="135" frameborder="0" allowfullscreen></iframe>  
</body>
</html>

0 个答案:

没有答案