Frasier013
Frasier013

Reputation: 311

Pause YouTube iframe embed when playing another

I have multiple YouTube iFrames embedded on a page. If one of the movies is already playing, and a user then decides to start playing a different movie, is it possible to stop playing the first movie so there is only ever one playing at a time?

I have looked at the 'YouTube Player API Reference for iframe Embeds' https://developers.google.com/youtube/iframe_api_reference but if i'm honest I just don't understand it. My developer skills are very limited.... clearly.

Pitiful I know, but this is all I have at the moment (just the iFrames)... http://jsfiddle.net/YGMUJ/

<iframe width="520" height="293" src="http://www.youtube.com/v/zXV8GMSc5Vg?version=3&enablejsapi=1" frameborder="0" allowfullscreen></iframe>
<iframe width="520" height="293" src="http://www.youtube.com/v/LTy0TzA_4DQ?version=3&enablejsapi=1" frameborder="0" allowfullscreen></iframe>

I thought all I needed to do was add '&enablejsapi=1' at the end of the video URLs.

Any help would be much appreciated.
Thank you in advance.

Upvotes: 11

Views: 21468

Answers (6)

Ian Venskus
Ian Venskus

Reputation: 952

Vanilla JS based on answer by Jennie Sadler.

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

function onYouTubeIframeAPIReady() {
var players = [];
Array.prototype.slice.call(document.getElementsByTagName("iframe")).filter(function(e) {
    return e.src.indexOf("https://www.youtube.com/") == 0;
}).forEach(function(youtubevideo, k, v) {
    if (!youtubevideo.id) {
        youtubevideo.id = 'embeddedvideoiframe' + k;
    }
    players.push(new YT.Player(youtubevideo.id, {
        events: {
            'onStateChange': function(event) {
                if (event.data == YT.PlayerState.PLAYING) {
                    Array.prototype.slice.call(players).forEach(function(youtubevideo, k, v) {
                        if (youtubevideo.getPlayerState() == YT.PlayerState.PLAYING //# checks for only players that are playing
                            && youtubevideo.getIframe().id != event.target.getIframe().id) {
                            youtubevideo.pauseVideo();
                        }
                    });
                }
            }
        }
    }))
});

}

Upvotes: 0

a.0
a.0

Reputation: 1

I'm super new to this. I am posting this to see if this is fine. Also I do not know jQuery so this was just a simpler way for me. I also only have one iframe and change src. Is this a problem??? I put an id on an iframe to populate it with an array of videos. I ran into a problem where it would keep playing it after I closed a modal box. After looking for answers I decided to try making the iframe reference nothing. It works but probably is not the best solution if you want both videos on screen.

function stopVid(){
  var iframe = document.getElementById("videoPlayer");
  iframe.src = "";
 }

Upvotes: 0

umerbanday
umerbanday

Reputation: 76

The above script of vbence works perfectly.

Here is the same script in javascript.

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

function onYouTubeIframeAPIReady() {
  var i,
    frames,
    players = [];
  frames = document.getElementsByTagName("iframe");
  const arr = Array.from(frames);
  const arrnew = arr.filter((e) => {
    return e.src.indexOf("https://www.youtube.com/") == 0;
  });
  arrnew.forEach((ele, index) => {
    if (!ele.id) {
      ele.id = "embeddedvideoiframe" + index;
    }
    players.push(
      new YT.Player(ele.id, {
        events: {
          onStateChange: (event) => {
            if (event.data == YT.PlayerState.PLAYING) {
              players.forEach((ply) => {
                if (ply.getIframe().id != event.target.getIframe().id) {
                  ply.pauseVideo();
                }
              });
            }
          },
        },
      })
    );
  });
}

Upvotes: 0

vbence
vbence

Reputation: 20343

Here is an advanced version of @Matt Koskela's version. It does not require you to create the videos by JavaScript. It works for example if the videos are generated on the PHP side (think Wordpress).

JsFiddle demo here.

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

    function onYouTubeIframeAPIReady() {
        var $ = jQuery;
        var players = [];
        $('iframe').filter(function(){return this.src.indexOf('http://www.youtube.com/') == 0}).each( function (k, v) {
            if (!this.id) { this.id='embeddedvideoiframe' + k }
            players.push(new YT.Player(this.id, {
                events: {
                    'onStateChange': function(event) {
                        if (event.data == YT.PlayerState.PLAYING) {
                            $.each(players, function(k, v) {
                                if (this.getIframe().id != event.target.getIframe().id) {
                                    this.pauseVideo();
                                }
                            });
                        }
                    }
                }
            }))
        });
    }
</script>

One: 
<iframe frameborder="0" allowfullscreen="1" title="YouTube video player" width="160" height="100" src="http://www.youtube.com/embed/zXV8GMSc5Vg?enablejsapi=1&amp;origin=http%3A%2F%2Ffiddle.jshell.net"></iframe>
<br/>
Two:
<iframe frameborder="0" allowfullscreen="1" title="YouTube video player" width="160" height="100" src="http://www.youtube.com/embed/LTy0TzA_4DQ?enablejsapi=1&amp;origin=http%3A%2F%2Ffiddle.jshell.net"></iframe>

Edit: Check out Jennie Sadler's fine-tuned version below if your videos start as thumbnails.

Upvotes: 17

Jennie Sadler
Jennie Sadler

Reputation: 83

vbence's solution is really close, but there's one edit I would suggest. You should check that the other players are playing before you pause them, otherwise, playing the first embed on the page will play/pause every other embed on the page, removing the preview thumbnail and creating startling side-effects.

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

function onYouTubeIframeAPIReady() {
    var $ = jQuery;
    var players = [];
    $('iframe').filter(function(){return this.src.indexOf('http://www.youtube.com/') == 0}).each( function (k, v) {
        if (!this.id) { this.id='embeddedvideoiframe' + k }
        players.push(new YT.Player(this.id, {
            events: {
                'onStateChange': function(event) {
                    if (event.data == YT.PlayerState.PLAYING) {
                        $.each(players, function(k, v) {
                            if (this.getPlayerState() == YT.PlayerState.PLAYING # checks for only players that are playing
                                  && this.getIframe().id != event.target.getIframe().id) { 
                                this.pauseVideo();
                            }
                        });
                    }
                }
            }
        }))
    });
}
</script>

One: 
<iframe frameborder="0" allowfullscreen="1" title="YouTube video player" width="160" height="100" src="http://www.youtube.com/embed/zXV8GMSc5Vg?enablejsapi=1&amp;origin=http%3A%2F%2Ffiddle.jshell.net"></iframe>
<br/>
Two:
<iframe frameborder="0" allowfullscreen="1" title="YouTube video player" width="160" height="100" src="http://www.youtube.com/embed/LTy0TzA_4DQ?enablejsapi=1&amp;origin=http%3A%2F%2Ffiddle.jshell.net"></iframe>

Upvotes: 8

Matt Koskela
Matt Koskela

Reputation: 5317

Instead of using iframes, you actually want to use the iFrame Player API. Depending on how many videos you actually wanted to embed, you might want to make this javascript more dynamic, but this working example should give you enough to get started.

Basically what I'm doing here is initializing the two players, and pausing the opposite video when a player state changes to play.

You can play with the following code at http://jsfiddle.net/mattkoskela/Whxjx/

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

var player;
function onYouTubeIframeAPIReady() {
    player1 = new YT.Player('player1', {
        height: '293',
        width: '520',
        videoId: 'zXV8GMSc5Vg',
        events: {
            'onStateChange': onPlayerStateChange
        }
    });
    player2 = new YT.Player('player2', {
        height: '293',
        width: '520',
        videoId: 'LTy0TzA_4DQ',
        events: {
            'onStateChange': onPlayerStateChange
        }
    });
}

function onPlayerStateChange(event) {
    if (event.data == YT.PlayerState.PLAYING) {
        stopVideo(event.target.a.id);
    }
}

function stopVideo(player_id) {
    if (player_id == "player1") {
        player2.stopVideo();
    } else if (player_id == "player2") {
        player1.stopVideo();
    }
}

Upvotes: 8

Related Questions