2016-06-14 22 views
6

EDIT - 2016/06/25
(Tôi đã gỡ bỏ bản cập nhật ngày 16 tháng 6 của tôi, vì không phù hợp nữa
 .     tôi rời OP của tôi dưới đây ...)Javascript Event Listener bỏ từ nghe ... Youtube API (?) - Không có lỗi console



tôi đã dành một 4 giờ ngày hôm nay này.
Đây là tình huống hiện tại:

Chức năng của tôi WORKS cho hai liên kết.
Thông số video được xác định trong một mảng.
Hai liên kết khác không hoạt động.

Tôi nhận được Uncaught TypeError: thisPlayer.loadVideoById is not a function cho các liên kết # 3 và # 4.
NHƯNG Chức năng CÙNG hoạt động tốt cho các liên kết # 1 và # 2.

Có vẻ như các đối tượng youtube chỉ được xác định cho hai lần đầu tiên.
TẠI SAO?

Xin vui lòng, có một cái nhìn gần gũi với giao diện điều khiển vào liên kết trực tiếp này:
https://www.bessetteweb.com/?p=youtube-video-test
tôi chèn A LOT của messagess console.log để làm cho nó rõ ràng.

Đây là mã thực tế của tôi:

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



Đây là một bản chụp của giao diện điều khiển đăng nhập của tôi: Console-log



--------- --------
Anh ấy re là bài đăng gốc của tôi - tháng thứ 14:

Tôi đã dành 6 giờ cho điều này rồi.
(cộng với 1 chỉnh sửa câu hỏi này!)

Tôi đang gỡ lỗi 4 dòng cuối cùng của nó.

Vấn đề là mà tôi nhận được lỗi giao diện điều khiển KHÔNG làm gợi ý.



Concept:
Tôi muốn liên kết nhiều video Youtube để liên kết văn bản.
Hiệu ứng mong muốn cho người dùng là có thể nhấp vào liên kết trích dẫn trong khi đọc văn bản ... Để có thể xác nhận trích dẫn.
Video KHÔNG phát hoàn toàn.

Video sẽ bắt đầu tại một mã thời gian cụ thể VÀ kết thúc tại một mã thời gian cụ thể.
Mức độ phức tạp của tiền thưởng: Tất cả điều này đều muốn được hiển thị theo kiểu xem phương thức.

Mã của tôi WORKED khá nhanh cho ONE video. See here.

Tôi dựa trên mã số của mình trên this tutorial và được nạp nhanh thật nhanh.

Sau đó, làm việc này ...
Tôi có nhu cầu tạo mảng để xử lý nhiều video.
Đối với id liên kết, id người chơi, mã thời gian cho bắt đầu/kết thúc ... VÀ LISTENERS!
Bắt đầu vui vẻ!

Như đã nói, tôi đã dành phần lớn thời gian của mình cho việc này. Tôi luôn gặp lỗi VỚI các lỗi console như hướng dẫn rõ ràng (LOLLL).

Tôi hài lòng về công việc của mình ... Điều này đang đi đúng hướng tôi nghĩ.
này hầu như làm việc ...


Nhưng lần này, không có lỗi! See here. (hãy kiểm tra bảng điều khiển!)

WHATT !!! KHÔNG L ERI?!?
Cánh tay của tôi bị tấn công ngay bây giờ.
Trong thực tế, chương trình đầu tiên nhưng video không bắt đầu ... Và thứ hai có vẻ hoàn toàn bị mất trong đám mây.

Trong thông báo nhật ký bảng điều khiển, tôi thấy lần xuất hiện đầu tiên của trình nghe onStateChange, là -1 (Không được bắt đầu). Nhưng sau đó ??? Nó chết!
Arrgg!

Tôi phải vượt qua niềm tự hào của mình ... Và mang nó như một câu hỏi trên StackOveflow.
;)



mã đầy đủ của tôi (cho nhiều liên kết):
Đây là một trang gọi qua ajax ... Vì vậy, tất cả các nguồn tài bên ngoài như jQuery đã nạp.

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

Trả lời

7

Có một vấn đề tạm thời với các API iFrame Player bạn có thể đọc ở đây: https://code.google.com/p/gdata-issues/issues/detail?id=4706

Như một sửa chữa tạm thời, bạn chỉ cần thêm người nghe sự kiện trong sự kiện onready:

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

Ngoài ra, như ai đó đã đề cập trên Chủ đề vấn đề mã Google, bạn đặt khoảng thời gian và thăm dò ý kiến ​​người chơi cho trạng thái hiện tại thay vì nghe cho sự kiện onStateChange. Dưới đây là đoạn mã ví dụ để làm điều đó:

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

Có vẻ như là đầu mối đúng để tìm sửa lỗi của tôi. Tôi phải thử trước khi chấp nhận. Nhưng, vì nó trông nghiêm trọng, tôi đã bình chọn nó. Tôi có một cuộc họp buổi tối bắt đầu trong 30 phút ... Vì vậy, tôi sẽ kiểm tra nó nghiêm túc tomorow. Cảm ơn! –

+0

không phải lo lắng! –

+0

Tôi đã thử một cái gì đó với ý tưởng khoảng thời gian này ... Bây giờ tôi có được một cái gì đó mới. Nhưng tôi vẫn còn trong rừng. Bây giờ tôi nhận playerState = 5 (video cued) trong 1 giây. Sau đó 3 (đệm) cho 80 millisec. Sau này, khoảng thời gian là vô tận đếm và trạng thái máy nghe nhạc bị mắc kẹt trên -1 (unstarted). Xem bảng điều khiển trên [liên kết công việc đang tiến hành] của tôi (https://www.bessetteweb.com/?p=youtube-video-test) Tôi sẽ Chỉnh sửa câu hỏi để hiển thị mã đã sửa đổi của tôi. –

Các vấn đề liên quan