【发布时间】:2016-10-15 20:43:27
【问题描述】:
编辑 - 2016-06-25
(我删除了 6 月 16 日的更新,因为不再相关。
我在下面留下了我的 OP...)
我今天又花了 4 个小时来解决这个问题。
这是现在的情况:
我的函数 WORKS 用于两个链接。
视频参数在数组中定义。
其他两个链接失效。
我收到了链接 #3 和 #4 的 Uncaught TypeError: thisPlayer.loadVideoById is not a function。
但相同的功能适用于链接 #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);
-----------------
这是我的原始帖子 - 6 月 14 日:强>
我已经为此花费了 6 个小时。
(加上 1 个编辑这个问题!)
我正在调试它的最后 4 行。
问题是没有控制台错误提示。
概念:
我想将大量 Youtube 视频链接到文本链接。
用户想要的效果是能够在阅读文本时单击引文链接...以便能够确认引文。
视频不能完全播放。
视频应以特定时间码开始并以特定时间码结束。
额外的复杂性:所有这些都希望以模态视图样式显示。
我的代码在 ONE 视频中运行得非常快。 See here。
我的代码基于this tutorial 并很快成功。
然后,让这个工作......
我需要构建数组来处理多个视频。
对于链接 ID、玩家 ID、开始/结束时间码...和听众!
乐趣开始了!
就像说的那样,我大部分时间都在这上面度过。 我总是遇到控制台错误作为明确 (LOLL) 指南的错误。
我对我的工作感到满意...我认为这是朝着正确的方向发展。
这几乎可以工作...
但这一次,没有错误! See here。 (检查控制台!)
什么!!!没有错误?!?
我的手臂现在被砍掉了。
事实上,第一个节目但视频没有开始......第二个看起来完全迷失在阴霾中。
在控制台日志消息中,我看到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>
【问题讨论】:
标签: javascript jquery video youtube-api listener