博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
如何监听页面关闭或刷新动作
阅读量:6228 次
发布时间:2019-06-21

本文共 2404 字,大约阅读时间需要 8 分钟。

原文:

其实这篇文章也可以叫如何监听并上传用户观看的视频时长。最近有需求做到,监听用户播放视频的动作并上报播放事件,需要上报的是用户观看视频的时长。这里就有几种情况了,一是用户点击播放,然后直到视频播放完毕,触发video.ended事件,此时上报用户的观看时长,这个比较好处理。第二种情况是用户点击播放后离开或刷新页面,在用户离开前需要把事件上报,这里主要会触发window.onunload事件,看起来可以做到,其实有坑。

由于公司采用的技术方案是.m3u8(hls),而这种格式目前PC浏览器只有Safari才支持,chrome、Firefox或移动端安卓其他的大部分浏览器都不支持播放这种格式。因此,用原生video标签的方案是不行了,得找一些插件或播放器。最终选择了DPlayer这个播放器,一个比较不错的开源播放器,简单易用。 说回正事,上报用户观看视频的时长。

重要更新

经评论区 @音客 指点,使用将会更好的支持上报事件,这是一个专门处理数据埋点的api,但是使用时请注意浏览器兼容性问题,目前(2018.06)移动端Android 5以上支持,ios需要11.3版本以上,具体请看。 本篇使用new Image()方法可以作为sendBeacon()的不兼容时的降级处理方法,更多请参考:。

目标

用户观看视频结束时上报观看时长。

准备工作

const dp = new DPlayer({        container: document.getElementById('dplayer'),        screenshot: true,        video: {            url: 'xx.m3u8',            pic: 'xx.jpg',            type: 'customHls',            customType: {                'customHls': function (video, player) {                    const hls = new Hls();                    hls.loadSource(video.src);                    hls.attachMedia(video);                }            }        }    });    // 是否播放的标记    var isPlay = false;    dp.on('play', function () {        console.log('player start');        isPlay = true;    });复制代码

第一种常规的情况,用户完整地看完了视频。

dp.on('ended', function () {      console.log('player ended');      sendVideoPlayEvent(); //上报事件方法      isPlay = false;    });复制代码

第二种情况,关闭浏览器或刷新页面

用户关闭页面或刷新浏览器时会触发onunload事件,用户开始观看视频到离开页面,这一段时间就是用户观看视频的时长。

window.onunload = function () {      sendVideoPlayEvent();      isPlay = false;      console.log('onunload');    };复制代码

坑点

经测试发现,sendVideoPlayEvent时,如果采用ajax,无论是post或get方式,将无效。这里的原因可能是页面关闭太快,ajax无法执行。 查了很多解决方案,最后发现,需要通过巧妙的方法来发起这个事件。就是利用img标签的src属性,将img插入到body中时会发起一个请求来获取资源,而服务端可以对这个路由进行处理,最后发现这种方法是可行的,成功地在onunload中上报事件了。

function sendVideoPlayEvent() {      if (isPlay) {        var videoId = getQueryString('videoId');        var duration = dp.video.currentTime; // 视频播放时间可以直接通过currentTime获得        var img = new Image();        img.style.display = 'none';        img.src = `/api/video/play?duration=${duration}&videoId=${videoId}`; // 服务端处理接口        document.body.appendChild(img);      }    }    function getQueryString(name) {        var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");        var r = window.location.search.substr(1).match(reg);        if (r != null) return unescape(r[2]); return null;    }复制代码

总结

  1. 后来想想,script标签的src应该也可以实现,没去验证。
  2. 坑总是很多,多动脑筋。。。
  3. 思路有点局限,应该还有其他解决方案,欢迎建议。

转载地址:http://njxna.baihongyu.com/

你可能感兴趣的文章
Nginx上部署HTTPS + HTTP2
查看>>
awk
查看>>
踩过的坑
查看>>
如何使用 tomcat !!!
查看>>
计算机网络参考模型
查看>>
戴尔的对比
查看>>
8款高质量小程序推荐:(工具类、电影类、阅读类)
查看>>
看图了解RocksDB
查看>>
python整数和变量
查看>>
深入探讨下Linux下修改hostname的五个问题(一)
查看>>
使用HCL模拟器配置DHCP相关项目
查看>>
OC中的NSSet(集合)
查看>>
为什么C++所有程序员都值得一学?
查看>>
如何隐藏IP地址
查看>>
网络yum源
查看>>
WSUS规划部署(一)安装部署WSUS
查看>>
谷歌浏览器不能通过页面打开摄像头的处理
查看>>
mysql+heartbeat双主高可用
查看>>
输入框字数统计(通过键盘输入和拷贝粘贴皆可)
查看>>
Qt笔记(1)连接 SQL Server 数据库
查看>>