分享一个在公司花了半年开发的服务端录制项目 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
BlackHole1
V2EX    分享创造

分享一个在公司花了半年开发的服务端录制项目

  •  2
     
  •   BlackHole1
    PRO
    BlackHole1 2019-12-04 14:57:52 +08:00 7910 次点击
    这是一个创建于 2152 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在公司里花了半年时间写的服务端录制项目(开源的是阉割版,但是基本功能都有) https://github.com/alo7/rebirth/

    Tips: 服务端意指在 docker、服务器上

    优点

    针对标签页进行录制,所以刷新网页、跳转也可以记录下来 也可以记录下网页的声音,即使你的服务器上没有声卡也可以 完善的崩溃、错误处理机制 可以对状态增加自己的代码,而且十分的方便 支持 Chrome 远程协议调试 和 VNC 调试 目前市面上我没找到相同类型的项目(可能有,但是我不知道?) 

    可以用来干嘛:

    在客户端记录下用户操作,在服务端进行复现并录制下来 记录下指定网页的任何变化 如果有客户端录制的功能,则可以减少客户端的电脑要求 

    扩展:

    改改代码,你甚至可以批量录制 P 站(不用买会员了...) 

    技术栈:NodeJS、TypeScript、Chrome Extension、Docker、Puppeteer、Chrome Remote Debugging Protocol

    如果有兴趣的朋友,可以点个 star 支持下...(卑微)

    35 条回复    2020-12-14 16:55:11 +08:00
    dreamerlv3ex
        1
    dreamerlv3ex  
       2019-12-04 15:44:06 +08:00
    是录 chrome 吗,抱歉不很理解.
    BlackHole1
        2
    BlackHole1  
    OP
    PRO
       2019-12-04 15:47:37 +08:00
    @dreamerlv3ex 是录制 chrome 下的 tab 页。tab 页内的网站任何变化都能录制下来(跳转、刷新、声音等)
    dreamerlv3ex
        3
    dreamerlv3ex  
       2019-12-04 15:49:43 +08:00
    @BlackHole1 没有过去文档和代码,提出一下疑问,如果在基础上增加爬虫行为,方便吗? 或者说可能吗?
    superbai
        4
    superbai  
       2019-12-04 15:51:05 +08:00
    用户操作浏览器,在 server 上可以把用户的操作以视频的形式记录下来?是这个目的吗?
    dreamerlv3ex
        5
    dreamerlv3ex  
       2019-12-04 15:51:08 +08:00
    @dreamerlv3ex 比如自己加 Selenium. 各种自动化骚*2操作.还能录制...没关系我就是YY一下.实现应该没问题.
    BlackHole1
        6
    BlackHole1  
    OP
    PRO
       2019-12-04 15:54:32 +08:00
    @dreamerlv3ex 是可以的,但是这个项目核心是录制。除非爬虫的时候有录制需求,不然的话我还是推荐直接用 Puppeteer

    @superbai 是的,当然也可以忽略用户的操作,只录制网页的变化
    dreamerlv3ex
        7
    dreamerlv3ex  
       2019-12-04 15:58:01 +08:00
    @BlackHole1 谢谢 虽然我目前用不上,但是挺开眼界的.
    superbai
        8
    superbai  
       2019-12-04 15:58:14 +08:00
    @BlackHole1 #6 需要用户授权吗?
    BlackHole1
        9
    BlackHole1  
    OP
    PRO
       2019-12-04 16:01:12 +08:00
    @superbai 不需要的。这个项目是在服务端进行录制的,如果有用户授权的行为,那其实是做不了自动化的。所以后来通过对 chrome 增加--whitelisted-extension-id 启动参数,来绕过了这个限制
    Latin
        10
    Latin  
       2019-12-04 16:03:54 +08:00
    哪个 P 站,手动狗头
    wudalang123
        11
    wudalang123  
       2019-12-04 16:48:59 +08:00
    应用场景是什么?》
    BlackHole1
        12
    BlackHole1  
    OP
    PRO
       2019-12-04 16:54:04 +08:00   1
    @wudalang123 把 README 上针对我们公司的应用场景介绍搬过来:

    我们是一个在线教育的公司。在实际业务场景中有一个需求是把上课过程录制下来,并进行 AI 分析,生成本节课的精彩视频,供学生及老师查看。

    因为我们的应用是 Electron 开发的,所以一开始我们使用的是在老师端启动一个屏幕录制,把上课过程录制下来,但是这样做有一个缺点,就是严重依赖了老师的电脑设备及网络带宽,导致我们公司在招聘老师的过程中,电脑性能也是一个非常重要的考察目标。

    为了招聘到更多优秀的老师,避免因为非老师自身问题导致的没有招聘,所带来的影响。从而我们研发出 Rebirth 项目。

    我们的做法是把上课页面完整的复制一份(这里称作 replay),同时在上课过程中,记录下学生和老师的动作行为(鼠标移动、鼠标点击、键盘打字、课件翻页、老师及学生摄像头的画面等),再根据这些动作行为数据,在 replay 里进行一次复现,在复现过程中由 Rebirth 进行录制。从而达到降低老师设备及网络带宽的要求,而且我们一节课可以为公司节省 6~8 元人民币的开销,因为之前屏幕录制使用的是第三方服务。
    Orenoid
        13
    Orenoid  
       2019-12-04 17:02:04 +08:00
    不错,挺有意思的,虽然暂时没什么这方面需求。

    顺便吐槽两点:
    Readme 写得太简略了,不看视频我都不知道怎么用
    Docker 镜像分层多得丧心病狂,那一堆 apt 安装不能合并成一层吗
    richard1122
        14
    richard1122  
       2019-12-04 17:18:12 +08:00
    https://logrocket.com/
    之前看过这个,是不是类似的?
    BlackHole1
        15
    BlackHole1  
    OP
    PRO
       2019-12-04 17:19:00 +08:00
    @Orenoid README 我实在不知道应该怎么写了...较劲脑汁写成这样了...

    以及那个 Dockerfile,是因为如果一次性安装过多时,有很大的几率会 build fail(至今想不明白...)
    BlackHole1
        16
    BlackHole1  
    OP
    PRO
       2019-12-04 17:22:30 +08:00
    @richard1122 看起来是很像,但是实现原理不同,这个貌似无法录制声音、刷新、跳转
    rizon
        17
    rizon  
       2019-12-04 22:36:50 +08:00
    看了一下后还是有些懵。。。

    这个录制的基本实现原理是什么?是在服务端同步了客户端的所有操作行为,然后服务端进行录制? 那比如在网页播放视频的时候怎么保证服务端和客户端的视频播放进度一致的?

    这个同时只能录制一个客户端吧?
    rizon
        18
    rizon  
       2019-12-04 22:54:12 +08:00
    恕我愚钝,想了半天还是没明白。。。。

    这个 docker 镜像是做什么用的?是个演示用的 还是服务端?
    docker 提供了两个接口,一个是 unbuntu 的 vnc 端口?一个 chrome 的 debug 端口?
    然后你在本地的 chrome 打开远程 debug,调试 docker 中的 Chrome 页面,然后本地执行 rebirth 的 录制命令,然后服务器就会录制。。
    但是好懵逼。。。实际的应用中是怎么个流程呢?
    怎么把你的这个东西安装到我们的服务里来?怎么去部署??
    在你们的业务场景中,老师端对应的是你视频里的哪部分?学生端对应的是哪部分?服务器录制是服务器自动化的操作还是需要谁去触发?
    rizon
        19
    rizon  
       2019-12-04 22:55:41 +08:00
    虽然没看懂,但是似乎这东西很厉害的样子。。。
    jobtesting
        20
    jobtesting  
       2019-12-04 23:01:55 +08:00 via iPhone
    在公司写的东西产权归公司,开源要公司同意,否则。。。。
    superbai
        21
    superbai  
       2019-12-04 23:03:43 +08:00
    @jobtesting #20 这个是开源到公司账号下面,没问题吧
    rizon
        22
    rizon  
       2019-12-04 23:11:26 +08:00
    @BlackHole1 #12
    你的描述有些不明白
    上课的页面与直播是相同的,以此为例子
    1. 只需要录制一个人的页面就可以了对吧,因为所有人看到的内容是相同的。而且也不可能同时录制多个客户端的操作,这些操作是不可能同时集中作用到服务器的一个网页上的啊
    2. 录制的内容大部分都是服务器已有的,比如摄像头数据,聊天内容,这些本来就会发送到服务器转发给其他客户端,这个还需要从客户端上传到服务端吗?应该是服务端直接获取才对啊。客户端也没有带宽去上传摄像头等视频内容啊
    3. 如果以上两点成立,也就是你把服务端已有的数据和教师端的页面操作行为拼凑到服务器上的镜像网页中复现。但我觉得这个比较难,服务器上不是镜像网站这么简单,是需要定制化开发的啊,从描述上看你们应该不是这样做的,

    所以 说来说去还是不懂。。。。
    jobtesting
        23
    jobtesting  
       2019-12-04 23:15:34 +08:00 via iPhone
    @superbai 最好上报领导,经技术负责人评估,安全团队评估。
    herozhang
        24
    herozhang  
       2019-12-04 23:38:59 +08:00
    如果是职务作品,所有权是公司的,开源是需要公司授权才行,哪怕是用公司账号做也是要授权的。
    BlackHole1
        25
    BlackHole1  
    OP
    PRO
       2019-12-05 08:57:29 +08:00
    @jobtesting @herozhang 这点可以放心,在开源之前已经得到了公司的授权,代码也经过了公司的 TC 委员会代码 review。没有问题后才进行开源的。并且开源所属账号是公司名下,且 docker images 管理账号也是公司名下的
    BlackHole1
        26
    BlackHole1  
    OP
    PRO
       2019-12-05 09:36:34 +08:00   1
    @rizon 提出的问题很棒。我这里逐一回答下。
    1. 这个录制的基本实现原理
    在服务器上启动一个 chrome 浏览器,并且使用 xvfb 进行虚拟桌面。只所以使用 xvfb 虚拟出一个桌面,是因为项目中使用了 chrome 插件,而 chrome 目前不支持在 headless 模式下注入插件,所以 chrome 启动也不是 headless 模式。启动 chrome 后,同时也会为启动的 chrome 注入一个插件,这个插件会和服务端启动的 server 进行一个通信,打开要录制的网站,并在网站里植入一些 api(start、pause、resume、stop、fail、setExtraInfo)。当网站本身调用了 start 接口开始录制时,会通知到 chrome 插件,插件会调用 chrome extension 插件 api(chrome.tabCapture.capture)。但是这个 api 会有一个需要用户确认的操作,所以我当时翻了下相关的 chrome 的源码。找到了--whitelisted-extension-id 参数,可以绕过。从而达成自动化,但是因为这个 chrome 启动参数需要一个固定的 chrome 插件 id,所以就自己生成了一个 key,来保证 id 固定。整理大致流程就是这样,但是里面的细节非常多,所以后面我会写篇文章进行一个分析、疏通。

    . 是在服务端同步了客户端的所有操作行为,然后服务端进行录制?
    是的

    3. 那比如在网页播放视频的时候怎么保证服务端和客户端的视频播放进度一致的?
    这个问题其实是一个难点,当时要录制的网站是由我的 leader 写的,据我所知,他使用了一个 timingsrc 项目来做相关同步的( https://webtiming.github.io/timingsrc/index.html)。而且我们其实不会说必须 100%和客户端同步,我们客户端每个用户操作其实都会触发一个信令,这个信令数据包含了用户的操作、时间等,在准备录制的时候,后端会基于信令数据生成相关的 json 数据,将要录制的网站就是根据这个 json 数据进行回放操作的,而因为我们是多个视频流(老师、多个学生),多个视频流同步就是我刚刚提到的 timingsrc 项目。

    4. 这个同时只能录制一个客户端么?
    其实是支持多个的,我在设计之初其实就是设计成了一个 chrome 录制多个客户端,其实就是打开多个 tab 页,而且 A Tab 页的声音不会影响 B Tab 页的声音。只不过这种设计不够“最小集”,而且这样对一个 docker(k8s 里为 pod)。占用的资源太大,不利于后面的管理。所以就砍掉了。

    5. 这个 docker 镜像是做什么用的?是个演示用的 还是服务端?
    其实都可以,做成 docker 是因为这个是为了方便演示,以及有人使用 k8s 进行集群部署时方便一点

    6. docker 提供了两个接口,一个是 unbuntu 的 vnc 端口?一个 chrome 的 debug 端口?
    是的,这里应该改为 提供了两个端口

    7. 然后你在本地的 chrome 打开远程 debug,调试 docker 中的 Chrome 页面,然后本地执行 rebirth 的 录制命令,然后服务器就会录制。。但是好懵逼。。。实际的应用中是怎么个流程呢?
    我在演示时只所以这么做有两个原因。1: 当时我不能对我要录制的网站有完整可控权; 2: 我想演示下 vnc 和 remote debug 的连接方式。之所以没有可控权,是因为我无权更改网站代码,所以我不能再网站里写上:“准确就绪后调用 start 接口,等 20 秒调用 stop 接口”。所以你可以看下 https://github.com/alo7/rebirth/tree/master/examples/webm2mp4。这个例子中,录制的是 https://www.bugs.cc/self_page/github/rebirth/webm2mp4/这个网站,而这个网站我写了一个定时器,网站打开后一秒钟开始录制,5 分钟后完成录制。

    8. 怎么把你的这个东西安装到我们的服务里来?怎么去部署??服务器录制是服务器自动化的操作还是需要谁去触发?
    我们公司使用的是 k8s 部署方案,所以 docker 其实就是部署在 k8s 上的 pod 而已。我们公司是这节课上完后,server 把信令转化成 json 格式后,往数据库里插入一条数据。而我写了另一个项目,这个项目就是会定时 3 分钟去扫这个数据,一旦发现有新的录制任务,则会调用 k8s 的 api,启动一个 Job->Pod。来进行录制。并自动回收,因为这个项目代码简单,而且不太方面开源,就没有放出来,可以看下我之前针对这个项目写的文章:基于任务量进行 k8s 集群的灵活调度处理( https://juejin.im/post/5d5ba474f265da03b638aee1)
    Rico
        27
    Rico  
       2019-12-05 09:42:33 +08:00
    对我来说是个很好的参考,感谢楼主。已 star。我想做的是将一些网页 webgl 的动画录制下来生成视频类似于跑步锻炼的那种动态轨迹视频,借鉴意义很大
    ofblyt
        28
    ofblyt  
       2019-12-05 14:41:55 +08:00
    有意思,感觉有点像 dota2 录像的感觉
    rizon
        29
    rizon  
       2019-12-05 22:46:29 +08:00
    @BlackHole1 #26 感谢楼主的耐心回复,我感觉我应该是明白了哈,这个思路确实很有创意也很大胆。感觉也许能好好利用下去做些东西。

    有时间好好学习下,感谢
    rizon
        30
    rizon  
       2019-12-06 11:40:48 +08:00
    @BlackHole1 #26 get 到一个好东西 timesrc 这东西很有意思啊,对于能够基于速度的运动可以用最少的数据交换量实现跨设备的同步,有点意思
    BlackHole1
        31
    BlackHole1  
    OP
    PRO
       2019-12-06 13:18:39 +08:00
    @Rico 写了一篇文章来大概介绍一些原理,有兴趣可以看看: https://www.notion.so/5bda1e4a12c5478baabfd04de965b6f8
    viakiba
        32
    viakiba  
       2019-12-06 15:58:40 +08:00
    感觉和这个差不多 https://recordscreen.io/
    BlackHole1
        33
    BlackHole1  
    OP
    PRO
       2019-12-06 17:11:50 +08:00
    @viakiba 这个不能在服务器上录制,而且必须要用户手动确定才可以
    Rico
        34
    Rico  
       2019-12-07 12:09:33 +08:00
    @BlackHole1 好的,thanks
    x10ng
        35
    x10ng  
       2020-12-14 16:55:11 +08:00
    @BlackHole1 访问不了,能加下吗?
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2621 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 14:46 PVG 22:46 LAX 07:46 JFK 10:46
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86