2016-06-14 38 views
6

編輯 - 2016年6月25日
(我打消了我6月16日更新,因爲不再相關
 。     我離開了我下面的OP ...)JavaScript事件監聽器退出從聽... YouTube的API(?) - 無控制檯錯誤



我花了4小時今日上。
現在情況如下:

我的功能作品兩個鏈接。
視頻參數在數組中定義。
其他兩個鏈接不起作用。

對於鏈接#3和#4,我得到一個Uncaught TypeError: thisPlayer.loadVideoById is not a function
但是,相同的功能適用於鏈接#1和#2。

看起來像youtube對象只是定義了兩個第一。
爲什麼?

請,有一個近距離觀察到控制檯這個活鏈接:
https://www.bessetteweb.com/?p=youtube-video-test
我插入的console.log messagess的很多講清楚。

這裏是我的實際代碼:

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



這裏是我的控制檯日誌的快照: Console-log



--------- --------
他重新是我的原始後 - 6月14日:

我已經花了6個小時了。
(加1編輯這個問題!)

我有種調試的最後4行吧。

問題是我得到NO控制檯錯誤作爲提示。



理念:
我要鏈接衆多YouTube視頻到文本鏈接。
用戶想要的效果是能夠在閱讀文本時點擊引文鏈接...爲了能夠確認引文。
視頻不能完全播放。

視頻應以特定的時間碼開始並以特定的時間碼結束。
獎勵複雜度:所有這些都希望以模態視圖樣式顯示。

我的代碼WORKED相當快爲ONE視頻。 See here

我基於我的代碼this tutorial,並迅速成功。

然後,將具有這方面的工作...
我有必要建立陣列來處理多個視頻。
對於鏈接ID,玩家ID,開始/結束的時間碼...和聽衆!
有趣的開始!

就像這樣說,我在這一天度過了大半天。 我總是遇到錯誤作爲明確(LOLLL)指南的控制檯錯誤。

我對我的工作感到滿意......這是我認爲正確的方向。
這幾乎是工作...


但是這一次,沒有任何錯誤! See here(檢查控制檯!)

熱點問題研究!沒有錯誤?!?
我的手臂現在被砍掉。
事實上,第一場表演,但視頻沒有開始......第二個看起來完全迷失在陰霾中。

在控制檯日誌消息中,我看到第一個發生的onStateChange偵聽器,它是-1(未啓動)。但是之後 ???它死了!
Arrgg!

我不得不超越我的驕傲......並把它作爲一個問題在StackOveflow。
;)



我的全代碼(多鏈路):
這是一個通過AJAX ......因此,所有外部ressources如jQuery已經載入稱爲頁。

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

回答

7

有使用iframe Player API的暫時性問題,你可以讀到這裏:https://code.google.com/p/gdata-issues/issues/detail?id=4706

作爲一個臨時的解決辦法,你只需要在onReady事件中添加事件偵聽器:

function onReady() { 
player.addEventListener('onStateChange', function(e) { 
console.log('State is:', e.data); 
}); 
} 

此外,正如Google代碼問題主題中提到的人,您設置一個時間間隔並輪詢播放器的當前狀態,而不是偵聽onStateChange事件。以下是一個示例代碼片段:

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

看起來像是找到我的修復程序的正確線索。我必須先嚐試才能接受。但是,由於它看起來很嚴肅,我贊成它。我有一個30分鐘開始的晚間會議......所以我會認真檢查一下。謝謝! –

+0

不用擔心隊友! –

+0

我嘗試了這個間隔的想法...我現在得到一些新的東西。但我仍然在樹林裏。現在我得到playerState = 5(視頻提示)1秒。然後3(緩衝)80毫秒。在此之後,時間間隔不斷計算,玩家狀態在-1(未啓動)上被阻塞。請參閱我的[正在進行中的工作鏈接](https://www.bessetteweb.com/?p=youtube-video-test)上的控制檯我將編輯該問題以顯示我的修改後的代碼。 –