it-swarm.com.de

Youtube iframe api löst kein onYouTubeIframeAPIReady aus

Ich kämpfe schon seit geraumer Zeit mit dem Youtube-iframe-API. Irgendwie wird die Methode onYouTubeIframeAPIReady nicht immer ausgelöst. 

Aus den Symptomen scheint es ein Ladeproblem zu sein. Im Inspector werden keine Fehler angezeigt.

Hier ist mein 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

(Aufruf am Ende der Seite. Ich habe versucht, den Code direkt nach dem obigen Skript zu platzieren, und das Ergebnis war dasselbe.)

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

Das Problem ist, dass manchmal nichts vom console.log gedruckt wird und nichts passiert.

Auf Mobiltelefonen geschieht dies ständig. Irgendwelche Ideen?

34
jribeiro

Es ist kein Timeout-Problem, und Sie sollten diese Funktion nicht manuell auslösen müssen.

Stellen Sie sicher, dass Ihre onYouTubeIframeAPIReady-Funktion auf globaler Ebene verfügbar ist und nicht in einer anderen Funktion verschachtelt (ausgeblendet) wird.

63
bcm

Sie können es immer an das Fensterobjekt anhängen, um sicherzustellen, dass es global aufgerufen wird. Dies ist hilfreich, wenn Ihr Code AMD verwendet.

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

Wenn Sie eine Funktion in eine Funktion einfügen müssen, ist eine mögliche Lösung .__ anstelle von:

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

sie können es so erklären:

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

Stellen Sie in diesem Fall sicher, dass Sie das bestimmte Skript nach der Deklaration in den dom einfügen (der Aufruf von insertBefore(), was jetzt in Ihrem Fall im globalen Bereich liegt)

9
Pengő Dzsó

Wenn Sie den IFrame Player-API-Code asynchron wie folgt laden:

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

und Sie laden den Skriptcode auch so:

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

dann wird die Funktion onYouTubeIframeAPIReady nicht aufgerufen, da derselbe Code zweimal geladen wird (die Funktion wird nur einmal aufgerufen, wenn das API vollständig geladen ist).

Verwenden Sie also eine der Möglichkeiten, die Ihren Bedürfnissen entspricht.

7
Joar

Nachdem ich dies erneut besprochen hatte, fand ich eine funktionierende Lösung für mich, wenn ich webpack verwende (oder ich gehe von einem anderen commongJS-Modulsystem aus), oder wenn Sie feststellen, dass die Youtube-API vor Ihrer eigenen JS-Datei bereit ist, ein Intervall zu verwenden war - bis Youtube ein solches bereitstellt Form des Versprechensrückrufs:

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

        clearInterval(checkYT);
    }
}, 100);

Dies schien in meinem Fall der fehleranfälligste zu sein.

3
Joao

Stellen Sie sicher, dass Sie die Seite testen, indem Sie sie tatsächlich im Web bereitstellen und nicht nur lokal laden. Das Verhalten der YouTube-iFrame-API ist inkonsistent/nicht deterministisch

3
Ben Wheeler

Ich hatte ein ähnliches Problem. In meinem Fall wurde onYouTubeIframeAPIReady so schnell aufgerufen, dass die tatsächliche Implementierung nicht für den richtigen Aufruf bereit war. Nach dem Aufruf von youtube player_api habe ich also eine einfache Implementierung mit einer var zur Verifizierung von onYouTubeIframeAPIReady hinzugefügt:

<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

Ich habe das eigentlich zum faulen Laden des Youtube-Players gemacht. Kommt mir kugelsicher vor.

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