0

i would like to measure the skipped time during video playback if a user skipped some.

Using video.currentTime

First it looks quite trivial

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

B - A = Seeked Time

When i do that in Chrome the result is 0. Why is that? If you listen to timeupdate TU it gets quite obvious. Simplified Sequence:

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
...

I know i can play dirty and save the currentTime somewhere but not in an reliable way ;-)

Using TimeRanges video.played

I can use TimeRanges to calculate the amount of Time which got seeked/skipped. But the Problem is: TimeRanges come in ordered and normalized form as list. So if the User jumps forth an back the Ranges become merged and ordered => not reliable for accurate tracking.

Is there an easier less complicated approch i just dont see?

mons droid
  • 1,038
  • 9
  • 10
  • Im kinda thinking of using a queue with max 5-10 elements where i save the time. after an seeking i go trough it and use the first time which differs at starting time – mons droid Nov 23 '16 at 18:31

1 Answers1

0

How I solved it.

I used a RingBuffer (Size 10) from here https://stackoverflow.com/a/28038535/2588818 and push the Math.round(video.currentTime) with every timeupdate to it. On seekend I go left (prev) in the RingBuffer and take the first datum which differs from the current time.

Works just fine enough to use it for tracking the skipped time.

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));
},

...

Community
  • 1
  • 1
mons droid
  • 1,038
  • 9
  • 10