YT.Player不返回playVideo()的实例

时间:2018-01-21 06:24:07

标签: javascript youtube-api youtube-iframe-api

当我创建YT.Player(HTMLIFrameElement, { options })的实例时,我找回了一个具有以下内容的对象:

  • 破坏
  • 的setSize
  • getIframe
  • 的addEventListener
  • getVideoEmbedCode
  • getOptions
  • getOption

但不是playVideo中描述的pauseVideotrait.playable.youtube.js等。

我在这里得到了一个演示:documentation

我通过documentFragment中的DOM创建iframe,并将iframe添加到最终将添加到div的const element = document.createElement('iframe') element.src = `https://www.youtube.com/embed/${id}?rel=0;&autoplay=${this.options.autostart ? 1 : 0};&enablejsapi=1;&origin=${location.hostname};` element.style = this.inlineStyle

// nasty initialization because we're outside webpack and this is a demo
if (global.YT.loaded) {
  this.player = new global.YT.Player(element, {
    events: {
      'onStateChange': this.stateHandler,
      'onReady': onPlayerReady
    }
  })
} else {
  const oldHandler = global.onYouTubeIframeAPIReady
  global.onYouTubeIframeAPIReady = () => {
    if (oldHandler) oldHandler()

    this.player = new global.YT.Player(element, {
      events: {
        'onStateChange': this.stateHandler,
        'onReady': onPlayerReady
      }
    })
  }
}

然后我创建了一个YT.Player的实例:

S = {<"A","">, <"B","">, <"AB","A">, <"AB","B">, <"C","">, <"ABC","A">,<"ABC","B">, <"ABC","C">, <"ABC","AB">},

YT.Player的实例看起来像这样:

http://siesta-annotations.surge.sh/Siesta_webviewer_test/?page=3

看起来缩小过程非常错误。我做错了什么 - 我应该如何为我的用例初始化YT.Player?

2 个答案:

答案 0 :(得分:0)

奇怪的是,直到在构造函数播放器选项对象中调用'onReady'之前,您都无法访问YTPlayer API。 https://developers.google.com/youtube/iframe_api_reference#Loading_a_Video_Player

function onYouTubeIframeAPIReady() {
  new YT.Player('player', {
    height: '390',
    width: '640',
    videoId: 'M7lc1UVf-VE',
    events: {
      'onReady': function (event) {
        onPlayerReady(event.target)
      },
      'onStateChange': onPlayerStateChange
    }
  });
}

function onPlayerReady(player) {
  player.playVideo();
}

这当然仅适用于一个播放器,因此如果要处理多个播放器,则需要推出自己的YouTube播放器管理器。 (我知道API很疯狂)

如果您将iframe与youtube视频(未体验)配合使用,则可以采用以下快速解决方案:

const YTManager = {
  videos: [],
  youtubeApiReady = false,
  initialize () {
    const matchId = /[^/]+$/

    this.youtubeApiReady = true

    document.querySelectorAll('iframe[src*="youtube"]')
      .forEach(iframe => this.videos.push({
         dom: iframe,
         player: null,
         videoId: iframe.src.exec(matchId) || iframe.src.exec(matchId)[0]
       }))
  },
  createPlayers () {
    if (this.youtubeApiReady === false) return

    this.videos.forEach(v => {
      new YT.Player(v.dom.id, {
        videoId: v.videoId,
        events: {
          'onReady': function (event) {
            v.player = event.target
          }
        }
      })
    })
  },
  find (id) {
    return this.videos.find(v => v.id === id)
  },
  play (id) {
    const video = this.find(id)
    if (this.youtubeApiReady && video && video.player) {
      video.playVideo()
    }
  },
  pause (id) {
    const video = this.find(id)
    if (this.youtubeApiReady && video && video.player) {
      video.pauseVideo()
    }
  },
}

window.onYouTubeIframeAPIReady = function onYouTubeIframeAPIReady() {
  // YouTube client side script has been loaded
  nappYoutubePlayer.youtubeApiReady = true
  nappYoutubePlayer.createPlayers()
}

document.addEventListener("DOMContentLoaded", function() {
  // all iframes has been parsed by the browser
  YTManager.initialize()
});

当然,如果没有ID,您就无法调用YTManager.playYTManager.pause并等待YouTube脚本加载,然后视频初始化完成。总而言之,真是一团糟。我相信您可以找到一个更好的经理。我在工作中写的更好,但也可以处理完全不同的对象和要求,因此它不太适合通用YouTube视频管理器。但是上面的那个是我当前球员的要旨。

我建议从一开始就使用iframe-如果脚本中出现任何问题,视频仍然可以播放,您将无法对其进行任何控制。

已陷害的youtube视频如下:

<iframe
  id="uniqueDOMElementID1"
  width="560"
  height="315"
  src="https://www.youtube.com/embed/bHQqvYy5KYo"
  frameborder="0"
  allow="autoplay; encrypted-media"
  allowfullscreen></iframe>

答案 1 :(得分:0)

这是我的第二篇文章,希望我能解决您的问题。

我不确定您的代码是如何工作的100%,但是我怀疑...

  

似乎YT.Player对象的两次实例化,将导致YT.Player对象不稳定。

我自己也挣扎了很长时间(ps:我是一名业余程序员。)

例如,从Youtube Iframe API website修改了以下代码片段,并举例说明了第二个实例化将如何破坏播放器对象try it! JS Bin

<!DOCTYPE html>
<html>

<body>
    <!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
    <div id="player"></div>
    </br>
    <button onclick="instantiateOneMore()">
        Call
        <pre>new YT.Player('player')</pre>
    </button>
    <button onclick="pauseVideo()">
      pauseVideo();
    </button>
    <script>
        // 2. This code loads the IFrame Player API code asynchronously.
        var tag = document.createElement('script');

        tag.src = "https://www.youtube.com/iframe_api";
        var firstScriptTag = document.getElementsByTagName('script')[0];
        firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

        // 3. This function creates an <iframe> (and YouTube player)
        //    after the API code downloads.
        var player;

        function onYouTubeIframeAPIReady() {
            player = new YT.Player('player', {
                height: '390',
                width: '640',
                videoId: 'M7lc1UVf-VE',
                events: {
                    'onReady': onPlayerReady,
                    'onStateChange': onPlayerStateChange
                }
            });

        }


        let callTime = 0;
        // 4. The API will call this function when the video player is ready.
        function onPlayerReady(event) {
            event.target.playVideo();
            callTime ++;
            console.log(callTime);
            //document.querySelector('#dd').innerHTML = player.pauseVideo;
        }
      function pauseVideo(){
        player.pauseVideo();
      }
        instantiateOneMore = () => {
            player = new YT.Player('player', {
                height: '390',
                width: '640',
                videoId: 'M7lc1UVf-VE',
                events: {
                    'onReady': onPlayerReady,
                    'onStateChange': onPlayerStateChange
                }
            });
            //document.querySelector('#dd').innerHTML = player.pauseVideo;
        }

        // 5. The API calls this function when the player's state changes.
        //    The function indicates that when playing a video (state=1),
        //    the player should play for six seconds and then stop.
        var done = false;

        function onPlayerStateChange(event) {
            if (event.data == YT.PlayerState.PLAYING && !done) {
                /* setTimeout(stopVideo, 6000) */
                ;
                done = true;
            }
        }
        /* 
              function stopVideo() {
                player.stopVideo();
              } */
    </script>
</body>

</html>

此外,第二个onPlayerReady()甚至都不会被调用。因此,如果您打算放一些计数器来查看调用new YT.Player(...)的次数,您会怀疑它仅被调用了一次。这使效果远离调试。