javascript - Youtube Iframe API loadVideoById() 跳过视频

标签 javascript iframe video youtube

问题

我正在使用 Youtube Iframe API,我需要使用每个视频的 API 的 startSeconds 和 endSeconds 选项。

但这就是问题所在:loadVideoById 函数会跳过视频。 在我的示例代码中,只播放了第一、第三、第五个视频。

这是代码。它只是我的应用程序的简化版本。

源代码

<!DOCTYPE html>
<html>
  <body>
    <!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
    <div id="player"></div>

    <script>
      // 2. This code loads the IFrame Player API code asynchronously.
      var tag = document.createElement('script');
      tag.src = "http://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',
          events: {
            'onReady': onPlayerReady,
            'onStateChange': onPlayerStateChange
          }
        });
      }

      var videos = [
        {
          vid: 'nbCqWMIT-Pk',
          startSeconds: 10,
          endSeconds: 15
        },
        {
          vid: 'sAoJGNF_laA',
          startSeconds: 10,
          endSeconds: 15
        },
        {
          vid: 'kF_23_XxaHQ',
          startSeconds: 10,
          endSeconds: 15
        },
        {
          vid: 'zxYp3I0Gyrg',
          startSeconds: 10,
          endSeconds: 15
        },
        {
          vid: 'U_gA99OQwO4',
          startSeconds: 10,
          endSeconds: 15
        }
      ];
      var index = 0;
      // 4. The API will call this function when the video player is ready.
      function onPlayerReady(event) {
        event.target.cueVideoById({
          videoId: videos[index].vid,
          startSeconds: videos[index].startSeconds,
          endSeconds: videos[index].endSeconds
        });
        event.target.playVideo();
      }

      function onPlayerStateChange(event) {
        if (event.data === YT.PlayerState.ENDED) {
          console.log(index);
          if (index < videos.length - 1) {
            index++;
            event.target.loadVideoById({
              videoId: videos[index].vid,
              startSeconds: videos[index].startSeconds,
              endSeconds: videos[index].endSeconds
            });
          }
        }
      }

    </script>
  </body>
</html>

源码简单说明

视频数组是为我自己的测试分配的。 (这都是 Faker 的亮点,因为我是他的忠实粉丝:))

我让播放器播放列表中的视频。如果播放器发出“ENDED”事件,则更改索引​​并播放下一个视频。

但是当第二个和第四个视频要播放的时候,这个视频没有播放。只有 ENDED 事件到来。

似乎加载的视频的 endSeconds 值不等于视频的总时长,它会跳过下一个视频。

我该如何解决这种情况?是 Youtube API 的错误吗?

最佳答案

我添加了一个日志函数来查看调用了哪些状态,这似乎是 API 中的问题。当加载新视频时,状态 -1(未开始)紧接着是状态 0(结束)。

为了防止这种情况发生,我刚刚添加了一个额外的检查以确保至少加载了一部分视频。

<!DOCTYPE html>
<html>
  <body>
    <!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
    <div id="player"></div>

    <script>
      // 2. This code loads the IFrame Player API code asynchronously.
      var tag = document.createElement('script');
      tag.src = "http://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',
          events: {
            'onReady': onPlayerReady,
            'onStateChange': onPlayerStateChange
          }
        });
      }

      var videos = [
        {
          vid: 'nbCqWMIT-Pk',
          startSeconds: 10,
          endSeconds: 15
        },
        {
          vid: 'sAoJGNF_laA',
          startSeconds: 10,
          endSeconds: 15
        },
        {
          vid: 'kF_23_XxaHQ',
          startSeconds: 10,
          endSeconds: 15
        },
        {
          vid: 'zxYp3I0Gyrg',
          startSeconds: 10,
          endSeconds: 15
        },
        {
          vid: 'U_gA99OQwO4',
          startSeconds: 10,
          endSeconds: 15
        }
      ];
      var index = 0;
      // 4. The API will call this function when the video player is ready.
      function onPlayerReady(event) {
        event.target.cueVideoById({
          videoId: videos[index].vid,
          startSeconds: videos[index].startSeconds,
          endSeconds: videos[index].endSeconds
        });
        event.target.playVideo();
      }

      function onPlayerStateChange(event) {
        console.log("State change: " + event.data + " for index: " + index);

        if (event.data === YT.PlayerState.ENDED && player.getVideoLoadedFraction() > 0) {
          console.log(index);
          if (index < videos.length - 1) {
            index++;
            event.target.loadVideoById({
              videoId: videos[index].vid,
              startSeconds: videos[index].startSeconds,
              endSeconds: videos[index].endSeconds
            });
          }
        }
      }

    </script>
  </body>
</html>

关于javascript - Youtube Iframe API loadVideoById() 跳过视频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31510351/

相关文章:

javascript - 尝试播放 youtube 视频 javascript 时出现 ".playVideo is not a function"

css - Facebook 新 Page Plugin 自定义样式

javascript - AngularJS 和谷歌分析

javascript - 在 jQuery 中准确定位 <div>

javascript - 在 nvd3 图表中更改 xAxis 的日期格式

facebook - 通过 https 在 iframe 中加载页面应用程序时静默失败

java - 如果我们有视频 URL,如何检查视频是否正在播放?

video - 最便携的网络视频编解码器?

ruby-on-rails - 如何使用 ruby​​ on Rails 在 vi​​deo_tag 中传递静音选项

javascript - 如何获取 React.js 中选中复选框的数量?