我一直试图找出一个简单的指令模式来控制html5视频/ youtube视频。
我想用“Angular方式”来做,因此将视频的属性绑定到对象模型。但是,当处理视频的“currentTime”属性时,我遇到了一些问题,因为它会不断更新。
这是我到目前为止所得到的:
html控件:
<!--range input that both show and control $scope.currentTime -->
<input type="range" min=0 max=60 ng-model="currentTime">
<!--bind main $scope.currentTime to someVideo directive's videoCurrentTime -->
<video some-video video-current-time="currentTime"> </video>
指令:
app.controller('MainCtrl', function ($scope) {
$scope.currentTime = 0;
})
app.directive('someVideo', function ($window) {
return{
scope: {
videoCurrentTime: "=videoCurrentTime"
},
controller: function ($scope, $element) {
$scope.onTimeUpdate = function () {
$scope.videoCurrentTime = $element[0].currentTime;
$scope.$apply();
}
},
link: function (scope, elm) {
scope.$watch('videoCurrentTime', function (newVar) {
elm[0].currentTime = newVar;
});
elm.bind('timeupdate', scope.onTimeUpdate);
}
}
})
JSFiddler:http://jsfiddle.net/vQ5wQ/
::
虽然这似乎有效,但请注意,每次onTimeUpdate
触发时,都会触发$watch
。
例如,当视频运行到10秒时,它通知onTimeUpdate将模型更改为10,$ watch将捕获此更改并要求视频再次寻找10秒 。< / p>
有时会创建一个循环,导致视频时滞。
您认为有更好的方法吗?一种不会触发不必要的$ watch的方法?任何建议表示赞赏。
答案 0 :(得分:2)
某些timeupdate documentation的摘录说明当你
时调用与timeupdate绑定的函数
- 播放视频
- 在播放控件上移动位置指示器
因此,当播放被修改时,事件会被触发,并且您不需要显式地$观看附加到该播放控件的模型。
这意味着您可以在timeupdate侦听器中执行两个更新,而不是在watch语句中进行外部模型到视频分配...但请确保检查其注释中提到的jkjustjoshing之类的阈值为了确保控件实际上已被移动。
$scope.onTimeUpdate = function () {
var currTime = $element[0].currentTime;
if (currTime - $scope.videoCurrentTime > 0.5 ||
$scope.videoCurrentTime - currTime > 0.5) {
$element[0].currentTime = $scope.videoCurrentTime;
}
$scope.$apply(function () {
$scope.videoCurrentTime = $element[0].currentTime;
});
};
另一个注意事项:我不确定这是否与您相关,但是一旦视频结束,即使您明确调用play()
,它也不会再次播放,即使您设置了currentTime
1}}。要解决此问题,您可以在videoCurrenTime
上使用$ watch语句,如果视频结束,则会重新启动视频。
你原来的代码并不是很迟钝,但这里有一个更新的小提琴,似乎有几秒钟的延迟(至少从我的有限测试中): http://jsfiddle.net/B7hT5/
答案 1 :(得分:0)
删除videoCurrentTime的延迟更新监视
scope.$watch('videoCurrentTime', function (newVar) {
if (newVar && (0.1 < newVar - elm[0].currentTime || 0.1 < elm[0].currentTime - newVar)) {
elm[0].currentTime = newVar;
}
});