onYouTubeIframeAPIReady() not firing
Asked Answered
F

4

26

I've looked through so many questions and the youtube api stuff but for the life of me can't figure out why the onYouTubeIframeAPIReady is not working.

Here is my iframe:

<iframe id="youtube_vid" width="763" height="430" src="https://www.youtube.com/embed/dlJshzOv2cw?theme=light&amp;showinfo=0&amp;rel=0&amp;enablejsapi=1" frameborder="0" allowfullscreen=""></iframe>

And my script:

function callYTapi() {

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

    function onYouTubeIframeAPIReady() {
        console.log('IframeAPI = Ready');
        var player = new YT.Player('youtube_vid', {
            events: {
                'onReady': onPlayerReady,
                'onStateChange': onPlayerStateChange
            }
        });
    }

    function onPlayerReady(event) {
        event.target.playVideo();
    }

    function onPlayerStateChange(event) {
        if (event.data == YT.PlayerState.PAUSED) {
            console.log("Paused");
        }

        if (event.data == YT.PlayerState.PLAYING) {
            console.log("Playing");
        }

        if (event.data == YT.PlayerState.ENDED) {
            end(); 
        }
    }
}

I get the console.log for the loaded script but not for Iframe ready or anything else. Any ideas? Thanks

Faradize answered 10/4, 2014 at 16:36 Comment(1)
Possible duplicate of Youtube iframe api not triggering onYouTubeIframeAPIReadyBanter
I
47

The callback functions must be in the global scope. Just move onYouTubeIframeAPIReady and the others outside callYTapi.

Isauraisbel answered 10/4, 2014 at 20:59 Comment(5)
Yes I just realized that! Thanks Vincius! I needed it in that function so I changed to window.onYouTubeIframeAPIReady() = function (){} and all is well...in case anyone was wondering.Faradize
I had a similar problem. For some reason the cover images wasn't loading up. I wrapped the API in the function window.onYouTubeIframeAPIReady() = function (){} and it works. Thanks!Paperboy
i couln't able to get video url by player object while accessing same video id on second timeGaribull
A bit more clarification if someone is still wondering - onYouTubeIframeAPIReady() function must be defined globally. Simply replace the line "function onYouTubeIframeAPIReady() {...." with "window.onYouTubeIframeAPIReady = function() {...."Auckland
Perfect. Exactly my issue and quick solution. Thanks.Tautonym
R
9

Fortunately for me, after a lot of experimenting with console, I had something concrete. I kind of had the same issue until a day ago and figured out how to do when I was within a singleton scope.

Here is what my code looks like:

var XT = XT || {};

window.onYouTubeIframeAPIReady = function(){
    setTimeout(XT.yt.onYouTubeIframeAPIReady,500);
}

XT.yt = {

/* load the YouTube API first */
loadApi: function () {

        var j = document.createElement("script"),
            f = document.getElementsByTagName("script")[0];
        j.src = "//www.youtube.com/iframe_api";
        j.async = true;
        f.parentNode.insertBefore(j, f);
        console.log('API Loaded');
    },

/*default youtube api listener*/
onYouTubeIframeAPIReady: function () {
    console.log('API Ready?');
    window.YT = window.YT || {};
    if (typeof window.YT.Player === 'function') {
        player = new window.YT.Player('player', {
            width: '640',
            height: '390',
            videoId: 'nE6mDCdYuwY',
            events: {
                onStateChange: XT.yt.onPlayerStateChange,
                onError: XT.yt.onPlayerError,
                onReady: setTimeout(XT.yt.onPlayerReady, 4000)
            }
        });
    }
},


onPlayerReady: function() {
    player.playVideo(); /* start the video */
    player.setVolume(1); /* set volume to 1 (accepts 0-100) */
},

onPlayerStateChange: function (e) {
    console.log(e.data, YT.PlayerState.PLAYING, e.data === YT.PlayerState.PLAYING);
    var video_data = e.target.getVideoData();

    //do something on video ends
    if(e.data === YT.PlayerState.ENDED)
    this.onPlayerStop();
},

onPlayerStop: function(){
    //console.log('video ended');
},

onPlayerError: function (e) {
    console.log( "youtube: " + e.target.src + " - " + e.data);
},

init: function () {
    this.loadApi();
}

}

XT.yt.init();
Rawdon answered 2/1, 2015 at 21:34 Comment(4)
Also, for some weird reason I get an error on the consoles. On Chrome: "Uncaught TypeError: undefined is not a function".Rawdon
Playing around and inserting setTimeout(function (){}, 1) to a few places did the trick for meCobaltic
Works for me using setTimeoutPit
Been trying different solutions. This seems to be working for me. Thanks!!Saltcellar
L
8

Just to be clear, the accepted answer above seems to work for me in this way:

Load API (from yt documentation)

var tag = document.createElement('script');

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

specify YouTube's built-in ready function "onYouTubeIframeAPIReady" on window

window.onYouTubeIframeAPIReady = this.onYTready;

So this.onYTready is my function name and located elsewhere. I can confirm my onYTready function can console logs/debugger breakpoints in Chrome.

(edit) you may want to bind this to your function, example:

window.onYouTubeIframeAPIReady = this.onYTready.bind(this);

or 'this' will be for window instead of a specific view you may be using..

Latea answered 10/6, 2016 at 19:0 Comment(1)
This method of specifically assigning the onYouTubeIframeReady event to window was the solution I was looking for when integrating the YouTube API with webpack.Temekatemerity
O
1
function playIframeVideo(iframe) {
    iframe.videoPlay = true; //init state
    iframe.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}', '*');
}

function pauseIframeVideo(iframe) {
    iframe.videoPlay = false; //init state
    iframe.contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}', '*');
}

$('.vc_video-bg-container').on('click', function () {

    var iframe = $('iframe').get(0); //iframe tag

    if (iframe.videoPlay != true) {
        playIframeVideo(iframe);
    } else {
        pauseIframeVideo(iframe);
    }
});
Ocana answered 22/11, 2017 at 12:48 Comment(2)
Consider explaining your answer before helping with the codeHim
This solution is helped me to fire play video on WPBakery page builder in background video for row.Perceptible

© 2022 - 2024 — McMap. All rights reserved.