如何最好地跟踪视频播放了多长时间? [英] How to best track how long a video was played?

查看:57
本文介绍了如何最好地跟踪视频播放了多长时间?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当用户观看视频时,我想拨打2个AJAX电话.当用户观看完视频并且播放的时间等于或大于视频的持续时间时(因为用户也可以倒带). timePlayed> =持续时间&&event.type =="ended" .我成功地打电话了.

When the user watches a video, I would like to make 2 AJAX calls. One when the user finished watching the video and the time played is equal or more than the duration of the video (because users can rewind as well then). timePlayed>=duration && event.type=="ended". I successfully make the call for that.

让我感到不安的是,我还想在观看视频超过80%并且播放视频的时间也超过80%时拨打电话,以防止用户进行快速转发.

Where I struggle is that I would also like to make a call when the video is watched more than 80% and the time played of the video is more than 80% as well in order to prevent the user from just fast forwarding.

为了使其正常工作,我必须修改我的 videoStartedPlaying()方法,这是我在尝试设置时间间隔时遇到的问题.现在,设置一个间隔,就好像一个无休止的循环.

In order for that to work I have to modify my videoStartedPlaying() method and this is where I come across issues as I am trying to set an interval. Now, with setting an interval, it is like an endless loop.

var video_data = document.getElementById("video");

var timeStarted = -1;
var timePlayed = 0;
var duration = 0;

// If video metadata is loaded get duration
if(video_data.readyState > 0)
    getDuration.call(video_data);
//If metadata not loaded, use event to get it
else {
    video_data.addEventListener('loadedmetadata', getDuration);
}

// remember time user started the video
function videoStartedPlaying() {
    timeStarted = new Date().getTime()/1000;
    setInterval(function(){
        playedFor = new Date().getTime()/1000 - timeStarted;
        checkpoint = playedFor / duration;
        percentComplete = video_data.currentTime/video_data.duration;

        // here I need help of how to best accomplish this
        if (percentComplete >= 0.8 && checkpoint >= 0.8) {
            // AJAX call here
        }
    }, 2000);
}

function videoStoppedPlaying(event) {
    // Start time less then zero means stop event was fired vidout start event
    if(timeStarted>0) {
        var playedFor = new Date().getTime()/1000 - timeStarted;
        timeStarted = -1;
        // add the new amount of seconds played
        timePlayed+=playedFor;
    }

    // Count as complete only if end of video was reached
    if(timePlayed>=duration && event.type=="ended") {
        // AJAX call here
    }
}

function getDuration() {
    duration = video_data.duration;
}

video_data.addEventListener("play", videoStartedPlaying);
video_data.addEventListener("playing", videoStartedPlaying);
video_data.addEventListener("ended", videoStoppedPlaying);
video_data.addEventListener("pause", videoStoppedPlaying);

我真的很感激这方面的任何帮助,因为看来我已经不知所措了.

I truly would appreciate any help with this as it seems like I am at my wits end.

非常感谢!

多亏了我的评论:

const video = document.getElementById("video");
const set = new Set();
const percent = .8;
let toWatch;

function mediaWatched (curr) {
  alert(`${curr}% of media watched`)
}

function handleMetadata(e) {
  toWatch = Math.ceil(video.duration * percent);
  console.log(toWatch, video.duration);
}

function handleTimeupdate (e) {
  set.add(Math.ceil(video.currentTime));
  let watched = Array.from(set).pop();
  if (set.has(toWatch) && watched === toWatch) {
    video.removeEventListener("timeupdate", handleTimeupdate);
    console.log(watched);
    mediaWatched(
      Math.round(watched / Math.ceil(video.duration) * 100)
    );
  }
}

video.addEventListener("loadedmetadata", handleMetadata);

video.addEventListener("timeupdate", handleTimeupdate);

<video width="400" height="300" controls="true" poster="" id="video">
    <source type="video/mp4" src="http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_2mb.mp4" />
</video>

例如,现在,如果我快进到50%左右的长度,然后播放,那么它将在到达电影的80%时触发,但这不是应该的,因为我快进到50%的长度,本质上只看了30%.

Now, for example, if I fast forward to around 50% length, and let it play then, it will fire whenever 80% of the movie is reached, but it shouldn't because I fast forwarded to 50% and essentially only watched 30%.

这有意义吗?我该如何实现这种行为?

Does that make sense? How can I achieve such behavior?

推荐答案

每个评论中的讨论,这是一个有效的示例.

per discussion in comments here's a working sample.

它包括几个处理程序,目的是使设置数组和累加内容更容易,使您知道达到80%的标记(尽管您可能需要更改该逻辑,如果要强制它们执行以下操作),例如,明确观看前80%的视频,而不仅仅是整个视频中的80%.

It includes a couple of handlers just to make life easier in setting up the array and summing the contents so you know when you have reached the 80% mark (though you may need to change that logic if you want to force them to, say, explicit watch the first 80% not just a total of 80% throughout the video).

其中有许多 console.log(...)语句,因此您可以在浏览器控制台窗口中查看它的运行状况……您可能希望将其取出在真正部署之前.

There are a number of console.log(...) statements in there so you can watch what it's doing in the browser console window... you'll probably want to take them out before deploying for real.

我已经在 timeupdate 事件中添加了进行ajax调用的位置的钩子,但是您也总是可以在主循环中使用常规的 setInterval 计时器检查80%并在那里打电话,但这看起来更干净

I've put the hook for where to make the ajax call in the timeupdate event, but you could always use a regular setInterval timer in the main loop as well to check for the 80% and make the call there, but this seemed cleaner

大多数应该是自我解释的,但是请在评论中询问是否有不清楚的地方...

most of it should be self explanatory, but do ask in comments if there's anything that's not clear...

<video controls preload="auto" id="video" width="640" height="365" muted>
      <source src="http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_2mb.mp4" type="video/mp4">
    </video>

<script>

 // handler to let me resize the array once we know the length
 Array.prototype.resize = function(newSize, defaultValue) {
    while(newSize > this.length)
        this.push(defaultValue);
    this.length = newSize;
}

// function to round up a number
function roundUp(num, precision) {
  return Math.ceil(num * precision) / precision
} 

var vid = document.getElementById("video")
var duration = 0; // will hold length of the video in seconds
var watched = new Array(0);
var reported80percent = false;

vid.addEventListener('loadedmetadata', getDuration, false);
vid.addEventListener('timeupdate',timeupdate,false)

function timeupdate() {
    currentTime = parseInt(vid.currentTime);
    // set the current second to "1" to flag it as watched
    watched[currentTime] = 1;

    // show the array of seconds so you can track what has been watched
    // you'll note that simply looping over the same few seconds never gets
    // the user closer to the magic 80%...
    console.log(watched);

    // sum the value of the array (add up the "watched" seconds)
    var sum = watched.reduce(function(acc, val) {return acc + val;}, 0);
    // take your desired action on the ?80% completion
    if ((sum >= (duration * .8)) && !reported80percent) {
        // set reported80percent to true so that the action is triggered once and only once
        // could also unregister the timeupdate event to avoid calling unneeded code at this point
        // vid.removeEventListener('timeupdate',timeupdate)
        reported80percent = true;
        console.log("80% watched...")
        // your ajax call to report progress could go here...   
    }
}

function getDuration() {
    console.log("duration:" + vid.duration)
    // get the duration in seconds, rounding up, to size the array
    duration = parseInt(roundUp(vid.duration,1));
    // resize the array, defaulting entries to zero
    console.log("resizing arrary to " + duration + " seconds.");
    watched.resize(duration,0)
}

</script> 

这篇关于如何最好地跟踪视频播放了多长时间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆