gpt4 book ai didi

Javascript 事件监听器退出(?)监听... Youtube API - 无控制台错误

转载 作者:数据小太阳 更新时间:2023-10-29 05:14:42 25 4
gpt4 key购买 nike

编辑 - 2016-06-25
(我删除了 6 月 16 日的更新,因为不再相关。
我把我的 OP 留在了下面...)



我今天又花了 4 个小时在这上面。
现在是这样的情况:

我的函数 WORKS 用于两个链接。
视频参数在数组中定义。
其他两个链接无效。

我得到一个 Uncaught TypeError: thisPlayer.loadVideoById is not a function对于链接 #3 和 #4。
但是相同的功能适用于链接 #1 和 #2。

似乎 youtube 对象仅针对两个第一定义。
为什么?

请仔细查看此实时链接上的控制台:
https://www.bessetteweb.com/?p=youtube-video-test
我插入了很多 console.log 消息以使其清晰。

这是我的实际代码:

// 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 行。

问题是我没有收到控制台错误提示。



概念:
我想将大量 Youtube 视频链接到文本链接。
用户想要的效果是能够在阅读文本时单击引文链接...以便能够确认引文。
视频不必完全播放。

视频应以特定时间码开始并以特定时间码结束。
额外的复杂性:所有这些都希望以模态视图样式显示。

我的代码工作对于ONE 视频来说相当快。 <强> See here

我的代码基于 this tutorial并且很快就成功了。

然后,让这个工作...
我需要构建数组来处理多个视频。
对于链接 ID、播放器 ID、开始/结束的时间码……以及听众!
乐趣开始了!

如前所述,我一天的大部分时间都花在了这上面。我总是遇到带有控制台错误的错误作为清晰的(LOLLL)指南。

我对自己的工作很满意......我认为这是朝着正确的方向前进。
这几乎可以工作了......


但这一次,没有错误! See here . (检查控制台!)

什么!!!没有错误?!?
我的 ARM 现在被砍掉了。
事实上,第一个显示但视频没有开始......第二个看起来完全迷失在阴霾中。

在控制台日志消息中,我看到第一次出现 onStateChange监听器,即 -1(未启动)。但是之后 ???它死了!
啊!

我必须超越我的骄傲……并将它作为一个问题带到 StackOveflow 上。
;)



我的完整代码(用于多个链接):
这是一个通过 ajax 调用的页面...因此所有外部资源(如 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>

最佳答案

iFrame 播放器 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);

关于Javascript 事件监听器退出(?)监听... Youtube API - 无控制台错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37823490/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com