video.js - find the start time of a seek during playback

旧城冷巷雨未停 提交于 2020-01-24 04:36:05

问题


I am using video.js (http://www.videojs.com/) to build a video approval system and need to log user actions in the player. I can do this easily enough with play, pause, end etc. but have hit a problem when trying to log seeks.

I want to be able to log the start and end times of any seeks within the plaback, so we know if the user has not actually watched a section of the video. The player seems to offer events to support this, but I am struggling to get correct timings from it.

When the user skips through a video the player emits the following events in order: pause, seeking, seeked, play.

If I query the player object at any of these events using currentTime() the result is always the end time for the seek, even on the initial pause event. This means I can log where the seek ended but not where it started.

Can anyone help me to find the position in the video where the seek begins?

If this is not possible, I'd settle for a way to disable seeking during playback.

EDIT: adding code as requested. It's pretty simple:

var trackedPlayer = videojs('pvp-player');

trackedPlayer.on("play", function (e) {
    console.log("Video playback started: " + trackedPlayer.currentTime());
});

trackedPlayer.on("pause", function (e) {
    console.log("Video playback paused: " + trackedPlayer.currentTime());
});

trackedPlayer.on("seeking", function (e) {
    console.log("Video seeking: " + trackedPlayer.currentTime());
});


trackedPlayer.on("seeked", function (e) {
    console.log("Video seek ended: " + trackedPlayer.currentTime());
});

trackedPlayer.on("ended", function (e) {
    console.log("Video playback ended.");
});

If I can get all the tracking I want I will replace console.log with ajax calls to store the data.


回答1:


You can listen to timeupdate und take the next to last value you got there before seeking is called as your source:

var previousTime = 0;
var currentTime = 0;
trackedPlayer.on('timeupdate', function() {
    previousTime = currentTime;
    currentTime = trackedPlayer.currentTime();
});
trackedPlayer.on('seeking', function() {
    console.log('seeking from', previousTime, 'to', currentTime, '; delta:', currentTime - previousTime);
});

This seems to work with the HTML5 tech. I have not tested with other techs.

There is, however, one glitch: the first time seeking a paused player yields only a small delta (and the almost-same previous value for both variables). But this shouldn’t matter much since the delta is only a few hundred milliseconds (and I gather you’re only interested in the “from” value).

Update

seeked is triggered far more infrequently than seeking. Try the following.

var previousTime = 0;
var currentTime = 0;
var seekStart = null;
trackedPlayer.on('timeupdate', function() {
    previousTime = currentTime;
    currentTime = trackedPlayer.currentTime();
});
trackedPlayer.on('seeking', function() {
    if(seekStart === null) {
        seekStart = previousTime;
    }
});
trackedPlayer.on('seeked', function() {
    console.log('seeked from', seekStart, 'to', currentTime, '; delta:', currentTime - previousTime);
    seekStart = null;
});

There are also many libraries for debouncing function calls (in this case the call to your backend).




回答2:


I needed to find the same value for a project I was working on so I could determine whether or not a user was skipping forward or backward in a videojs player.

Initially, I thought to save the currentTime() a user was seeking from on timeupdate then immediately removing my timeupdate listener once seeking was dispatched. While this worked in some browsers like Chrome, unfortunately, I found that other browsers continued to fire timeupdate more frequently and would continue to update the currentTime() I was saving after the player actually seeked.

Here was the solution that ultimately worked across Safari/Chrome/Firefox. I have yet to test in IE.

var previousTime = 0,
    currentTime = 0,
    completeTime = 0,
    position = 0;


trackedPlayer.on('timeupdate', function() {
    previousTime = currentTime;
    currentTime = Math.floor(player.currentTime());

    // save 'position' so long as time is moving forward with each update
    if (previousTime < currentTime) {
        position = previousTime;
        previousTime = currentTime;
    }
});

// when seeking starts
trackedPlayer.on('seeking', function() {
    player.off('timeupdate', onTimeUpdate);

    player.one('seeked', onSeekComplete);
});

// when seeking completes
trackedPlayer.on('seeked', function() {
    completeTime = Math.floor(player.currentTime());
    console.log("User came from: " + position);
    console.log("User ended at: " + completeTime);
});



回答3:


I know this is an old post but this is the only solution that worked for me.

var counter = 0;
var beforeTimeChange = 0;

function handleSeeking() {
  var timeoutTime = 300;
  var beforeCounter = counter + 1;
  if (trackedPlayer.cache_.currentTime === trackedPlayer.duration()) {
    return;
    // when video starts over, calls seek
  }
  beforeTimeChange = beforeTimeChange || trackedPlayer.cache_.currentTime;
  setTimeout(function() {
    if (beforeCounter === counter) {
        console.log('before seek', beforeTimeChange, '\nafter seek', trackedPlayer.currentTime() - (timeoutTime / 1000));
        counter = 0;
        beforeTimeChange = 0;
    }
  }, timeoutTime);
  counter++;
}

trackedPlayer.on('seeking', handleSeeking);



回答4:


Try with this code to know the length of video.

var duration = document.getElementById("duration");
var vid_duration = Math.round(document.getElementById("video").duration);
    //alert(vid_duration);
duration.innerHTML = vid_duration;
    //duration.firstChild.nodeValue = vid_duration;


来源:https://stackoverflow.com/questions/29743729/video-js-find-the-start-time-of-a-seek-during-playback

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!