1

This is a bit of a repost, but none of the accepted answer uses the api in conjunction with JQuery events, if the do then the answer is incomplete. Past answer: Twitter Bootstrap Modal stop Youtube video

I wonder how to to get a Youtube Iframe to start playing automatically, when a bootstrap modal is opened through a link. The video should stop playing when the modal is dismissed. I looked at many of the answers, but none shows me a next to complete answer. So how do you use JQuery events from bootstrap (show.bs.modal/hide.bs.modal) to start/stop the video? The following code works in Firefox if I press play on the video when the page(modal) first loads, then dismiss the modal and reopen it. This does not work in Safari or Chrome.

I looked at the documentation but can´t still get it to work: https://developers.google.com/youtube/iframe_api_reference

here is my code! html:

<div class="modal fade" id="video_modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
                    </div>
                    <div class="modal-body">
                        <iframe id="player" type="text/html" width="640" height="360" src="http://www.youtube.com/embed/zg8KE6bEP50?version=3&rel=0&enablejsapi=1&origin=*&html5=1" frameborder="0" allowfullscreen></iframe>
                    </div>
                </div>
            </div>
        </div><!--/modal fade-->

Javascript:

jQuery( document ).ready(function() {
var tag = document.createElement('script');
tag.src = "//www.youtube.com/player_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
});

var player;

window.onYouTubePlayerAPIReady = function() {
player = new YT.Player('player', {
  events: {
    'onReady': onPlayerReady
  }
});
}
function onPlayerReady(event) {
$("video_modal").on('shown.bs.modal', function() {
    player.playVideo();
});
$("video_modal").on('hidden.bs.modal', function() {
    player.stopVideo();
});
}
Community
  • 1
  • 1
StenW
  • 1,964
  • 5
  • 24
  • 27

1 Answers1

2

You're starting with the iframe in your HTML. I think you need to replace that with a div with id player, then specify the videoID when you instantiate the player object in onYouTubeIframeAPIReady. Like this:

<div class="modal fade" id="video_modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
            </div>
            <div class="modal-body">
                <div id="player"></div>
            </div>
        </div>
    </div>
</div><!--/modal fade-->
jQuery( document ).ready(function() {
    var tag = document.createElement('script');
    tag.src = "https://www.youtube.com/iframe_api";
    var firstScriptTag = document.getElementsByTagName('script')[0];
    firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);


    jQuery("#video_modal").on('shown.bs.modal', function() {
        if(typeof player.playVideo == 'function') {
            player.playVideo();
        } else {
            var fn = function(){
                player.playVideo();
            };
            setTimeout(fn, 200);
        }
    });
    jQuery("#video_modal").on('hidden.bs.modal', function() {
        player.stopVideo();
    });
});

var player;

function onYouTubeIframeAPIReady() {
    player = new YT.Player('player', {
        videoId: 'zg8KE6bEP50',
    });
}

Also, there were some other minor errors, like you needed some pound signs for the video_modal id, and I changed tag.src from player_api to iframe_api.

Edit: Posted full JS, as there were a few other minor errors.

Edit^2: So I think that onYouTubeIframeAPIReady's onReady event doesn't even fire until the video is visible (which happens as a result of show.bs.modal). So the first time onPlayerReady is called, show.bs.modal has already fired, and only after that does jQuery register the show.bs.modal event. I changed the code above to register your modal shown/hidden events right from document ready, and if the playVideo method doesn't exist yet, it will try again a little later. It's kind of hacky, but I'm sure you can improve on it.

I'm not sure if that made too much sense, so here's a diagram of sorts of what was happening:

click modal button -> shown.bs.modal fires -> player onReady fires -> calls onYouTubeIframeAPIReady -> register event listener for shown.bs.modal to play video
ebenpack
  • 458
  • 1
  • 6
  • 13
  • 1
    See my edits! Which I haven't made yet, but am about to! – ebenpack Jan 30 '14 at 16:42
  • One problem popped up: Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('https://www.youtube.com') does not match the recipient window's origin ('http://rollnstroll.se'). I guess I just have to add orgin to the player, it is not specified how to do this in the api instructions. – StenW Jan 30 '14 at 17:04
  • THx man, your diagram is what I have been chasing for two days. But its easier to visualize it then to actually code it. BTW it works! THx man, all I had to do was to add orgin: '*' to the player options. Thank you so much for straightening out my shit! – StenW Jan 30 '14 at 17:12
  • No problem :). The API is pretty good, but a lot of stuff doesn't seem to be documented (like onReady not firing until the frame is actually visible). – ebenpack Jan 30 '14 at 17:18
  • The biggest problem is the documentation. Im pretty shitty at writing javascript, but if you can look at some examples you get an understanding for why things are done they way they are, not just how. – StenW Jan 30 '14 at 17:53