2016-06-14 76 views
6

EDIT - 2016/06/25
(ho tolto il mio aggiornamento 16 giugno, in quanto non rilevante più
 .     ho lasciato il mio OP qui sotto ...)Javascript Event Listener si chiude da ascoltare ... Youtube API (?) - Nessun errore console



ho passato un altro 4 ore su questo oggi.
Qui è la situazione oggi:

La mia funzione FUNZIONA per due collegamenti.
I parametri video sono definiti in una matrice.
Gli altri due collegamenti non funzionano.

Ottengo uno Uncaught TypeError: thisPlayer.loadVideoById is not a function per i collegamenti 3 e 4.
MA LA STESSA funzione funziona bene per i collegamenti 1 e 2.

Sembra che gli oggetti di YouTube siano definiti solo per i primi due.
PERCHÉ?

prega, hanno uno sguardo da vicino alla console su questo link live:
https://www.bessetteweb.com/?p=youtube-video-test
ho inserito un sacco di messagess console.log mettere in chiaro.

Ecco il mio codice vero e proprio:

// Global variable for the player 
var player = []; 
var statePlaying=false; 

playerArr = [{ 
      linkID:"link0", 
      divID:"player1", 
      ytID:"5V_wKuw2mvI", // Heavy metal playlist 
      start:20, 
      end:30 
      }, 
      { 
      linkID:"link1", 
      divID:"player2", 
      ytID:"u9Dg-g7t2l4", // Disturbed 
      start:10, 
      end:20 
      }, 
      { 
      linkID:"link2", 
      divID:"player3", 
      ytID:"39b5v3-d6ZA", // Maiden 
      start:30, 
      end:40 
      }, 
      { 
      linkID:"link3", 
      divID:"player4", 
      ytID:"z8ZqFlw6hYg", // Slayer 
      start:120, 
      end:136 
      }]; 

// This function gets called when API is ready to use 
function onYouTubePlayerAPIReady() { 

    // Binding events loop 
    console.log("playerArr.length: "+playerArr.length); 
    for(i=0;i<playerArr.length;i++){ 
     console.log(""); 
     console.log("onPlayerReady for loop ->i: "+i); 

     var playButton = document.getElementById(playerArr[i].linkID); 
     console.log("playButton.id: "+playButton.id); 

     var thisArr = playerArr[i]; 
     console.log("playerArr[i] object (below): "); 
     console.log(thisArr); 

     playButton.addEventListener("click", function() { 
      thisLinkID = $(this).attr("id").replace("link",""); 

      console.log(""); 
      console.log("------------------"); 
      console.log("Link #"+(parseInt(thisLinkID)+1)+" clicked."); 
      console.log("------------------"); 

      var ytID = playerArr[thisLinkID].ytID; 
      var start = playerArr[thisLinkID].start; 
      var end = playerArr[thisLinkID].end; 

      var thisPlayer = new YT.Player(playerArr[thisLinkID].divID); 

      console.log("ytID: "+ytID); 
      console.log("start: "+start); 
      console.log("end: "+end); 
      console.log(""); 

      console.log("Below are the google ads, blocked by AdBlocker."); 

      $("#ytplayerModal").css({"display":"block"}); 
      $("#ytplayerModal").animate({"opacity":"0.7"},1000,function(){ 

       console.log(""); 
       console.log("player show()"); 
       $(".ytplayer").show(); 

       console.log("Youtube player object:"); 
       console.log(thisPlayer); 
       console.log(""); 
       console.log('loadVideoById() parameters --\> videoId:'+ytID+', startSeconds:'+start+', endSeconds:'+end); 

       thisPlayer.loadVideoById({'videoId':ytID, 'startSeconds':start, 'endSeconds':end}); 
       console.log(""); 
      }); 

      // Bugfix - Set Interval instead of listener 
      setTimeout(function(){ 
       var IntervalCounter=0; 
       listenerInterval = setInterval(function() { 

        var state = thisPlayer.getPlayerState(); //player[thisLinkID].getPlayerState(); 
        var stateMsg; 

        switch (state){ 
         case -1: stateMsg="unstarted"; thisPlayer.playVideo(); console.log("player["+thisLinkID+"]"); break; 
         case 0: stateMsg="ended"; break; 
         case 1: stateMsg="playing"; break; 
         case 2: stateMsg="paused"; break; 
         case 3: stateMsg="buffering"; break; 
         case 5: stateMsg="video cued"; break; 
         default: stateMsg="Undefined player state..."; 
        } 
        console.log(state+" : "+stateMsg); 

        if(state==1){ 
         statePlaying=true; 
        } 

        // Closes the modal 
        if((statePlaying) && (state==0)){ 
        //if((statePlaying) && (stateObj.data==0)){ 
         setTimeout(function(){ 
          console.log("Closing Modal"); 
          $(".ytplayer").css({"display":"none"}); 
          $("#ytplayerModal").animate({"opacity":"0"},1000,function(){ 
           $("#ytplayerModal").css({"display":"none"}); 
          }); 
          statePlaying=false; 
         },500); 
         clearInterval(listenerInterval); 
         console.log("Interval loop stopped on video end.") 
        } 

        // Stop the interval at 1000... Endless instead! 
        IntervalCounter++; 
        if((IntervalCounter>999)&&(state!=1)&&(state!=2)&&(state!=0)){ 
         clearInterval(listenerInterval); 
         console.log("Interval loop willingly stopped. Endless otherwise.") 
        } 
       }, 10); 
      },1100); // Interval setTimeout 
     }); 
    } 
} 

// Inject YouTube API script 
var tag = document.createElement('script'); 
tag.src = "//www.youtube.com/player_api"; 
var firstScriptTag = document.getElementsByTagName('script')[0]; 
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); 



Ecco un'istantanea della mia log della console: Console-log



--------- --------
Lui è il mio post originale - 14 giugno:

Ho trascorso 6 ore su questo già.
(più 1 modifica a questa domanda!)

sto tipo di debug delle ultime 4 righe di esso.

Il problema è che non ricevo NESSUN errore di console come suggerimento.



Concetto:
voglio collegare numerosi video di YouTube per collegamenti di testo.
L'effetto desiderato per l'utente è di poter cliccare su un link di citazione durante la lettura di un testo ... Per poter confermare la citazione.
Il video NON deve giocare interamente.

Il video deve iniziare con un determinato codice temporale E terminare con un codice temporale specifico.
Complessità bonus: Tutto ciò deve essere mostrato in uno stile di visualizzazione modale.

Il mio codice LAVORATO abbastanza veloce per UNO video. See here.

Ho basato il mio codice su this tutorial e si è verificato rapidamente.

Poi, avendo questo lavoro ...
ho avuto la necessità di costruire matrici di gestire più video.
Per ID di collegamenti, ID giocatori, codici di tempo per inizio/fine ... E ASCOLTORI!
Il divertimento inizia!

Come detto, ho passato la maggior parte della mia giornata a questo. Ho sempre riscontrato bug CON gli errori di console come guide chiare (LOLLL).

Sono soddisfatto del mio lavoro ... Questo sta andando nella giusta direzione, penso.
Questo è quasi funziona ...


Ma questa volta, nessun errore! See here. (controllare la console!)

Whatt !!! NESSUN ERRORE?!?
Adesso le mie braccia sono state cancellate.
In effetti, il primo mostra ma il video non parte ... E il secondo sembra completamente perso nella foschia.

Nei messaggi di registro della console, vedo la prima occorrenza del listener onStateChange, che è -1 (Non avviato). Ma allora ??? Muore!
Arrgg!

Devo superare il mio orgoglio ... E portarlo come una domanda su StackOveflow.
;)



Il mio codice completo (per collegamenti multipli):
Questa è una pagina chiamata tramite la tecnologia AJAX ... Quindi tutte le risorse esterne come jQuery sono già caricati.

<style> 
.ytplayer{ 
    position:fixed; 
    z-index:2; 
    width:60%; 
    height:40%; 
    top:30%; 
    left:20%; 
    display:none; 
} 
#ytplayerModal{ 
    display:none; 
    background-color:#000; 
    opacity:0; 
    position:fixed; 
    z-index:1; 
    top:0; 
    left:0; 
    width:100%; 
    height:100%; 
} 
.ytTriggerPlay{ 
    text-decoration:underline; 
    color:dodgerblue; 
    cursor:pointer; 
} 
</style> 



<h1>Youtube modal trigger link test</h1> 
<br> 
<br> 
<div id="text"> 
    Lorem ipsum dolor sit amet, consectetur <a id="0" class="ytTriggerPlay">adipiscing elit</a>. Quisque feugiat lectus ut est vestibulum ornare. Vivamus felis nulla, facilisis id cursus non, pharetra non diam. Sed pellentesque turpis vel sem tincidunt consectetur. Aenean ut lorem erat. Donec ut tellus sed leo ultrices cursus. <a id="1" class="ytTriggerPlay">Cras varius libero</a> ut purus suscipit ultrices. Vivamus eget efficitur turpis. Aenean suscipit, dui nec luctus fringilla, neque tellus fringilla risus, et porta enim justo et turpis. Sed risus orci, vehicula sed eleifend eget, tincidunt ut turpis. Vestibulum in sapien non lacus tristique mattis id eget tortor.<br> 
    <br> 
    Proin est purus, maximus id nunc vel, consectetur tristique urna. Mauris cursus ipsum a varius luctus. Nunc interdum condimentum massa vitae rutrum. Morbi volutpat nec lorem eleifend malesuada. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Duis fringilla metus vel nunc elementum efficitur. Duis sed dolor diam. In eu ultrices libero, eget lobortis mi. Sed pretium orci non augue vehicula, eget placerat leo lacinia. Sed sed gravida dui. Lorem ipsum dolor sit amet, consectetur adipiscing elit. In bibendum, erat eget venenatis elementum, nulla enim posuere lacus, quis efficitur dolor ex quis ipsum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Phasellus volutpat finibus odio id venenatis. Fusce at leo libero. Cras eget velit sed justo egestas vehicula efficitur sit amet ex.<br> 
</div> 

<!--iframe id="ytplayer" type="text/html" width="720" height="405" src="https://www.youtube.com/embed/5V_wKuw2mvI?end=60&start=20" frameborder="0" allowfullscreen--> 

<div id="ytplayerModal"></div> 
<div id="player1" class="ytplayer"></div> 
<div id="player2" class="ytplayer"></div> 

<script> 
// https://developers.google.com/youtube/iframe_api_reference 
// https://css-tricks.com/play-button-youtube-and-vimeo-api/ 

// Global variable for the player 
var player = []; 
var statePlaying=false; 

playerArr = [{ 
      linkID:"0", 
      divID:"player1", 
      ytID:"5V_wKuw2mvI", // Heavy metal playlist 
      start:20, 
      end:40, 
      }, 
      { 
      linkID:"1", 
      divID:"player2", 
      ytID:"39b5v3-d6ZA", // Maiden 
      start:30, 
      end:60, 
      }]; 

// This function gets called when API is ready to use 

function onYouTubePlayerAPIReady() { 
    for(i=0;i<playerArr.length;i++){ 
     // Create the global player from the specific iframe (#video) 
     thisPlayer = new YT.Player(playerArr[i].divID, { 
      height: '352', 
      width: '640', 
      videoId: '5V_wKuw2mvI', 
      startSeconds:20, 
      endSeconds:40, 
      events: { 
       // Call this function when player is ready to use 
       // 'onReady': onPlayerReady   // Commented out willingly. 
      } 
     }); 
     player[i] = thisPlayer; 

    } 
    onPlayerReady(); 
} 

function onPlayerReady(event) { 

    // Binding events loop 
    console.log("playerArr.length: "+playerArr.length); 
    for(i=0;i<playerArr.length;i++){ 
     console.log(""); 
     console.log("onPlayerReady for loop ->i: "+i); 

     var playButton = document.getElementById(playerArr[i].linkID); 
     console.log("playButton.id: "+playButton.id); 

     var thisArr = playerArr[i]; 
     console.log("playerArr[i] object (below): "); 
     console.log(thisArr); 

     var thissPlayer = player[i]; 

     playButton.addEventListener("click", function() { 
      thisLinkID = parseInt($(this).attr("id")); 
      console.log("thisLinkID: "+thisLinkID); 

      var ytID = playerArr[thisLinkID].ytID; 
      var start = playerArr[thisLinkID].start; 
      var end = playerArr[thisLinkID].end; 

      console.log("ytID: "+ytID); 
      console.log("start: "+start); 
      console.log("end: "+end); 
      console.log("thissPlayer object (below): "); 
      console.log(thissPlayer); 

      $("#ytplayerModal").css({"display":"block"}); 
      $("#ytplayerModal").animate({"opacity":"0.7"},1000,function(thissPlayer,ytID,start,end){ 
       $(".ytplayer").show(); 

       player[thisLinkID].loadVideoById({videoId:ytID, startSeconds:start, endSeconds:end}); 
       setTimeout(function(){ 
        player[thisLinkID].playVideo(); 
       },500); 
      }); 
     }); 



     thissPlayer.addEventListener("onStateChange", function(stateObj){ 
      console.log("Player State: "+stateObj.data); 
      console.log("Again, thissPlayer object in the onStateChange listener (below)."); 
      console.log(thissPlayer); 
      // State sequence : -1, 3, 1, 2, 0, which is: Unstarted, Buffering, Playing, Paused, Ended. 

      if(stateObj.data==1){ 
       statePlaying=true; 
      } 
      console.log("Player State bolean memory: "+statePlaying); 

      // Closes the modal 
      if((statePlaying) && (stateObj.data==0)){ 
       setTimeout(function(){ 
        console.log("Closing Modal"); 
        $(".ytplayer").css({"display":"none"}); 
        $("#ytplayerModal").animate({"opacity":"0"},1000,function(){ 
         $("#ytplayerModal").css({"display":"none"}); 
        }); 
        statePlaying=false; 
       },500); 
      } 
     }); 
    } 
} 

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

risposta

7

C'è stato un problema temporaneo con l'API iFrame Player che potete leggere qui: https://code.google.com/p/gdata-issues/issues/detail?id=4706

Come una soluzione temporanea, è sufficiente aggiungere il listener evento nell'evento onReady:

Inoltre, come qualcuno menzionato nel thread di emissione del codice Google, si imposta un intervallo e si esegue il polling del lettore per il suo stato corrente invece di ascoltare l'evento onStateChange. Ecco un esempio di snippet di codice per farlo:

setInterval(function() { 
var state = player.getPlayerState(); 
if (playerState !== state) { 
onPlayerStateChange({ 
data: state 
}); 
} 
}, 10); 
+0

Sembra essere il giusto indizio per trovare la mia soluzione. Devo provare prima di accettare. Ma, dal momento che sembra serio, l'ho svalutato. Ho un incontro serale che inizia tra 30 minuti ... Quindi lo controllo seriamente domani. Grazie! –

+0

nessun problema amico! –

+0

Ho provato qualcosa con questa idea di intervallo ... Ora ho qualcosa di nuovo. Ma sono ancora nei boschi. Ora ottengo playerState = 5 (video cued) per 1 secondo. Quindi 3 (buffering) per 80 millisec. Dopodiché, l'intervallo ha un conteggio infinito e gli stati dei giocatori sono bloccati su -1 (non avviato). Vedi console sul mio [work in progress link] (https://www.bessetteweb.com/?p=youtube-video-test) I'll Modifica la domanda per mostrare il mio codice modificato. –