Pause YouTube iframe embed when playing another
Asked Answered
H

6

10

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.

Hersch answered 18/2, 2013 at 18:26 Comment(0)
E
9

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();
    }
}

Esoterica answered 19/2, 2013 at 7:43 Comment(2)
Matt, thank you so much. That's great. For the time being it's just the 2 videos I need to work with, but i'm sure I can figure it out if I need to add any more. Thank you :)Hersch
Hi Matt, sorry to trouble you but i've just tested my site in IE8 and it's only showing one videohttp://www.lornanaylorhomeopath.co.uk/testarea/site/benefits_of_homeopathy/index.htm It reporting back the following error: Webpage error details Message: Object doesn't support this property or method Line: 52 Char: 2 Code: 0 URI: lornanaylorhomeopath.co.uk/testarea/assets/generic.js If it's a big deal, i'm really really not fussed as I can just revert to using regular embedded iFrames. But just thought i'd ask :)Hersch
K
17

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.

Kyleekylen answered 29/4, 2014 at 16:15 Comment(1)
This should really be the accepted answer. This is a much more robust solution. Thanks!Underlie
E
9

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();
    }
}

Esoterica answered 19/2, 2013 at 7:43 Comment(2)
Matt, thank you so much. That's great. For the time being it's just the 2 videos I need to work with, but i'm sure I can figure it out if I need to add any more. Thank you :)Hersch
Hi Matt, sorry to trouble you but i've just tested my site in IE8 and it's only showing one videohttp://www.lornanaylorhomeopath.co.uk/testarea/site/benefits_of_homeopathy/index.htm It reporting back the following error: Webpage error details Message: Object doesn't support this property or method Line: 52 Char: 2 Code: 0 URI: lornanaylorhomeopath.co.uk/testarea/assets/generic.js If it's a big deal, i'm really really not fussed as I can just revert to using regular embedded iFrames. But just thought i'd ask :)Hersch
H
8

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>
Hypothermia answered 15/7, 2016 at 22:31 Comment(1)
If using https, you will need to update the iframe line to include the s.Isotonic
S
0

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();
                }
              });
            }
          },
        },
      })
    );
  });
}
Saiff answered 25/3, 2022 at 9:55 Comment(0)
M
0

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 = "";
 }
Mezereum answered 1/9, 2022 at 19:58 Comment(0)
I
0

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();
                        }
                    });
                }
            }
        }
    }))
});

}

Isotonic answered 17/11, 2022 at 7:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.