【问题标题】:AngularJS: Two way binding video's currentTime with directiveAngularJS:两种方式将视频的 currentTime 与指令绑定
【发布时间】:2016-10-07 21:49:32
【问题描述】:

我一直在尝试找出一个简单的指令模式来控制 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 秒

这有时会创建一个循环,导致视频不时出现延迟。

您认为有更好的方法吗?一种不会触发不需要的 $watch 的方法?任何建议表示赞赏。

【问题讨论】:

  • 'currentTime' 的分辨率是多少?我知道ontimeupdate 大约每帧视频运行一次(每秒多次)-currentTime 是否获得亚秒级精度?如果是这样,在$watch 中,您可以在进行更改之前检查newVarelem[0].currentTime 之间的最小差异。

标签: angularjs html5-video


【解决方案1】:

一些timeupdate documentation的摘录说绑定到 timeupdate 的函数在你调用时被调用

  • 播放视频
  • 移动播放控件上的位置指示器

因此,当播放被修改时,事件会被触发,并且您不需要显式地 $watch 附加到该播放控件的模型。

这意味着您可以在 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;
    });
};

另一个注意事项:我不确定这与您是否相关,但是一旦视频结束,即使您设置了 currentTime,它也不会再次播放,直到您明确调用 play()。要解决此问题,您可以在 videoCurrenTime 上使用 $watch 语句,如果视频已结束则重新启动。

您的原始代码不是很滞后,但这里有一个更新的小提琴,似乎有几秒钟的滞后(至少从我的有限测试来看): http://jsfiddle.net/B7hT5/

【讨论】:

  • 我认为这就是我最终要做的(这是不久前的事)。我希望一切都遵循一个模型,但有时这并不是最好的方法:)
【解决方案2】:

要消除视频当前时间的滞后更新手表

scope.$watch('videoCurrentTime', function (newVar) {
                if (newVar && (0.1 < newVar - elm[0].currentTime || 0.1 < elm[0].currentTime - newVar)) {
                    elm[0].currentTime = newVar;
                }
            });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-23
    • 2012-10-28
    • 1970-01-01
    • 2013-11-29
    • 1970-01-01
    • 2014-02-13
    • 1970-01-01
    • 2016-02-27
    相关资源
    最近更新 更多