javascript - Youtube Iframe API loadVideoById() skips the video - Stack Overflow

ProblemI'm using Youtube Iframe API, And I need to use the API's startSeconds and endSeconds

Problem

I'm using Youtube Iframe API, And I need to use the API's startSeconds and endSeconds option of each video.

But here's the problem: the loadVideoById function skips the video. In my example code, the first, third, fifth video is only played.

Here's the code. It's just simplified version of my application.

Source Code

<!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 = ";;
      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>

Simple explanation for the source code

The videos array is assigned for test of my own. ( It's all Faker's highlights because I'm a big fan of him :) )

I made the player plays the videos in the list. If the player emits the "ENDED" event, then change the index and play the next video.

But when the time second and fourth video is to be played, This video isn't played. Only the ENDED event es.

It seems like that the loaded video's endSeconds value isn't equal to video's total duration, It skips next video.

How can I solve this situation? Is it Youtube API's bug?

Problem

I'm using Youtube Iframe API, And I need to use the API's startSeconds and endSeconds option of each video.

But here's the problem: the loadVideoById function skips the video. In my example code, the first, third, fifth video is only played.

Here's the code. It's just simplified version of my application.

Source Code

<!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./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>

Simple explanation for the source code

The videos array is assigned for test of my own. ( It's all Faker's highlights because I'm a big fan of him :) )

I made the player plays the videos in the list. If the player emits the "ENDED" event, then change the index and play the next video.

But when the time second and fourth video is to be played, This video isn't played. Only the ENDED event es.

It seems like that the loaded video's endSeconds value isn't equal to video's total duration, It skips next video.

How can I solve this situation? Is it Youtube API's bug?

Share Improve this question edited Jun 20, 2020 at 9:12 CommunityBot 11 silver badge asked Jul 20, 2015 at 6:54 Dong Hyun KooDong Hyun Koo 131 silver badge6 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 3

I added a log function to see which states are called and it seems to be a problem in the API. When a new video loads a state of -1 (unstarted) is immediately followed by a state of 0 (ended).

To prevent this from happening, I just added an extra check to make sure at least a fraction of the video is loaded.

<!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./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>

I found your problem it's in the function onPlayerStateChange() incrementation should be at the end (after loading your video ):

function onPlayerStateChange(event) {
        if (event.data === YT.PlayerState.ENDED) {
          console.log(index);
          if (index < videos.length - 1) {

            event.target.loadVideoById({
              videoId: videos[index].vid,
              startSeconds: videos[index].startSeconds,
              endSeconds: videos[index].endSeconds
            });
            index++;
        }
    }
}  

This code works, but the first video is playing twice, and the last is not displayed. You need to increment the index only for the first video in onPlayerReady, and to put <= in onPlayerStatechange.

function onPlayerReady(event) {
    event.target.cueVideoById({
        videoId: videos[index],
    });
    event.target.playVideo();
    if (index == 0){
        index++;
    }
}

// 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.
;
function onPlayerStateChange(event) {
    if (event.data === YT.PlayerState.ENDED) {
        console.log(index);
        if (index <= videos.length - 1) {

            event.target.loadVideoById({
                videoId: videos[index],
            });
            index++;
        }
    }
}
  var index = 0;
   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) {  
      index++;
      if (index > videos.length -1 ) {index=0;}else{index=index;}



        event.target.loadVideoById({
          videoId: videos[index].vid,
          startSeconds: videos[index].startSeconds,
          endSeconds: videos[index].endSeconds

          });


    }
  }

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745458724a4628608.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信