这个前端录屏原理是怎么实现的?有大佬知道吗?

2018-07-13 11:21:25 +08:00
 firhome
在找关于前端监控的一些资料的时候 看到 这篇文章:
https://zhuanlan.zhihu.com/p/37182714

非常好奇它这个记录行为的“录屏” 是怎么实现的?
8593 次点击
所在节点    程序员
21 条回复
SouUED
2018-07-13 11:30:54 +08:00
网页转换为 canvas,canvas 传帧到后台,后台在生成视频
randyzhao
2018-07-13 11:33:45 +08:00
感觉是通过插件,记录下每个 click 的位置,click 动作触发的时间、时长,用户的屏幕分辨率。
然后“重放”用户行为的时候:
实际是根据先前记录的用户屏幕分辨率 load 起来一个页面,再用 js 绘制一个“假鼠标”。
然后根据之前记录的 click 事件的时间,位置,来模拟这个假鼠标的行走轨迹
randyzhao
2018-07-13 11:35:08 +08:00
咦。。。一楼说的。。。也行。。。真的生成视频么?
好土豪的样子
firhome
2018-07-13 11:42:32 +08:00
@SouUED 效率不会有问题么? 我比较赞同 下面评论区说的那样,记录鼠标 点击,DOM 的位置。然后报错的时候再上报。 但是 网页界面的表现 不知道背后的原理
Quarter
2018-07-13 11:47:39 +08:00
@randyzhao #2 你说的这个感觉数据量会少一点,但是感觉没有一楼的方便呐,另外,题外话,一秒 24 个数据,可获得电影级流畅体验😂
OSF2E
2018-07-13 11:49:50 +08:00
@randyzhao #3
用四大发明之一的活字印刷术的原理类比一下:
每修改一次活字布局就拍一张照片,并按时间顺序保存照片,把照片流转换为逐帧动画就能“场景重现”了。
另外根据视频中动画的流畅度来看,十有八九用的 canvas,也就是一楼说的原理。
chinaglwo
2018-07-13 11:50:36 +08:00
有没有 ios 或 Android 的解决方案
firhome
2018-07-13 11:54:29 +08:00
@OSF2E 但是作为一个 监控日志 的脚本 这种方法 上传照片 体积不会很大吗?
OSF2E
2018-07-13 11:59:20 +08:00
@firhome 不一定是直接截图,只要把视图渲染逻辑描述清楚,理论上,用 dom+css3/canvas/svg/ios-view/android-view 等视图引擎都可以复现原始视图,例如 react 的 vDOM 思想就是这个原理
LeungJZ
2018-07-13 12:00:25 +08:00
#1 的方案几乎最好吧。但是截屏好像截不了鼠标,而且,最关键的是,要流畅播放,需要一秒 24 帧,那报错的时候,岂不是要上传好几十兆甚至上百兆的图片?

#2 的方案应该最通用。
randyzhao
2018-07-13 12:07:40 +08:00
@OSF2E 没仔细看链接 就看了下官网的描述。。。

又看了遍链接里的视频,应该是 #1 的做法。
Sparetire
2018-07-13 12:30:59 +08:00
记录各种事件生成队列,上传队列以后重放各种事件
tjsdtc
2018-07-13 16:01:59 +08:00
@randyzhao 感觉还是 canvas 截屏简单点,你这个方案如果是每个用户都不同的页面就比较麻烦了,不同的页面都还要回传不同的参数,很难做通用处理
silencefent
2018-07-13 16:56:17 +08:00
用 canvas 画,家里有矿吧
randyzhao
2018-07-13 17:28:26 +08:00
@tjsdtc 嗯 是的。我这个方案,简单的说,很容易出 bug。。。。。
aryu
2018-07-13 21:55:17 +08:00
不确定 fundebug 是怎么做的,不过看原理应该和国外一个很成熟的产品 logrocket 中的回放功能类似。

首先这类功能一般是为了用户行为追踪或者捕获异常前的操作信息,以 sdk 的形式集成到用户的应用中。
因此侵入性强、计算消耗大、网络开销多的方案都是不可能产品化的,上面讨论的 canvas 方案基本也就不可能。

具体来说可以把这个过程看作是 DOM 快照链。

第一步:对界面 DOM 进行一次全量快照。这一步还包括样式的收集、js 脚本的去除等,并通过一定的规则给当前的每个 DOM 元素标记一个 id。

第二步:监听所有可能对界面产生影响的事件,例如各类鼠标事件、输入事件、滚动事件、缩放事件等等,每个事件都记录 payload 和 target,target 是某个 DOM 元素的话就记录为第一步中的 id,这样比记录一个 css selector 数据量要小不少,同时还会定时获取鼠标的绝对坐标,有变化时也记录为一个事件。这样的每一次变化事件可以记录为一次增量的快照。

第三步:一些优化处理,比如浏览器端存一定量的增量快照后再一起发送到服务端,减少网络开销;也包括多次增量之后再进行一次全量,对齐真实状态。

第四步:再后台观看“录制”的时候,其实就是先用全量快照渲染出界面,然后顺着快照链走,按照时间戳把对应的修改重放到页面上,就形成了像视频一样的回放。

以上是我看 logrocket 的视频并且试用,然后逆向了一小部分 sdk 代码之后的分析,仅供参考。
ltq918
2018-07-14 07:43:44 +08:00
Redux 了解一下
SouUED
2018-07-14 09:49:41 +08:00
@aryu 整理了一个不错的思路,我提的那个只是实现的一种思路,仅供参考 工程去实现肯定有很多问题的
SouUED
2018-07-14 10:00:14 +08:00
用 canvas 画的话,难点应该在于什么时候传递数据到后台,传哪些帧到后台,生成视频可能夸张了,直接传 gif 图到后台就行了。我觉得 canvas 网页快照加路径记录加重放的工程可行性高点,性能什么的也好很多
marvinwilliam
2018-07-14 13:21:15 +08:00
MutationObserver

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/470507

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX