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

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

<video width="480" height="400" 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 }
  • 您是在尝试确定视频的每一秒是否都已播放(无法知道是否已观看),还是播放结束时终止,还是什么?您的要求不明确。

标签: javascript html video html5-video


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

添加id 属性:

<video id="video" width="480" height="400" 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 width="200" 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>

          【讨论】:

          • 这与其他答案有何不同?
          猜你喜欢
          • 1970-01-01
          • 2018-03-21
          • 2021-01-31
          • 2018-07-08
          • 1970-01-01
          • 1970-01-01
          • 2016-01-28
          • 1970-01-01
          相关资源
          最近更新 更多