首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  程序员

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

  •  
  •   firhome · 6 天前 · 1952 次点击
    在找关于前端监控的一些资料的时候 看到 这篇文章:
    https://zhuanlan.zhihu.com/p/37182714

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

    #2 的方案应该最通用。
        11
    randyzhao   6 天前
    @OSF2E 没仔细看链接 就看了下官网的描述。。。

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

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

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

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

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

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

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

    以上是我看 logrocket 的视频并且试用,然后逆向了一小部分 sdk 代码之后的分析,仅供参考。
        17
    ltq918   5 天前 via iPhone
    Redux 了解一下
        18
    SouUED   5 天前 via Android
    @aryu 整理了一个不错的思路,我提的那个只是实现的一种思路,仅供参考 工程去实现肯定有很多问题的
        19
    SouUED   5 天前 via Android
    用 canvas 画的话,难点应该在于什么时候传递数据到后台,传哪些帧到后台,生成视频可能夸张了,直接传 gif 图到后台就行了。我觉得 canvas 网页快照加路径记录加重放的工程可行性高点,性能什么的也好很多
        20
    marvinwilliam   5 天前
    MutationObserver
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   鸣谢   ·   实用小工具   ·   701 人在线   最高记录 3541   ·  
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.1 · 19ms · UTC 19:18 · PVG 03:18 · LAX 12:18 · JFK 15:18
    ♥ Do have faith in what you're doing.
    沪ICP备16043287号-1