如何检查用户在 html5 视频播放器中观看了完整视频

Posted

技术标签:

【中文标题】如何检查用户在 html5 视频播放器中观看了完整视频【英文标题】:How to check a user watched the full video in html5 video player 【发布时间】:2016-09-14 14:22:41 【问题描述】:

有谁知道我如何检查视频是否已被完整观看? 我正在使用 html5 视频播放器:

<video   controls="true" poster="">
    <source type="video/mp4" src="video.mp4"></source>
</video>

【问题讨论】:

这是我找到的一个解决方案,谢谢大家document.getElementById('myVideo').addEventListener('ended',myHandler,false); function myHandler(e) alert("finished"); // What you want to do after the event 您是在尝试确定视频的每一秒是否都已播放(无法知道是否已观看),还是播放结束时终止,还是什么?您的要求不明确。 【参考方案1】:

基本检查很简单,等待ended事件。这很简单,您只需 google 即可。

现在要检查用户是否播放了完整视频,需要进行广泛的分析,检查他是否每一秒都播放。但是,这不是必需的,用户应该足够了:

播放的秒数与视频长度一样多 播放到视频结尾

这个 sn-p 正是证明了这一点。如果您只是跳到最后,视频将不会被标记为完全播放。一遍又一遍地播放开头也不会将其标记为完全播放:

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

var timeStarted = -1;
var timePlayed = 0;
var duration = 0;
// If video metadata is laoded get duration
if(video.readyState > 0)
  getDuration.call(video);
//If metadata not loaded, use event to get it
else

  video.addEventListener('loadedmetadata', getDuration);

// remember time user started the video
function videoStartedPlaying() 
  timeStarted = new Date().getTime()/1000;

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 number of seconds played
    timePlayed+=playedFor;
  
  document.getElementById("played").innerHTML = Math.round(timePlayed)+"";
  // Count as complete only if end of video was reached
  if(timePlayed>=duration && event.type=="ended") 
    document.getElementById("status").className="complete";
  


function getDuration() 
  duration = video.duration;
  document.getElementById("duration").appendChild(new Text(Math.round(duration)+""));
  console.log("Duration: ", duration);


video.addEventListener("play", videoStartedPlaying);
video.addEventListener("playing", videoStartedPlaying);

video.addEventListener("ended", videoStoppedPlaying);
video.addEventListener("pause", videoStoppedPlaying);
#status span.status 
  display: none;
  font-weight: bold;

span.status.complete 
  color: green;

span.status.incomplete 
  color: red;

#status.complete span.status.complete 
  display: inline;

#status.incomplete span.status.incomplete 
  display: inline;
<video  controls="true" poster="" id="video">
    <source type="video/mp4" src="http://www.w3schools.com/html/mov_bbb.mp4"></source>
</video>

<div id="status" class="incomplete">
<span>Play status: </span>
<span class="status complete">COMPLETE</span>
<span class="status incomplete">INCOMPLETE</span>
<br />
</div>
<div>
<span id="played">0</span> seconds out of 
<span id="duration"></span> seconds. (only updates when the video pauses)
</div>
同样在 jsFiddle 上:https://jsfiddle.net/p56a1r45/2/

然后,您可以将其连接到谷歌分析,以查看有多少视频用户播放。来自google analytics website的简单代码:

ga('send', 'event', 'Videos', 'play', 'Video name');

【讨论】:

这实际上是一个不错的答案。你能帮我关闭视频seeking 选项吗?所以没有人可以向前寻找。 @mrana 在 *** 上,提出不属于您原始问题的内容被认为是不礼貌的。如果您认为互联网上的任何地方都没有解释禁用视频搜索(我敢打赌),请提出另一个问题。 很棒的代码,这真的帮了我很多,我只是想为将来使用此代码的其他人做一个笔记。如果用户暂停视频几次,并且可以将秒数向下舍入而不是向上舍入,您将永远不会收到“完整”消息。 Math.round(timePlayed)+""; 四舍五入到最接近的整数(向上或向下)....将其更改为 Math.ceil(timePlayed)+""; 并且它只会四舍五入以解决此错误。 计算时不会四舍五入 - 仅用于在 HTML 中显示总和。在此处将 round 更改为 ceil 没有任何改变。 如何使用 youtube 嵌入视频做到这一点?【参考方案2】:

添加id 属性:

<video id="video"   controls="true" poster="">
    <source type="video/mp4" src="video.mp4"></source>
</video>

您可以将活动ended 附加到您的视频中:

使用纯 javascript

document.getElementById('video').addEventListener('ended', function(e) 
    // Your code goes here
);

使用 jQuery:

$('#video').bind('ended', function() 
   // Your code goes here
);

【讨论】:

【参考方案3】:

这是一个全面的解决方案:

用户无法向前搜索尚未观看的部分(这也确保了正确的观看顺序,即不会向前跳然后向后跳) 那么就可以简单的检测视频结尾了 另外:当窗口(或选项卡)失去焦点时,视频会暂停,以使用户更有可能在整个过程中实际观看视频 另外:它可以轻松重置为任意数量的观看/视频

(下面的seek禁用功能来自How to disable seeking with HTML5 video tag ?)

假设您在 HTML 中有一个 ID 为 "vid_id" 的视频元素,例如:

<video id="vid_id" controls>
    <source src="whatever.mp4" type="video/mp4">
</video>

您可以使用这些功能:

function vid_listen() 
    var video = document.getElementById('vid_id');
    video.addEventListener('timeupdate', function() 
        if (!video.seeking) 
            if (video.currentTime > timeTracking.watchedTime) 
                timeTracking.watchedTime = video.currentTime;
                lastUpdated = 'watchedTime';
             else 
                //tracking time updated  after user rewinds
                timeTracking.currentTime = video.currentTime;
                lastUpdated = 'currentTime';
            
        
        if (!document.hasFocus()) 
            video.pause();
        
    );
    // prevent user from seeking
    video.addEventListener('seeking', function() 
        var delta = video.currentTime - timeTracking.watchedTime;
        if (delta > 0) 
            video.pause();
            //play back from where the user started seeking after rewind or without rewind
            video.currentTime = timeTracking[lastUpdated];
            video.play();
        
    );
    video.addEventListener("ended", function() 
        // here the end is detected
        console.log("The video has ended");
    );

function vid_start() 
    window.timeTracking = 
        watchedTime: 0,
        currentTime: 0
    ;
    window.lastUpdated = 'currentTime';

在文档加载后的任何时间执行vid_listen()。在视频开始之前的任何时间(或需要进行新的类似检查时)执行vid_start()

【讨论】:

【参考方案4】:
var vid = document.getElementById("myVid");
vid.onended = function() alert("The video has ended");;

【讨论】:

【参考方案5】:

你可以使用:

function getPlayedTime(video) 
    let totalPlayed = 0;
    const played = video.played;

    for (let i = 0; i < played.length; i++) 
        totalPlayed += played.end(i) - played.start(i);
    

    return 
        total: totalPlayed,
        percent: totalPlayed / video.duration * 100,
    ;

【讨论】:

【参考方案6】:

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

var timeStarted = -1;
var timePlayed = 0;
var duration = 0;
// If video metadata is laoded get duration
if(video.readyState > 0)
  getDuration.call(video);
//If metadata not loaded, use event to get it
else

  video.addEventListener('loadedmetadata', getDuration);

// remember time user started the video
function videoStartedPlaying() 
  timeStarted = new Date().getTime()/1000;

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 number of seconds played
    timePlayed+=playedFor;
  
  document.getElementById("played").innerHTML = Math.round(timePlayed)+"";
  // Count as complete only if end of video was reached
  if(timePlayed>=duration && event.type=="ended") 
    document.getElementById("status").className="complete";
  


function getDuration() 
  duration = video.duration;
  document.getElementById("duration").appendChild(new Text(Math.round(duration)+""));
  console.log("Duration: ", duration);


video.addEventListener("play", videoStartedPlaying);
video.addEventListener("playing", videoStartedPlaying);

video.addEventListener("ended", videoStoppedPlaying);
video.addEventListener("pause", videoStoppedPlaying);
#status span.status 
  display: none;
  font-weight: bold;

span.status.complete 
  color: green;

span.status.incomplete 
  color: red;

#status.complete span.status.complete 
  display: inline;

#status.incomplete span.status.incomplete 
  display: inline;
<video  controls="true" poster="" id="video">
    <source type="video/mp4" src="http://www.w3schools.com/html/mov_bbb.mp4"></source>
</video>

<div id="status" class="incomplete">
<span>Play status: </span>
<span class="status complete">COMPLETE</span>
<span class="status incomplete">INCOMPLETE</span>
<br />
</div>
<div>
<span id="played">0</span> seconds out of 
<span id="duration"></span> seconds. (only updates when the video pauses)
</div>

【讨论】:

这与其他答案有何不同?

以上是关于如何检查用户在 html5 视频播放器中观看了完整视频的主要内容,如果未能解决你的问题,请参考以下文章

检查是不是正在播放 HTML5 视频元素

防止通过检查元素下载 html5 视频

仅在缓冲完整视频后才开始播放 HTML5 视频

加载 HTML5 视频时如何制作加载图像?

HTML5 视频删除覆盖播放图标

在 iPad 中观看 PDF 中的视频