Javascript YouTube iframe API:如何控制';它已经在HTML中了吗?

Javascript YouTube iframe API:如何控制';它已经在HTML中了吗?,javascript,youtube-api,youtube-javascript-api,Javascript,Youtube Api,Youtube Javascript Api,我希望能够控制基于iframe的YouTube播放器。这个播放器已经在HTML中了,但是我想通过JavaScript API来控制它们 我一直在阅读,其中解释了如何使用API向页面添加新视频,然后使用YouTube播放器功能进行控制: var player; function onYouTubePlayerAPIReady() { player = new YT.Player('container', { height: '390', width: '64

我希望能够控制基于iframe的YouTube播放器。这个播放器已经在HTML中了,但是我想通过JavaScript API来控制它们

我一直在阅读,其中解释了如何使用API向页面添加新视频,然后使用YouTube播放器功能进行控制:

var player;
function onYouTubePlayerAPIReady() {
    player = new YT.Player('container', {
        height: '390',
        width: '640',
        videoId: 'u1zgFlCw8Aw',
        events: {
            'onReady': onPlayerReady,
            'onStateChange': onPlayerStateChange
        }
    });
}
该代码创建一个新的player对象并将其分配给“player”,然后将其插入到#container div中。然后我可以对“player”进行操作,并在其上调用
playVideo()
pauseVideo()
,等等

但我希望能够在页面上已有的iframe播放器上操作。

我可以用旧的嵌入方法很容易地做到这一点,比如:

player = getElementById('whateverID');
player.playVideo();
但这不适用于新的iFrame。如何分配页面上已有的iframe对象,然后在其上使用API函数?

小提琴链接:--
更新:这个小函数只在一个方向上执行代码。如果您需要全面支持(如事件侦听器/获取器),请查看

经过深入的代码分析,我创建了一个函数:
functioncallplayer
请求对任何带边框的YouTube视频进行函数调用。请参阅以获取可能的函数调用的完整列表。阅读源代码中的注释以获得解释

2012年5月17日,为了照顾玩家的就绪状态,代码大小增加了一倍。如果您需要一个不处理播放器就绪状态的紧凑函数,请参阅

可能的问题和答案: Q:它不起作用
A:“不起作用”不是一个明确的描述。您是否收到任何错误消息?请出示相关代码

Q
播放视频
不播放视频。
A:播放需要用户交互,并且iframe上存在
allow=“autoplay”
。看到和

Q:我使用
嵌入了一个YouTube视频,但该函数不执行任何函数
A:您必须在URL的末尾添加
?enablejsapi=1
/embed/vid\u id?enablejsapi=1

Q:我收到错误消息“指定了无效或非法的字符串”。为什么?
A:API在本地主机上无法正常运行(
文件://
)。在线托管(测试)页面,或使用。示例:请参阅此答案顶部的链接

Q:你怎么知道的 A:我花了一些时间手动解释API的源代码。我的结论是我必须使用这种方法。为了知道要传递哪些参数,我创建了一个拦截消息的Chrome扩展。可以下载扩展的源代码

Q:支持哪些浏览器?
A:每个支持和的浏览器

  • IE 8+
  • Firefox 3.6+(实际上是3.5,但是
    document.readyState
    是在3.6中实现的)
  • 歌剧院10.50+
  • 狩猎4+
  • 铬3+
相关回答/实施:
完整的API支持:
官方API:

修订历史
  • 2012年5月17日
    实现了onyoutubeplayerrady:
    callPlayer('frame_id',function(){…})

    当播放机尚未准备就绪时,函数将自动排队
  • 2012年7月24日
    在支持的浏览器中更新并成功测试(展望)
  • 2013年10月10日 当函数作为参数传递时,
    callPlayer
    强制检查就绪状态。这是必需的,因为当文档准备就绪时插入iframe后立即调用
    callPlayer
    时,它无法确定iframe是否完全准备就绪。在Internet Explorer和Firefox中,这种情况导致过早调用
    postMessage
    ,而被忽略
  • 2013年12月12日,建议在URL中添加
    &origin=*
  • 2014年3月2日,撤回了将
    &origin=*
    删除到URL的建议
  • 2019年4月9日,修复在页面准备就绪之前加载YouTube时导致无限递归的错误。添加有关自动播放的注释

    • 看起来YouTube已经更新了他们的JS API,所以默认情况下这是可用的!您可以使用现有YouTube iframe的ID

      <iframe id="player" src="http://www.youtube.com/embed/M7lc1UVf-VE?enablejsapi=1&origin=http://example.com" frameborder="0"></iframe>
      
      …构造函数将使用现有的iframe,而不是用新的iframe替换它。这也意味着您不必为构造函数指定videoId


      请参见

      您可以用少得多的代码完成此操作:

      function callPlayer(func, args) {
          var i = 0,
              iframes = document.getElementsByTagName('iframe'),
              src = '';
          for (i = 0; i < iframes.length; i += 1) {
              src = iframes[i].getAttribute('src');
              if (src && src.indexOf('youtube.com/embed') !== -1) {
                  iframes[i].contentWindow.postMessage(JSON.stringify({
                      'event': 'command',
                      'func': func,
                      'args': args || []
                  }), '*');
              }
          }
      }
      
      函数调用播放器(func,args){
      var i=0,
      iframes=document.getElementsByTagName('iframe'),
      src='';
      对于(i=0;i
      工作示例:

      我自己版本的Kim T代码,它与一些jQuery相结合,允许针对特定的iFrame

      $(function() {
          callPlayer($('#iframe')[0], 'unMute');
      });
      
      function callPlayer(iframe, func, args) {
          if ( iframe.src.indexOf('youtube.com/embed') !== -1) {
              iframe.contentWindow.postMessage( JSON.stringify({
                  'event': 'command',
                  'func': func,
                  'args': args || []
              } ), '*');
          }
      }
      

      谢谢你的回答

      我一直在Cordova应用程序中使用它,以避免加载API,从而可以轻松控制动态加载的iFrame

      我一直希望能够从iframe中提取信息,比如状态(getPlayerState)和时间(getCurrentTime)

      Rob W帮助强调了API是如何使用postMessage工作的,但当然,这只向一个方向发送信息,从我们的web页面发送到iframe。访问getter需要我们监听从iframe发回给我们的消息

      我花了一些时间去费古
      var player;
      function onYouTubeIframeAPIReady() {
        player = new YT.Player('player', {
          events: {
            'onStateChange': onPlayerStateChange
          }
        });
      }
      
      function onPlayerStateChange() {
        //...
      }
      
      function callPlayer(func, args) {
          var i = 0,
              iframes = document.getElementsByTagName('iframe'),
              src = '';
          for (i = 0; i < iframes.length; i += 1) {
              src = iframes[i].getAttribute('src');
              if (src && src.indexOf('youtube.com/embed') !== -1) {
                  iframes[i].contentWindow.postMessage(JSON.stringify({
                      'event': 'command',
                      'func': func,
                      'args': args || []
                  }), '*');
              }
          }
      }
      
      $(function() {
          callPlayer($('#iframe')[0], 'unMute');
      });
      
      function callPlayer(iframe, func, args) {
          if ( iframe.src.indexOf('youtube.com/embed') !== -1) {
              iframe.contentWindow.postMessage( JSON.stringify({
                  'event': 'command',
                  'func': func,
                  'args': args || []
              } ), '*');
          }
      }
      
      function callPlayer(iframe, func, args) {
          iframe=document.getElementById(iframe);
          var event = "command";
          if(func.indexOf('get')>-1){
              event = "listening";
          }
      
          if ( iframe&&iframe.src.indexOf('youtube.com/embed') !== -1) {
            iframe.contentWindow.postMessage( JSON.stringify({
                'event': event,
                'func': func,
                'args': args || []
            }), '*');
          }
      }
      window.onmessage = function(e){
          var data = JSON.parse(e.data);
          data = data.info;
          if(data.currentTime){
              console.log("The current time is "+data.currentTime);
          }
          if(data.playerState){
              console.log("The player state is "+data.playerState);
          }
      }
      
      <!-- HTML -->
      <div class="iframe" data-player="viemo" data-src="$PageComponentVideo.VideoId"></div>
      
      
      <!-- jQuery -->
      $(".btnVideoPlay").on("click", function (e) {
              var iframe = $(this).parents(".video-play").siblings(".iframe");
              iframe.show();
      
              if (iframe.data("player") === "youtube") {
                  autoPlayVideo(iframe, iframe.data("src"), "100%", "100%");
              } else {
                  autoPlayVideo(iframe, iframe.data("src"), "100%", "100%", true);
              }
          });
      
          function autoPlayVideo(iframe, vcode, width, height, isVimeo) {
              if (isVimeo) {
                  iframe.html(
                      '<iframe width="' +
                          width +
                          '" height="' +
                          height +
                          '" src="https://player.vimeo.com/video/' +
                          vcode +
                          '?color=ff9933&portrait=0&autoplay=1" frameborder="0" allowfullscreen wmode="Opaque"></iframe>'
                  );
              } else {
                  iframe.html(
                      '<iframe width="' +
                          width +
                          '" height="' +
                          height +
                          '" src="https://www.youtube.com/embed/' +
                          vcode +
                          '?autoplay=1&loop=1&rel=0&wmode=transparent" frameborder="0" allowfullscreen wmode="Opaque"></iframe>'
                  );
              }
          }