web-dev-qa-db-fra.com

onYouTubeIframeAPIReady () ne déclenche pas

J'ai parcouru tellement de questions et le contenu de l'API YouTube, mais je ne peux pas dire pourquoi mon onYouTubeIframeAPIReady ne fonctionne pas.

Voici mon 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>

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

Je reçois le fichier console.log pour le script chargé, mais pas pour Iframe ready ou quoi que ce soit d'autre. Des idées? Merci

18
JGVM

Les fonctions de rappel doivent être dans la portée globale. Il suffit de déplacer onYouTubeIframeAPIReady et les autres à l'extérieur callYTapi.

29
Vinicius Pinto

Heureusement pour moi, après avoir beaucoup expérimenté avec la console, j'avais quelque chose de concret. J'avais un peu le même problème jusqu'à il y a un jour et j'ai compris comment faire lorsque j'étais dans un domaine de singleton.

Voici à quoi ressemble mon code:

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();
5
johnanish

Pour être clair, la réponse acceptée ci-dessus semble fonctionner pour moi de la manière suivante:

API de chargement (à partir de la documentation de yt)

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

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

spécifier la fonction de préparation intégrée de YouTube "onYouTubeIframeAPIReady" dans la fenêtre

window.onYouTubeIframeAPIReady = this.onYTready;

Donc, this.onYTready est le nom de ma fonction et est situé ailleurs . Je peux confirmer que ma fonction onYTready peut consolider les points d'arrêt des journaux/débogueur dans Chrome.

(edit) vous pouvez vouloir lier ceci à votre fonction, exemple:

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

ou 'ceci' sera pour fenêtre au lieu d'une vue spécifique que vous utilisez peut-être.

3
mat
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);
    }
});