我正在尝试将函数动态分配给 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 次才能使其工作(例如,当我在输入提示时绘制图像时),或者当它工作时,它会随机工作,直到达到 10 个提示中的第 4 个,然后停止工作。
这只是没有意义,但也许你们中的一些人知道如何为此提供回退和稳定性解决方案。
附加信息:这作为 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