HTML5跟踪元素提示事件Buggy吗



我正在尝试为HTML5的cue.onenter事件动态分配函数。这是一个非常新的功能,目前只有在启用特定标志的Chrome中才支持(请参阅HTML5 Rocks的示例)。

然而,要么由于早期开发,它真的有缺陷,要么我做错了什么。基本上,我在一个普通的HTML页面上有一个track元素。没什么奇怪的。

<audio id="audiocast" controls oncanplay="setReadyToPlay();">
<source id="audiosource" src="SomeWorkingUrlwithaudio" ></source>
<track kind="metadata" id="audioTrack" label="slides" src="/data.vtt" default >
</track>
Your Browser does not support HTML5
</audio>

我通过JavaScript访问它,比如:

//(...)
var trackElements = $("#audiocast")[0].children("track")[0];
_track = trackElements.track;
_cues = _track.cues;
for (var j = 0; j < _cues.length; ++j) {
var cue = _cues[j];
cue.onenter = getOnEnter(j);
}
//(...)
function getOnEnter(idx) {
return function() {
setCueIdx(idx);
updateURL(idx);
var json = JSON.parse(this.text);
_currImgSrc = json.src;
drawIt();
}
};

然而,这只是部分时间有效。有时我必须重新加载浏览器3次才能工作(例如,当我在输入提示时绘制图像时),或者工作时,它会随机工作,直到达到第4个提示(共10个),然后停止工作。

这是没有意义的,但也许你们中的一些人知道如何为此提供后备和稳定性解决方案。

附加信息:它作为Node.js应用程序运行。媒体播放器处理提示的完整来源如下。

请注意,由于Stack Overflow对脚本进行了沙盒处理,该片段将无法工作。

/*
* slideCastController.js
* © by pschne2s, nkopp2s, 2012
*
* Basically encapsulates the Media Player Object, handling the function of the HTML5-Player
*/
/****************************OBJECT DEFINITION***********************************/
CanvasRenderingContext2D.prototype.clear = CanvasRenderingContext2D.prototype.clear ||
function(preserveTransform) {
if (preserveTransform) {
this.save();
this.setTransform(1, 0, 0, 1, 0, 0);
}
this.clearRect(0, 0, this.canvas.width, this.canvas.height);
if (preserveTransform) {
this.restore();
}
};
var mediaPlayer = (function() {
//Members
var _cueIdx = 0;
var _cues = [];
var _target;
var _track;
var _readyToPlay = false;
var _currImgSrc;
function setupCues() {
if (_readyToPlay) {
if (_track === undefined) {
// var trackElements = document.getElementById("audioTrack");
var trackElements = $(_target).children("track")[0];
_track = trackElements.track;
}
_cues = _track.cues;
$("#maxcues").text(_cues.length - 1);
for (var j = 0; j < _cues.length; ++j) {
var cue = _cues[j];
cue.onenter = getOnEnter(j);
}
_track.oncuechange = function() {
//updateURL(mediaPlayerInfo.cueIdx);
};
checkFragments();
} else {
setTimeout(setupCues, 1);
}
};
function getOnEnter(idx) {
return function() {
setCueIdx(idx);
updateURL(idx);
var json = JSON.parse(this.text);
_currImgSrc = json.src;
drawIt();
}
};
function drawIt() {
var ctx = $("#slide")[0].getContext('2d');
ctx.clear();
var tmpImg = new Image();
tmpImg.onload = function() {
ctx.drawImage(tmpImg, 0, 0, 592, 256);
}
tmpImg.src = _currImgSrc;
}
function checkFragments() {
var fragments = purl(window.document.URL);
var slide = fragments.fparam("slide");
if (slide !== undefined) {
gotoCue(slide);
}
var action = fragments.fparam("action");
if (action == "play") {
_target.play();
}
};
function setCueIdx(idx) {
//alert("Cue idx set to: " + idx);
_cueIdx = idx;
$("#cueidx").text(idx);
};
function gotoCue(index) {
if (index >= 0 && index < _cues.length) {
_cueIdx = index;
var audioElement = $("#audiocast").get(0);
//mediaPlayerInfo.cues[mediaPlayerInfo.cueIdx].onenter();
audioElement.currentTime = _cues[index].startTime;
}
};
var updateURL = (function() {
// set Base-URL (without query/hash-String)
var url = location.protocol + "//" + location.host + location.pathname;
var html5 = window.history.replaceState !== undefined ? true : false;
return function(slideIdx) {
if (html5)
window.history.replaceState(null, document.title + " | Slide #" + slideIdx, url + "#slide=" + slideIdx);
else
location.href = url + "#slide=" + slideIdx;
// No nice browser history
};
})();
return {
init: function() {
setupCues();
},
setTarget: function(obj) {
_target = obj;
},
setTrack: function(obj) {
_track = obj;
},
setReadyToPlay: function() {
_readyToPlay = true;
},
gotoNextCue: function() {
gotoCue(_cueIdx + 1);
},
gotoPrevCue: function() {
gotoCue(_cueIdx - 1);
}
};
})();
$(document).ready(function() {
// "Unobstrusive" Function-Bindings
$("#btnPrevCue").bind("click", mediaPlayer.gotoPrevCue);
$("#btnNextCue").bind("click", mediaPlayer.gotoNextCue);
mediaPlayer.setTarget($("#audiocast")[0]);
mediaPlayer.init();
});
window.setReadyToPlay = mediaPlayer.setReadyToPlay;
// does not work using other ways atm

从原始问题复制的内容


显然,音频/音轨元素真的很bug。然而,"oncuechange"似乎效果不错。我现在是这样做的:

var _cueLookup = new Object();
_cues = _track.cues;  //track-element cues.
for (var j = 0; j < _cues.length; ++j) {
var cue = _cues[j];
//cue.onenter = getOnEnter(j);
_cueLookup[cue.id] = j;
//alert(_cueLookup[cue.id]);
}
_track.oncuechange = function() {
// "this" is a textTrack
var cue = this.activeCues[0]; // assuming there is only one active cue

最新更新