How to allow play only one embedded YouTube video on page?

I have a few embedded YouTube videos on my page:

            <div class="video_block">
                <div class="embed-responsive embed-responsive-16by9">
                    <iframe class="embed-responsive-item" src="https://www.youtube.com/embed/4LaUVEF9GTs?rel=0" frameborder="0" allowfullscreen></iframe>
                </div>
            </div>

            <div class="video_block">
                <div class="embed-responsive embed-responsive-16by9">
                    <iframe class="embed-responsive-item" src="https://www.youtube.com/embed/JYZ_oP7QVSY?rel=0" frameborder="0" allowfullscreen></iframe>
                </div>
            </div>

How to avoid playing several videos at the same time if user press play button in all videos? Thank you for any suggestions or ideas in advance.


Solution 1:

Here's a quick YouTube player manager sketch that you can adapt to your needs. A couple of quick notes:

  1. You can also use the API to programmatically embed each iframe. This example assumes that the iframe elements are already on the page.

  2. If (as with this example) you utilize already embedded players then make sure you append '?enablejsapi=1' to the end of the embed URL.

  3. Essentially this manager keeps track of the registered videos. If it detects that a registered video begins to play it will pause any other registered video that is currently playing.

API Reference: https://developers.google.com/youtube/iframe_api_reference

UPDATE: Changed the example to use pauseVideo vs. stopVideo.

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

var ytPlayerManager = (function YTPlayerManager() {
  var players = [],
      PLAYING = 1;

  function register(id) {
    players.push({
      id: id,
      player: makePlayer(id)
    });
  }

  function makePlayer(id) {
      return new YT.Player(id, {
        events: {
          'onStateChange': function(event) {
            if(event.data == PLAYING) {
              videoPlaying(id);
            }
          }
        }
      });
  }

  function videoPlaying(id) {
    players.forEach(function(item) {
      if(item.id !== id) {
        item.player.pauseVideo();
      }
    });
  }

  return { register };
})();

function onYouTubeIframeAPIReady() {
  ytPlayerManager.register('video1');
  ytPlayerManager.register('video2');
  ytPlayerManager.register('video3');
}

Solution 2:

You need to use youtube api to have the full control over the videos and you can generate videos.

so you will be able to stop the others if one is playing

onStateChange

This event fires whenever the player's state changes. The data property of the event object that the API passes to your event listener function will specify an integer that corresponds to the new player state. Possible values are:

-1 (unstarted)
0 (ended)
1 (playing)
2 (paused)
3 (buffering)
5 (video cued).

When the player first loads a video, it will broadcast an unstarted (-1) event. When a video is cued and ready to play, the player will broadcast a video cued (5) event. In your code, you can specify the integer values or you can use one of the following namespaced variables:

YT.PlayerState.ENDED
YT.PlayerState.PLAYING
YT.PlayerState.PAUSED
YT.PlayerState.BUFFERING
YT.PlayerState.CUED

example :

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


 function onPlayerStateChange(event) {
    if (event.data == YT.PlayerState.PLAYING && !done) {
      setTimeout(stopVideo, 6000);
      done = true;
    }
  }

src is here

I hope it will helps