2014-03-04 138 views
5

我一直是想搞清楚控制HTML5视频/ YouTube视频简单的指令模式中的两路整合视频的currentTime的。AngularJS:用指令

我想要做的“角办法”,从而绑定视频的属性添加到对象模型。但是,在处理视频的“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秒

这段时间创建了一个循环,导致视频滞后于时间。

你认为有更好的方法来做到这一点?一种不会触发不需要的$ watch的方法?任何建议表示赞赏。

+0

'currentTime'的分辨率是多少?我知道'ontimeupdate'每运行一帧视频(每秒多次) - 'currentTime'获得亚秒精度吗?如果是这样,在'$ watch'内部,您可以在进行更改之前检查'newVar'和'elem [0] .currentTime'之间的最小差异。 – jkjustjoshing

回答

1

一些timeupdate documentation摘录说,当你

  • 播放视频
  • 移动位置指示器上的播放控件绑定到timeupdate函数被调用

因此,当播放被修改时,事件被触发,并且您不需要明确$观看附加到该播放控件的模型。

这意味着您可以在timeupdate监听器中执行两次更新,而不是在监视声明中执行外部模型到视频的分配......但请确保您检查了他的评论中提到的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玩。为了解决这个问题,你可以使用该重新启动视频是否已结束对videoCurrenTime一个$表的语句。

你原来的代码不是很laggy,但这里是一个更新的小提琴,似乎有几秒钟较少的滞后(从我有限的测试至少): 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; 
       } 
      });