2014-03-04 165 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; 
       } 
      });