0

如果用户跳过了一些,我想测量视频播放期间跳过的时间。

使用 video.currentTime

首先它看起来很微不足道

Listen to seeking and get the currentTime A
Listen to seekend and get the currentTime B

B - A = Seeked Time

当我在 Chrome 中执行此操作时,结果为 0。这是为什么呢?如果您听 timeupdate TU,它会变得非常明显。简化序列:

Press Play
TU: 1
TU: 2
TU: 3 // now i use the mouse to seek forward to 19
TU: 19
//chrome & ff fire pause in between, ie not
Seek Start: 19
TU: 19
Seek End: 19
TU: 19
//chrome & ff fire play, ie not
TU: 20
...

我知道我可以玩脏并在某处保存 currentTime 但不是以可靠的方式;-)

使用 TimeRanges video.played

我可以使用 TimeRanges 来计算被搜索/跳过的时间量。但问题是:TimeRanges 以有序和规范化的形式作为列表出现。因此,如果用户向后跳,则 Ranges 会被合并和排序 => 对于准确跟踪来说不可靠。

有没有更简单的不太复杂的方法我只是没有看到?

4

1 回答 1

0

我是如何解决的。

我从这里https://stackoverflow.com/a/28038535/2588818使用了一个 RingBuffer(大小 10),并在Math.round(video.currentTime)每次更新时推送它。我在seekendRingBuffer 中向左(上一个)并获取与当前时间不同的第一个数据。

工作得很好,可以用它来跟踪跳过的时间。

var createRingBuffer = createRingBuffer || function(length) {
  /* https://stackoverflow.com/a/4774081 */
  var pointer = 0, buffer = [];

  return {

    ...

    push : function(item){
      buffer[pointer] = item;
      pointer = (pointer + 1) % length;
      return item;
    },

    ...

    getFirstDifference: function() {
        var last_value = buffer[pointer - 1],
            prev_value;
        for (var i = 1; i <= length; i++) {
            prev_value = buffer[(pointer - i) % length]

            //check for undefined or initialize the buffer beforehand
            if(prev_value === undefined || last_value === prev_value) {

            } else {
                return prev_value;
            }
        }
        return last_value;
    },
    print: function() {
        console.log(JSON.stringify(buffer));
    }
  };
};

...

var seekTimes = createRingBuffer(10);

handleUpdateTime = function() {
    seekTimes.push(Math.round(video.currentTime));
},

handleSeekEnd = function(e) {
    seekTimes.print();
    console.log("%s - %s", seekTimes.getFirstDifference(), Math.round(video.currentTime));
},

...

于 2016-11-24T12:38:28.793 回答