frumbert
frumbert

Reputation: 2427

load youtube iframe_api on demand and then use it

I have a page that can be deployed in an offline situation, and want to handle playing youtube videos in a particular container on screen. I don't want to load iframe_api from youtube until it's needed, since there's a large chance it won't be.

function EmbedAndPlay_Youtube(videoid, container) {
// todo: allow script caching
$.getScript("//www.youtube.com/iframe_api")
    .fail(function () {
        // some kind of alert to the user ...
    })
    .done(function () {
        var $container = $(container);
        var w = $(container).width(),
            h = $(container).height(),
            player = new YT.Player('ytvideo', {
                height: h,
                width: w,
                videoId: videoid,
                events: {
                    'onReady': function (event) {
                        event.target.playVideo(); 
                    }
                }

            });
    });
}

sometimes, depending on the platform and its network capability, I get a script undefined kind of error, which I think means that the "done" function has executed before the youtube script has finished executing itself.

Is there a way to ensure that the loaded script has finished executing before calling a "done" method?

Upvotes: 0

Views: 2542

Answers (1)

Bernardo Domingues
Bernardo Domingues

Reputation: 391

Your problem there is that the script loaded async in the url //youtube.com/player_api loads another script asynchronously (the JS player itself, which defines YT.Player). In your case, your done() callback is called when the script is loaded, but the player script may not be loaded yet. (Technically, the script in //youtube.com/player_api is just a loader)

To use YT.Player safely, bind your callback to window.onYouTubeIframeAPIReady, which is called by YouTube's script:

function EmbedAndPlay_Youtube(videoid, container) {
    $.getScript("//www.youtube.com/iframe_api")
    .fail(function () {
        // some kind of alert to the user ...
    })
    .done(function () {
        window.onYouTubeIframeAPIReady = function () {
            var $container = $(container);
            var w = $(container).width(),
            h = $(container).height(),
            player = new YT.Player('ytvideo', {
                height: h,
                width: w,
                videoId: videoid,
                events: {
                    'onReady': function (event) {
                        event.target.playVideo(); 
                    }
                }
            });
        }
    });
}

Upvotes: 1

Related Questions