Javascript 如何包装HTML5视频元素的currentTime属性?
我正在开发一个视频播放器,作为学习模块系统的一部分。某些模块要求用户不能轻松地在视频中向前跳过。我知道这通常会被认为是一种糟糕的用户体验,但在这种情况下这是必不可少的 我已经能够通过执行以下操作覆盖video.currentTime属性。它可以防止跳过,但我需要能够有条件地打开和关闭它Javascript 如何包装HTML5视频元素的currentTime属性?,javascript,html,video,html5-video,Javascript,Html,Video,Html5 Video,我正在开发一个视频播放器,作为学习模块系统的一部分。某些模块要求用户不能轻松地在视频中向前跳过。我知道这通常会被认为是一种糟糕的用户体验,但在这种情况下这是必不可少的 我已经能够通过执行以下操作覆盖video.currentTime属性。它可以防止跳过,但我需要能够有条件地打开和关闭它 Object.defineProperty(videoElement, 'currentTime', { enumerable: true, configurable: true, get: func
Object.defineProperty(videoElement, 'currentTime', {
enumerable: true,
configurable: true,
get: function() {
// return from original currentTime
},
set: function(newValue) {
// intercept values here
}
});
如何在getter和setter中引用原始video.currentTime属性?不幸的是,Object.getOwnPropertyDescriptorvideoElement为“currentTime”;返回未定义。可能有一种更优雅的方法来实现这一点,但是在本例中调用原型的currentTime getter,对象上的HTMLMediaElement原型将为您提供实际的currentTime。因此,这将阻止设置,但允许获取:
Object.defineProperty(videoElement, 'currentTime', {
enumerable: true,
configurable: true,
get: function() {
var ct = Object.getOwnPropertyDescriptor(HTMLMediaElement.prototype,
'currentTime').get.call(this);
return ct;
},
set: function(newValue) {
// intercept values here
}
});
如果您希望禁用搜索跳过,那么以下是我的解决方案:
var video = document.getElementById('video');
var supposedCurrentTime = 0;
video.addEventListener('timeupdate', function() {
if (!video.seeking) {
supposedCurrentTime = video.currentTime;
}
});
// prevent user from seeking
video.addEventListener('seeking', function() {
// guard agains infinite recursion:
// user seeks, seeking is fired, currentTime is modified, seeking is fired, current time is modified, ....
var delta = video.currentTime - supposedCurrentTime;
if (Math.abs(delta) > 0.01) {
console.log("Seeking is disabled");
video.currentTime = supposedCurrentTime;
}
});
// delete the following event handler if rewind is not required
video.addEventListener('ended', function() {
// reset state in order to allow for rewind
supposedCurrentTime = 0;
});
此代码仅在查找时将video.currentTime恢复为其最后一个已知值。这有效地取消了查找过程。无需覆盖/包装currentTime
包装currentTime的问题在于,如果用户足够聪明,可以选择视频元素并设置其currentTime属性,则用户可能足够聪明,可以调用:
Object.getOwnPropertyDescriptor(HTMLMediaElement.prototype,
'currentTime').set.call(videoElement, videoElement.duration);
为什么不重命名它(例如currentTime2)以访问原始的currentTime?您不能重命名属性,只能创建新属性并删除旧属性。啊哈!太好了。我试图做一些类似的事情来获取prototype属性,但不断出现非法调用错误,因为我缺少get。呜呜,我不小心将赏金分配给了错误的人:我将启动另一个赏金并将其交给你。噢!呵呵!没什么大不了的,不过还好!好了。赏金。每个人在这个问题上都做得很好,呵呵。我以前使用过这种方法,但发现它在浏览器之间非常脆弱,因为它实际上会短暂地改变时间,从而触发任何观看时间更新的行为。我不担心有人窃听视频。这种方法主要是为了防止意外点击或按键错误地推进视频。这只是针对一个学习模块,该模块对考生有一个法律要求,要求考生全程观看视频。使用该模块的用户不希望跳过,因为他们以后会错过所需的信息;我不小心让他们回答了这个问题。我明白了,在这种情况下,你不能简单地隐藏控件吗?这将有效地消除错误点击的可能性。您甚至可以创建自己的控件,这些控件仍然具有播放/暂停和音量按钮,但没有搜索栏。谢谢你的赏金,但现在我觉得有点内疚,因为我不配。不,他们仍然需要能够暂停,改变音量,有时全屏。