cue.onenter
関数を HTML5 のイベントに動的に割り当てようとしています。これは非常に新しい機能で、現在、特定のフラグが有効になっている 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 アプリケーションとして実行されます。キューを処理する Media Player の完全なソースを以下に示します。
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