web-dev-qa-db-fra.com

Youtube iframe api ne se déclenche pas surYouTubeIframeAPIReady

Je me bats avec l'ifi iframe youtube depuis un certain temps déjà. D'une manière ou d'une autre, la méthode onYouTubeIframeAPIReady n'est pas toujours déclenchée. 

D'après les symptômes, cela semble être un problème de chargement. Aucune erreur n'est affichée dans l'inspecteur.

Voici mon code:

HTML

<div id="player"></div>
          <script>
            videoId = 'someVideoId';
            var tag = document.createElement('script');
            tag.src = "//www.youtube.com/iframe_api";
            var firstScriptTag = document.getElementsByTagName('script')[0];
            firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
          </script>

JS

(appelé à la fin de la page. J'ai essayé de placer le code juste après le script ci-dessus et le résultat était le même.)

var isReady = false
  , player
  , poster
  , video;

$(function () {
$('.js-play').click(function (e) {
    e.preventDefault();
    interval = setInterval(videoLoaded, 100);
  });
});
function onYouTubeIframeAPIReady() {
  console.log(videoId)
  player = new YT.Player('player', {
    height: '445',
    width: '810',
    videoId: videoId,
    events: {
      'onReady': onPlayerReady//,
      //'onStateChange': onPlayerStateChange
    }
  });
}

function onPlayerReady(event) {
  isReady = true;
  console.log("youtube says play")
}

function videoLoaded (){
  if (isReady) {
      console.log("ready and play")
      poster.hide();
      video.show();

      $('body').trigger('fluidvideos');

      player.playVideo();
      clearInterval(interval);
  } 
}

Le problème est que parfois, rien n’est imprimé par le console.log et rien ne se passe.

Sur les téléphones mobiles, cela se produit tout le temps. Des idées?

34
jribeiro

Ce n'est pas un problème de délai d'attente, et vous ne devriez pas avoir besoin d'activer cette fonction manuellement.

Assurez-vous que votre fonction onYouTubeIframeAPIReady est disponible au niveau global et non imbriquée (cachée) dans une autre fonction.

63
bcm

Vous pouvez toujours l'ajouter à l'objet window pour vous assurer qu'il est évoqué globalement. Ceci est utile si votre code utilise AMD.

window.onYouTubeIframeAPIReady = function() {}
42
Erick R Soto

Si vous devez intégrer une fonction, une solution possible est Au lieu de:

function onYouTubeIframeAPIReady() {
  // func body...
}

vous pouvez le déclarer comme ceci:

window.onYouTubeIframeAPIReady = function() {
  // func body...
}

Dans ce cas, assurez-vous d’insérer le script dans le dom après la déclaration (l’appel insertBefore() appelle ce qui est dans la portée globale de votre cas):

9
Pengő Dzsó

Si vous chargez le code de l'API IFrame Player de manière asynchrone comme suit:

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

et vous chargez également le code de script comme ceci:

<script src="http://www.youtube.com/player_api"></script>

alors la fonction onYouTubeIframeAPIReady ne sera pas appelée car le même code est chargé deux fois (la fonction est appelée une seule fois lorsque l'api est complètement chargé).

Utilisez donc l’un des moyens selon vos besoins.

7
Joar

Après avoir revisité cela, j’ai trouvé une solution qui me convenait lors de l’utilisation de webpack (ou de tout autre système de module commongJS). forme de promesse callback:

var checkYT = setInterval(function () {
    if(YT.loaded){
        //...setup video here using YT.Player()

        clearInterval(checkYT);
    }
}, 100);

Cela semblait être le plus sûr des erreurs dans mon cas.

3
Joao

Assurez-vous de tester la page en la faisant servir sur le Web, pas seulement chargée localement. Le comportement de l'API YouTube iFrame est incohérent/non déterministe

3
Ben Wheeler

J'ai eu un problème similaire. Dans mon cas, YouTube a été appelé si rapidement que l'implémentation réelle n'était pas prête pour le bon appel. Donc, après l'appel de youtube player_api, j'ai ajouté une implémentation simple avec une variable permettant la vérification de onYouTubeIframeAPIReady juste comme ça:

<script src="http://www.youtube.com/player_api"></script>
<script>
var playerReady = false
window.onYouTubeIframeAPIReady = function() { //simple implementation
    playerReady = true;
}
</script>
</header>
.
.
.
<body>
<script>
window.onYouTubeIframeAPIReady = function() { //real and fully implemented
    var player; // ... and so on ...
}
if(playerReady) { onYouTubeIframeAPIReady(); console.log("force to call again") }
</script>
0
Diogo Garcia

J'ai en fait fait cela pour charger paresseux le lecteur youtube. Semble la preuve de balle pour moi.

window.videoApiLoaded = [];
window.videoApiLoaded.youtube = false;

function loadYoutubeVideo(videoId) {

    window.onYouTubeIframeAPIReady = function() { document.dispatchEvent(new CustomEvent('onYouTubeIframeAPIReady', {})) };

    if(window.videoApiLoaded.youtube == false) {
        var tag = document.createElement('script');
        tag.src = "https://www.youtube.com/iframe_api";
        var firstScriptTag = document.getElementsByTagName('script')[0];
        firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
        window.videoApiLoaded.youtube = true;
    }

    var player;

    document.addEventListener('onYouTubeIframeAPIReady', function (e) {
        player = new YT.Player('player', {
          height: '400',
          width: '600',
          videoId: videoId,
          events: {
            'onStateChange': onYtStateChange
          }
        });

    }, false);

}
0
Matt Loye