Coder Social home page Coder Social logo

oct16 / timecat Goto Github PK

View Code? Open in Web Editor NEW
2.3K 44.0 188.0 4.66 MB

A Magical Web Recorder & Player 🖥

Home Page: https://timecatjs.com

License: GNU General Public License v3.0

TypeScript 91.53% JavaScript 6.64% HTML 0.11% SCSS 1.68% Shell 0.04%
recorder replay player virtualdom screenshots audio video chrome chrome-extension

timecat's Introduction

TimeCat

A Magical Web Recorder And Player

GitHub issues GitHub last commit npm (tag)

Description

English | 中文

TimeCat is a open source web Page recording tool that generates files are not real video, but can be played like real video, completely restoring the user's actions in the browser.

🖥 Demo

Documentation

You can find the TimeCat documentation on the website. Check out the Introduction page for a quick overview. You can improve it by sending pull requests to this repository

Version

npm (tag)

Browsers Support

Edge
Edge
Firefox
Firefox
Chrome
Chrome
Safari
Safari

Chrome Plugin

Provides Chrome plugin and supports one-click record and export

TimeCat-Chrome

Installation

Using NPM

$ npm i timecatjs -D

Import in Browser

Add script tags in your browser and use the global variable TimeCat, you can choose the follow CDN:

Usage

Contributing

Feel free to dive in! Open an issue or submit PRs
Standard Readme follows the Contributor Covenant Code of Conduct

Contributors

https://github.com/oct16/TimeCat/graphs/contributors

Donation

License

GPL-3.0

timecat's People

Contributors

cbbfcd avatar dependabot[bot] avatar jerry379 avatar jlalmes avatar oct16 avatar petergw avatar tyy110171 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

timecat's Issues

录制关闭问题

在单页面应用里 跳转页面时关闭录制 跳转完成时 已经关闭录制的所有页面会再走一次录制接口 导致回放时间变长 有什么办法可以解决么

'$npm_execpath' 不是内部或外部命令,也不是可运行的程序

请教一个问题,yarn install的时候提示这个错误如何处理?

yarn install v1.22.4
$ $npm_execpath --silent run checkyarn
'$npm_execpath' 不是内部或外部命令,也不是可运行的程序
或批处理文件。
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.

Use LCP instead of FMP

  • I have searched the issues of this repository and believe that this is not a duplicate.

What problem does this feature solve?

FMP is depcreated. so can we use lcp instead of? like create-react-app use new web-vitals too.

What does the proposed API look like?

just use LCP instead of, i will do a research

chrome 插件在页面跳转时,会取消录制 (版本是1.2.0.2)

  • I have searched the issues of this repository and believe that this is not a duplicate.

Reproduction link

https://chrome.google.com/webstore/detail/timecat-chrome/jgnkkambbdmhfdbdbkljlenddlbplhal

Steps to reproduce

  1. 安装插件
  2. 开始录制
  3. 点击链接,页面跳转

会发现录制中断,被取消了,没有导出

What is expected?

从demo来看,应该是支持多页面的录制的,要怎么操作?

What is actually happening?

录制中断,被取消了,没有导出

Environment Info
System macOS 10.14.6
Browser Chrome 86.0.4240.198

在一些页面的滑动滚动的过程播放不出来

在一些浏览器中(安卓的微信里),长页面的滑动过程播放不出来。
猜测是高度获取的问题。
下面是摘取的录制的数据。
{"data":{"top":0,"left":0},"time":"1598499278169.9","type":"SCROLL"}
{"data":{"top":0,"left":0},"time":"1598499278672","type":"SCROLL"}
{"data":{"top":0,"left":0},"time":"1598499279175.4","type":"SCROLL"}
{"data":{"top":0,"left":0},"time":"1598499279675.4","type":"SCROLL"}

路由切换后canvas没有生成快照

有一个网站含有A,B两个路由。
A路由有一个canvas(填充了图片或者颜色)
B路由只包含一个录制按钮(调用new Recorder())

从B路由开始录制后在进入A路由,发现canvas没有填充图片或者颜色(watcher 没有emit["RecordType"])

在jquery.mobile中使用timecat录制的视频dom错乱

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>jquery.mobile</title>
    <link rel="stylesheet" href="http://apps.bdimg.com/libs/jquerymobile/1.4.5/jquery.mobile-1.4.5.min.css">
    <script src="http://apps.bdimg.com/libs/jquery/1.10.2/jquery.min.js"></script>
    <script src="http://apps.bdimg.com/libs/jquerymobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
</head>
<body>
    <div data-role="page"id="pageone">
			<div data-role="header">
				<h1>第一页</h1>
			</div>
			<div data-role="main" class="ui-content">
				<p>我现在是一个移动端开发者!!</p>
			</div>
			<div data-role="footer">
				<a href="#pagetwo">下一页</a>
			</div>
		</div>
		<div data-role="page"id="pagetwo">
			<div data-role="header">
				<h1>第二页</h1>
			</div>
			<div data-role="main" class="ui-content">
				<form method="post" action="demo_form.php">
					<div class="ui-field-contain">
						<label for="fullname">全名:</label>
						<input type="text" name="fullname" id="fullname">       
						<label for="bday">生日:</label>
		        <input type="date" name="bday" id="bday">
						<label for="email">E-mail:</label>
		        <input type="email" name="email" id="email" placeholder="你的电子邮箱..">
					</div>
					<div class="ui-field-contain">
						<label for="info">附加信息:</label>
						<textarea name="addinfo" id="info"></textarea>
					</div>
					<div class="ui-field-contain">
						<label for="search">搜索:</label>
						<input type="search" name="search" id="search">
					</div>
					<div data-role="fieldcontain">
						<fieldset data-role="controlgroup">
						<legend>请选择您的性别:</legend>
							<label for="male">男性</label>
							<input type="radio" name="gender" id="male" value="male">
							<label for="female">女性</label>
							<input type="radio" name="gender" id="female" value="female"> 
						</fieldset>
					</div>
					<div data-role="fieldcontain">
						<fieldset data-role="controlgroup">
							<legend>请选择您喜爱的颜色:</legend>
								<label for="red">红色</label>
								<input type="checkbox" name="favcolor" id="red" value="red">
								<label for="green">绿色</label>
								<input type="checkbox" name="favcolor" id="green" value="green">
								<label for="blue">蓝色</label>
								<input type="checkbox" name="favcolor" id="blue" value="blue">  
						</fieldset>
					</div>
					<fieldset class="ui-field-contain">
						<label for="day">Select Day</label>
						<select name="day" id="day">
							<option value="mon">Monday</option>
							<option value="tue">Tuesday</option>
							<option value="wed">Wednesday</option>
						</select>
					</fieldset>
					<input type="submit" data-inline="true" value="提交" id="replay">
				</form>
			</div>
		</div>
    <script id="timecat" src="./timecat.global.js"></script>
    <script>
        const { Recorder } = TimeCat
        const recorder = new Recorder({})
        const replayButton = document.getElementById('replay')
        if (replayButton) {
            replayButton.addEventListener('click', () => {
                recorder.unsubscribe()
                window.open('replay.html')
            })
        }
    </script>
</body>
</html>

有一些想法

只是个人的一点想法。
能不能做成浏览器插件,支持录制数据的导出和导入?
因为我发现可以有这样一种使用场景,当一个网络小白需要一些基于网页的帮助时,用文字描述可能有点困难,录视频又得一步步照着做,还不如在这边直接录好动作,让ta导入插件,自动完成操作。

播放的方法能否支持更多选项

能否直接从接口拿到或者支持加载文件数据?
record可用传到服务器,但是replay只能通过socket拿,能不能拿到所有数据再播放

一些问题

如果是一些执行过程中的网络请求或者websocket,怎么保证事件执行和请求响应的顺序呢,最终的一致性是怎么保证的啊

iframe录制时修改iframe的src为另一路径,修改后的页面录制不上

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>TimeCat Iframe Demo</title>

    <style>
        .iframe-container {
            margin-top: 20px;
            padding-bottom: 20px;
            background: white;
            border: 3px solid grey;
            text-align: center;
        }

        iframe {
            max-width: 100%;
            width: 280px;
            display: inline-block;
            margin: 30px
        }

        @media only screen and (max-width: 500px) {
            iframe {
                padding: 0;
            }
        }

        .container {
            margin: 20px 0;
            padding: 20px;
            border: 3px solid grey;
        }

        number {
            margin-left: 10px;
        }

        h2 {
            margin-top: 0;
        }

        #replay {
            border: 1px solid grey;
            padding: 2px 10px;
            margin: 10px;
            color: red;
            font-weight: bold;
            cursor: pointer;
        }

        #replay.locked {
            color: rgb(205, 203, 203);
            border-color: rgb(205, 203, 203);
        }


        #replay.hide {
            visibility: hidden;
        }
    </style>
</head>

<body>
    <!--hidden--><button id="replay" class="locked">Replay</button>
    <div class="container">
        <h2>Window</h2>
        <button>Number ++</button>
        <number>0</number>

        <div class="iframe-container">
            <iframe id="iframe" src="./iframe-1.html" align="top" onload="resizeIframe(this)" frameborder="0"></iframe>
        </div>
    </div>

    <script id="time-cat" src="./timecatjs.min.js"></script>

    <script>
        function resizeIframe(target) {
            target.height = target.contentDocument.documentElement.offsetHeight
        }
        window.onresize = function () {
            setTimeout(() => {
                Array.from(window.frames).forEach(frame => {
                    resizeIframe(frame.frameElement)
                })
            }, 250)
        }

        const { record } = timecat
        const ctrl = record({
            emitter:function(data){
                console.log(data);
            }
        })
        const replayButton = document.getElementById('replay')
        if (replayButton) {
            setTimeout(() => {
                replayButton.className = ''
                document.getElementById('iframe').src="./iframe-2.html";
            }, 5000);
            replayButton.addEventListener('click', () => {
                if (replayButton.className) {
                    return
                }
                replayButton.className = 'hide'
                ctrl.unsubscribe()
                window.open('replay.html')
            })
        }

        const container = document.querySelector('.container');
        const number = container.querySelector('number')
        const button = container.querySelector('button')
        button.addEventListener('click', () => {
            number.innerHTML = Number(number.innerHTML) + 1
        })
    </script>
</body>

</html>

手机端录屏问题

手机端录屏,滚动页面,回放的时候,滚动没法回放,鼠标位置点也不准确

通过window.__ReplayDataList__无法正常播放

源码中获取播放数据可以通过__ReplayDataList__方式,

async function getReplayData() {
    const { socketUrl } = window.__ReplayOptions__

    const replayDataList =
        (socketUrl && (await getAsyncDataFromSocket(socketUrl))) ||
        getGZipData() ||
        (await getDataFromDB()) ||
        window.__ReplayDataList__

    if (!replayDataList) {
        return null
    }
    window.__ReplayDataList__ = replayDataList
    window.__ReplayData__ = Object.assign(
        {
            index: 0
        },
        replayDataList[0]
    )
    return window.__ReplayData__
}

但是我通过以下方式会报错

<script id="time-cat" src="https://cdn.jsdelivr.net/npm/timecatjs@latest/lib/timecatjs.min.js"></script>
    <script src="./data.js"></script>
    <script id="time-cat-init">
        window.onload = function(){
            var __ReplayDataList__ = [{}];
            __ReplayDataList__[0].snapshot = data.splice(0,1)[0];
            __ReplayDataList__[0].records = data;
            __ReplayDataList__[0].audio = null;
            window.__ReplayDataList__ = __ReplayDataList__;
            timecat.replay()
        }
    </script>
timecatjs.min.js:formatted:4875 Uncaught (in promise) TypeError: Cannot read property 'width' of undefined

link标签的虚拟dom转为真实dom后路径不正确

数据部分

{
  attrs:{
    href: "css/chunk-eb698628.4ec2ae32.css",
    rel: "prefetch",
  },
  children: [],
  extra: {},
  id: 17,
  tag: "link",
  type: 1,
}

packages\utils\src\tools\dom.ts中的completionAttrHref方法

if (!/^http/.test(str)) {
        if (str.startsWith('./')) {
            return stitchingLink(href(), str.substring(1))
        } else {
            return stitchingLink(origin(), str)
        }
}

window.ReplayData.snapshot中的

origin: "http://www.example.com"
pathname: "/NrrWeb/index.html"

问题

按照项目中生成的link标签的href地址为http://www.example.com/css/chunk-eb698628.4ec2ae32.css而我实际项目中的href地址应该为http://www.example.com/NrrWeb/css/chunk-eb698628.4ec2ae32.css,少了一层/NrrWeb.

关于带权限系统的录制

TimeCat 需要加载目标页 + 记录动作来进行回放
我的需求是录制带权限的页面,回放时加载目标页用户可能无权访问,这种情况能支持吗?谢谢!

iframe无法录制

  • I have searched the issues of this repository and believe that this is not a duplicate.

Reproduction link

https://timecatjs.com/examples/iframe

Steps to reproduce

打开demo操作,点击reply

What is expected?

iframe1和iframe2正常录制

What is actually happening?

录制result未展示iframe1和iframe2

Environment Info
System macOS 10.15.7
Browser Chrome 90.0.4430.93

华为P20手机兼容问题

用自带浏览器,录制后回放,没有样式。
安卓版本的夸克浏览器也能复现该效果。

PC端微信浏览器录制问题

在PC端微信h5网页进行录制 获取dom结构的时候 无法获取class名 导致播放的时候 没有样式 这个问题该怎么解决

录屏无法播放

调用 recorder 实例的 destroy 事件,会偶现 type 是 10 的 time 小于前面数据的 time。导致 player 播放的时候 packs 的 startTime 和 endTime 计算出问题,就无法播放了
[
...
{
type: 6,
data: {
type: 4,
id: 776
},
relatedId: 'A3RT2M66',
time: 1629806666079
},
{
type: 10,
data: null,
relatedId: 'A3RT2M66',
time: 1629806657826
}]

img 元素中srcset attribute录制结果不准确,有uriencode

  • I have searched the issues of this repository and believe that this is not a duplicate.

我使用的版本是chrome plugin 1.2.0.3

Reproduction link

https://user-images.githubusercontent.com/6702159/103499532-62311c00-4e83-11eb-81e4-04636de8eae4.png

Steps to reproduce

当录制页面中图片存在 attribute srcset, 通常格式是:

<img srcset=" url size, url size, url size " src="default url" >

例如:

image

而在录制之后,url 和size之间的空格就被转译成了 ‘%20’, 结果就是图片变成了404 不可访问的状态

image
类似的attribute data-srcset 则不会出现类似问题

What is expected?

支持srcset

What is actually happening?

支持srcset

Environment Info
System macOS 10.14.6
Browser Chrome 86.0.4240.198

能否保存之前的数据?

我们可能需要保留较久的录屏操作,而这个项目是一个快速迭代的项目,那么如果直接又做了方法的修改,是否会对以前的播放数据有影响

./timecat .global.js

I notice this is referenced in the examples but I do not see the page in the repo.

./timecat .global.js

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.