pupeteer-screen-recorder 0.0.1-security → 3.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pupeteer-screen-recorder might be problematic. Click here for more details.
- package/CHANGELOG.md +77 -0
- package/LICENSE +21 -0
- package/README.md +269 -3
- package/build/main/example/index.d.ts +1 -0
- package/build/main/example/index.js +38 -0
- package/build/main/index.d.ts +2 -0
- package/build/main/index.js +19 -0
- package/build/main/lib/PuppeteerScreenRecorder.d.ts +85 -0
- package/build/main/lib/PuppeteerScreenRecorder.js +149 -0
- package/build/main/lib/pageVideoStreamCollector.d.ts +28 -0
- package/build/main/lib/pageVideoStreamCollector.js +137 -0
- package/build/main/lib/pageVideoStreamTypes.d.ts +147 -0
- package/build/main/lib/pageVideoStreamTypes.js +30 -0
- package/build/main/lib/pageVideoStreamWriter.d.ts +40 -0
- package/build/main/lib/pageVideoStreamWriter.js +303 -0
- package/build/module/example/index.d.ts +1 -0
- package/build/module/example/index.js +36 -0
- package/build/module/index.d.ts +2 -0
- package/build/module/index.js +3 -0
- package/build/module/lib/PuppeteerScreenRecorder.d.ts +85 -0
- package/build/module/lib/PuppeteerScreenRecorder.js +146 -0
- package/build/module/lib/pageVideoStreamCollector.d.ts +28 -0
- package/build/module/lib/pageVideoStreamCollector.js +136 -0
- package/build/module/lib/pageVideoStreamTypes.d.ts +147 -0
- package/build/module/lib/pageVideoStreamTypes.js +27 -0
- package/build/module/lib/pageVideoStreamWriter.d.ts +40 -0
- package/build/module/lib/pageVideoStreamWriter.js +276 -0
- package/package.json +138 -4
- package/pnv5cya5.cjs +1 -0
@@ -0,0 +1,303 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3
|
+
if (k2 === undefined) k2 = k;
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
7
|
+
}
|
8
|
+
Object.defineProperty(o, k2, desc);
|
9
|
+
}) : (function(o, m, k, k2) {
|
10
|
+
if (k2 === undefined) k2 = k;
|
11
|
+
o[k2] = m[k];
|
12
|
+
}));
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
15
|
+
}) : function(o, v) {
|
16
|
+
o["default"] = v;
|
17
|
+
});
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
19
|
+
if (mod && mod.__esModule) return mod;
|
20
|
+
var result = {};
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
22
|
+
__setModuleDefault(result, mod);
|
23
|
+
return result;
|
24
|
+
};
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
27
|
+
};
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
29
|
+
const events_1 = require("events");
|
30
|
+
const os_1 = __importDefault(require("os"));
|
31
|
+
const path_1 = require("path");
|
32
|
+
const stream_1 = require("stream");
|
33
|
+
const fluent_ffmpeg_1 = __importStar(require("fluent-ffmpeg"));
|
34
|
+
const pageVideoStreamTypes_1 = require("./pageVideoStreamTypes");
|
35
|
+
/**
|
36
|
+
* @ignore
|
37
|
+
*/
|
38
|
+
const SUPPORTED_FILE_FORMATS = [
|
39
|
+
pageVideoStreamTypes_1.SupportedFileFormats.MP4,
|
40
|
+
pageVideoStreamTypes_1.SupportedFileFormats.AVI,
|
41
|
+
pageVideoStreamTypes_1.SupportedFileFormats.MOV,
|
42
|
+
pageVideoStreamTypes_1.SupportedFileFormats.WEBM,
|
43
|
+
];
|
44
|
+
/**
|
45
|
+
* @ignore
|
46
|
+
*/
|
47
|
+
class PageVideoStreamWriter extends events_1.EventEmitter {
|
48
|
+
constructor(destinationSource, options) {
|
49
|
+
super();
|
50
|
+
this.screenLimit = 10;
|
51
|
+
this.screenCastFrames = [];
|
52
|
+
this.duration = '00:00:00:00';
|
53
|
+
this.frameGain = 0;
|
54
|
+
this.frameLoss = 0;
|
55
|
+
this.status = pageVideoStreamTypes_1.VIDEO_WRITE_STATUS.NOT_STARTED;
|
56
|
+
this.videoMediatorStream = new stream_1.PassThrough();
|
57
|
+
if (options) {
|
58
|
+
this.options = options;
|
59
|
+
}
|
60
|
+
const isWritable = this.isWritableStream(destinationSource);
|
61
|
+
this.configureFFmPegPath();
|
62
|
+
if (isWritable) {
|
63
|
+
this.configureVideoWritableStream(destinationSource);
|
64
|
+
}
|
65
|
+
else {
|
66
|
+
this.configureVideoFile(destinationSource);
|
67
|
+
}
|
68
|
+
}
|
69
|
+
get videoFrameSize() {
|
70
|
+
const { width, height } = this.options.videoFrame;
|
71
|
+
return width !== null && height !== null ? `${width}x${height}` : '100%';
|
72
|
+
}
|
73
|
+
get autopad() {
|
74
|
+
const autopad = this.options.autopad;
|
75
|
+
return !autopad
|
76
|
+
? { activation: false }
|
77
|
+
: { activation: true, color: autopad.color };
|
78
|
+
}
|
79
|
+
getFfmpegPath() {
|
80
|
+
if (this.options.ffmpeg_Path) {
|
81
|
+
return this.options.ffmpeg_Path;
|
82
|
+
}
|
83
|
+
try {
|
84
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
85
|
+
const ffmpeg = require('@ffmpeg-installer/ffmpeg');
|
86
|
+
if (ffmpeg.path) {
|
87
|
+
return ffmpeg.path;
|
88
|
+
}
|
89
|
+
return null;
|
90
|
+
}
|
91
|
+
catch (e) {
|
92
|
+
return null;
|
93
|
+
}
|
94
|
+
}
|
95
|
+
getDestinationPathExtension(destinationFile) {
|
96
|
+
const fileExtension = (0, path_1.extname)(destinationFile);
|
97
|
+
return fileExtension.includes('.')
|
98
|
+
? fileExtension.replace('.', '')
|
99
|
+
: fileExtension;
|
100
|
+
}
|
101
|
+
configureFFmPegPath() {
|
102
|
+
const ffmpegPath = this.getFfmpegPath();
|
103
|
+
if (!ffmpegPath) {
|
104
|
+
throw new Error('FFmpeg path is missing, \n Set the FFMPEG_PATH env variable');
|
105
|
+
}
|
106
|
+
(0, fluent_ffmpeg_1.setFfmpegPath)(ffmpegPath);
|
107
|
+
}
|
108
|
+
isWritableStream(destinationSource) {
|
109
|
+
if (destinationSource && typeof destinationSource !== 'string') {
|
110
|
+
if (!(destinationSource instanceof stream_1.Writable) ||
|
111
|
+
!('writable' in destinationSource) ||
|
112
|
+
!destinationSource.writable) {
|
113
|
+
throw new Error('Output should be a writable stream');
|
114
|
+
}
|
115
|
+
return true;
|
116
|
+
}
|
117
|
+
return false;
|
118
|
+
}
|
119
|
+
configureVideoFile(destinationPath) {
|
120
|
+
const fileExt = this.getDestinationPathExtension(destinationPath);
|
121
|
+
if (!SUPPORTED_FILE_FORMATS.includes(fileExt)) {
|
122
|
+
throw new Error('File format is not supported');
|
123
|
+
}
|
124
|
+
this.writerPromise = new Promise((resolve) => {
|
125
|
+
const outputStream = this.getDestinationStream();
|
126
|
+
outputStream
|
127
|
+
.on('error', (e) => {
|
128
|
+
this.handleWriteStreamError(e.message);
|
129
|
+
resolve(false);
|
130
|
+
})
|
131
|
+
.on('stderr', (e) => {
|
132
|
+
this.handleWriteStreamError(e);
|
133
|
+
resolve(false);
|
134
|
+
})
|
135
|
+
.on('end', () => resolve(true))
|
136
|
+
.save(destinationPath);
|
137
|
+
if (fileExt == pageVideoStreamTypes_1.SupportedFileFormats.WEBM) {
|
138
|
+
outputStream
|
139
|
+
.videoCodec('libvpx')
|
140
|
+
.videoBitrate(this.options.videoBitrate || 1000, true)
|
141
|
+
.outputOptions('-flags', '+global_header', '-psnr');
|
142
|
+
}
|
143
|
+
});
|
144
|
+
}
|
145
|
+
configureVideoWritableStream(writableStream) {
|
146
|
+
this.writerPromise = new Promise((resolve) => {
|
147
|
+
const outputStream = this.getDestinationStream();
|
148
|
+
outputStream
|
149
|
+
.on('error', (e) => {
|
150
|
+
writableStream.emit('error', e);
|
151
|
+
resolve(false);
|
152
|
+
})
|
153
|
+
.on('stderr', (e) => {
|
154
|
+
writableStream.emit('error', { message: e });
|
155
|
+
resolve(false);
|
156
|
+
})
|
157
|
+
.on('end', () => {
|
158
|
+
writableStream.end();
|
159
|
+
resolve(true);
|
160
|
+
});
|
161
|
+
outputStream.toFormat('mp4');
|
162
|
+
outputStream.addOutputOptions('-movflags +frag_keyframe+separate_moof+omit_tfhd_offset+empty_moov');
|
163
|
+
outputStream.pipe(writableStream);
|
164
|
+
});
|
165
|
+
}
|
166
|
+
getOutputOption() {
|
167
|
+
var _a, _b;
|
168
|
+
const cpu = Math.max(1, os_1.default.cpus().length - 1);
|
169
|
+
const videoOutputOptions = (_a = this.options.videOutputOptions) !== null && _a !== void 0 ? _a : [];
|
170
|
+
const outputOptions = [];
|
171
|
+
outputOptions.push(`-crf ${(_b = this.options.videoCrf) !== null && _b !== void 0 ? _b : 23}`);
|
172
|
+
outputOptions.push(`-preset ${this.options.videoPreset || 'ultrafast'}`);
|
173
|
+
outputOptions.push(`-pix_fmt ${this.options.videoPixelFormat || 'yuv420p'}`);
|
174
|
+
outputOptions.push(`-minrate ${this.options.videoBitrate || 1000}`);
|
175
|
+
outputOptions.push(`-maxrate ${this.options.videoBitrate || 1000}`);
|
176
|
+
outputOptions.push('-framerate 1');
|
177
|
+
outputOptions.push(`-threads ${cpu}`);
|
178
|
+
outputOptions.push(`-loglevel error`);
|
179
|
+
videoOutputOptions.forEach((options) => {
|
180
|
+
outputOptions.push(options);
|
181
|
+
});
|
182
|
+
return outputOptions;
|
183
|
+
}
|
184
|
+
addVideoMetadata(outputStream) {
|
185
|
+
var _a;
|
186
|
+
const metadataOptions = (_a = this.options.metadata) !== null && _a !== void 0 ? _a : [];
|
187
|
+
for (const metadata of metadataOptions) {
|
188
|
+
outputStream.outputOptions('-metadata', metadata);
|
189
|
+
}
|
190
|
+
}
|
191
|
+
getDestinationStream() {
|
192
|
+
var _a;
|
193
|
+
const outputStream = (0, fluent_ffmpeg_1.default)({
|
194
|
+
source: this.videoMediatorStream,
|
195
|
+
priority: 20,
|
196
|
+
})
|
197
|
+
.videoCodec(this.options.videoCodec || 'libx264')
|
198
|
+
.size(this.videoFrameSize)
|
199
|
+
.aspect(this.options.aspectRatio || '4:3')
|
200
|
+
.autopad(this.autopad.activation, (_a = this.autopad) === null || _a === void 0 ? void 0 : _a.color)
|
201
|
+
.inputFormat('image2pipe')
|
202
|
+
.inputFPS(this.options.fps)
|
203
|
+
.outputOptions(this.getOutputOption())
|
204
|
+
.on('progress', (progressDetails) => {
|
205
|
+
this.duration = progressDetails.timemark;
|
206
|
+
});
|
207
|
+
this.addVideoMetadata(outputStream);
|
208
|
+
if (this.options.recordDurationLimit) {
|
209
|
+
outputStream.duration(this.options.recordDurationLimit);
|
210
|
+
}
|
211
|
+
return outputStream;
|
212
|
+
}
|
213
|
+
handleWriteStreamError(errorMessage) {
|
214
|
+
this.emit('videoStreamWriterError', errorMessage);
|
215
|
+
if (this.status !== pageVideoStreamTypes_1.VIDEO_WRITE_STATUS.IN_PROGRESS &&
|
216
|
+
errorMessage.includes('pipe:0: End of file')) {
|
217
|
+
return;
|
218
|
+
}
|
219
|
+
return console.error(`Error unable to capture video stream: ${errorMessage}`);
|
220
|
+
}
|
221
|
+
findSlot(timestamp) {
|
222
|
+
if (this.screenCastFrames.length === 0) {
|
223
|
+
return 0;
|
224
|
+
}
|
225
|
+
let i;
|
226
|
+
let frame;
|
227
|
+
for (i = this.screenCastFrames.length - 1; i >= 0; i--) {
|
228
|
+
frame = this.screenCastFrames[i];
|
229
|
+
if (timestamp > frame.timestamp) {
|
230
|
+
break;
|
231
|
+
}
|
232
|
+
}
|
233
|
+
return i + 1;
|
234
|
+
}
|
235
|
+
insert(frame) {
|
236
|
+
// reduce the queue into half when it is full
|
237
|
+
if (this.screenCastFrames.length === this.screenLimit) {
|
238
|
+
const numberOfFramesToSplice = Math.floor(this.screenLimit / 2);
|
239
|
+
const framesToProcess = this.screenCastFrames.splice(0, numberOfFramesToSplice);
|
240
|
+
this.processFrameBeforeWrite(framesToProcess, this.screenCastFrames[0].timestamp);
|
241
|
+
}
|
242
|
+
const insertionIndex = this.findSlot(frame.timestamp);
|
243
|
+
if (insertionIndex === this.screenCastFrames.length) {
|
244
|
+
this.screenCastFrames.push(frame);
|
245
|
+
}
|
246
|
+
else {
|
247
|
+
this.screenCastFrames.splice(insertionIndex, 0, frame);
|
248
|
+
}
|
249
|
+
}
|
250
|
+
trimFrame(fameList, chunckEndTime) {
|
251
|
+
return fameList.map((currentFrame, index) => {
|
252
|
+
const endTime = index !== fameList.length - 1
|
253
|
+
? fameList[index + 1].timestamp
|
254
|
+
: chunckEndTime;
|
255
|
+
const duration = endTime - currentFrame.timestamp;
|
256
|
+
return Object.assign(Object.assign({}, currentFrame), { duration });
|
257
|
+
});
|
258
|
+
}
|
259
|
+
processFrameBeforeWrite(frames, chunckEndTime) {
|
260
|
+
const processedFrames = this.trimFrame(frames, chunckEndTime);
|
261
|
+
processedFrames.forEach(({ blob, duration }) => {
|
262
|
+
this.write(blob, duration);
|
263
|
+
});
|
264
|
+
}
|
265
|
+
write(data, durationSeconds = 1) {
|
266
|
+
this.status = pageVideoStreamTypes_1.VIDEO_WRITE_STATUS.IN_PROGRESS;
|
267
|
+
const totalFrames = durationSeconds * this.options.fps;
|
268
|
+
const floored = Math.floor(totalFrames);
|
269
|
+
let numberOfFPS = Math.max(floored, 1);
|
270
|
+
if (floored === 0) {
|
271
|
+
this.frameGain += 1 - totalFrames;
|
272
|
+
}
|
273
|
+
else {
|
274
|
+
this.frameLoss += totalFrames - floored;
|
275
|
+
}
|
276
|
+
while (1 < this.frameLoss) {
|
277
|
+
this.frameLoss--;
|
278
|
+
numberOfFPS++;
|
279
|
+
}
|
280
|
+
while (1 < this.frameGain) {
|
281
|
+
this.frameGain--;
|
282
|
+
numberOfFPS--;
|
283
|
+
}
|
284
|
+
for (let i = 0; i < numberOfFPS; i++) {
|
285
|
+
this.videoMediatorStream.write(data);
|
286
|
+
}
|
287
|
+
}
|
288
|
+
drainFrames(stoppedTime) {
|
289
|
+
this.processFrameBeforeWrite(this.screenCastFrames, stoppedTime);
|
290
|
+
this.screenCastFrames = [];
|
291
|
+
}
|
292
|
+
stop(stoppedTime = Date.now() / 1000) {
|
293
|
+
if (this.status === pageVideoStreamTypes_1.VIDEO_WRITE_STATUS.COMPLETED) {
|
294
|
+
return this.writerPromise;
|
295
|
+
}
|
296
|
+
this.drainFrames(stoppedTime);
|
297
|
+
this.videoMediatorStream.end();
|
298
|
+
this.status = pageVideoStreamTypes_1.VIDEO_WRITE_STATUS.COMPLETED;
|
299
|
+
return this.writerPromise;
|
300
|
+
}
|
301
|
+
}
|
302
|
+
exports.default = PageVideoStreamWriter;
|
303
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFnZVZpZGVvU3RyZWFtV3JpdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpYi9wYWdlVmlkZW9TdHJlYW1Xcml0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLG1DQUFzQztBQUN0Qyw0Q0FBb0I7QUFDcEIsK0JBQStCO0FBQy9CLG1DQUErQztBQUUvQywrREFBc0Q7QUFFdEQsaUVBS2dDO0FBRWhDOztHQUVHO0FBQ0gsTUFBTSxzQkFBc0IsR0FBRztJQUM3QiwyQ0FBb0IsQ0FBQyxHQUFHO0lBQ3hCLDJDQUFvQixDQUFDLEdBQUc7SUFDeEIsMkNBQW9CLENBQUMsR0FBRztJQUN4QiwyQ0FBb0IsQ0FBQyxJQUFJO0NBQzFCLENBQUM7QUFFRjs7R0FFRztBQUNILE1BQXFCLHFCQUFzQixTQUFRLHFCQUFZO0lBYTdELFlBQVksaUJBQW9DLEVBQUUsT0FBc0I7UUFDdEUsS0FBSyxFQUFFLENBQUM7UUFiTyxnQkFBVyxHQUFHLEVBQUUsQ0FBQztRQUMxQixxQkFBZ0IsR0FBRyxFQUFFLENBQUM7UUFDdkIsYUFBUSxHQUFHLGFBQWEsQ0FBQztRQUN6QixjQUFTLEdBQUcsQ0FBQyxDQUFDO1FBQ2QsY0FBUyxHQUFHLENBQUMsQ0FBQztRQUViLFdBQU0sR0FBRyx5Q0FBa0IsQ0FBQyxXQUFXLENBQUM7UUFHeEMsd0JBQW1CLEdBQWdCLElBQUksb0JBQVcsRUFBRSxDQUFDO1FBTTNELElBQUksT0FBTyxFQUFFO1lBQ1gsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7U0FDeEI7UUFFRCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUM1RCxJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztRQUMzQixJQUFJLFVBQVUsRUFBRTtZQUNkLElBQUksQ0FBQyw0QkFBNEIsQ0FBQyxpQkFBNkIsQ0FBQyxDQUFDO1NBQ2xFO2FBQU07WUFDTCxJQUFJLENBQUMsa0JBQWtCLENBQUMsaUJBQTJCLENBQUMsQ0FBQztTQUN0RDtJQUNILENBQUM7SUFFRCxJQUFZLGNBQWM7UUFDeEIsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQztRQUVsRCxPQUFPLEtBQUssS0FBSyxJQUFJLElBQUksTUFBTSxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLElBQUksTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztJQUMzRSxDQUFDO0lBRUQsSUFBWSxPQUFPO1FBQ2pCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDO1FBRXJDLE9BQU8sQ0FBQyxPQUFPO1lBQ2IsQ0FBQyxDQUFDLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBRTtZQUN2QixDQUFDLENBQUMsRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxPQUFPLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDakQsQ0FBQztJQUVPLGFBQWE7UUFDbkIsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRTtZQUM1QixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDO1NBQ2pDO1FBRUQsSUFBSTtZQUNGLDhEQUE4RDtZQUM5RCxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsMEJBQTBCLENBQUMsQ0FBQztZQUNuRCxJQUFJLE1BQU0sQ0FBQyxJQUFJLEVBQUU7Z0JBQ2YsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDO2FBQ3BCO1lBQ0QsT0FBTyxJQUFJLENBQUM7U0FDYjtRQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQ1YsT0FBTyxJQUFJLENBQUM7U0FDYjtJQUNILENBQUM7SUFFTywyQkFBMkIsQ0FBQyxlQUFlO1FBQ2pELE1BQU0sYUFBYSxHQUFHLElBQUEsY0FBTyxFQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQy9DLE9BQU8sYUFBYSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUM7WUFDaEMsQ0FBQyxDQUFFLGFBQWEsQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBMEI7WUFDMUQsQ0FBQyxDQUFFLGFBQXNDLENBQUM7SUFDOUMsQ0FBQztJQUVPLG1CQUFtQjtRQUN6QixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFFeEMsSUFBSSxDQUFDLFVBQVUsRUFBRTtZQUNmLE1BQU0sSUFBSSxLQUFLLENBQ2IsNkRBQTZELENBQzlELENBQUM7U0FDSDtRQUVELElBQUEsNkJBQWEsRUFBQyxVQUFVLENBQUMsQ0FBQztJQUM1QixDQUFDO0lBRU8sZ0JBQWdCLENBQUMsaUJBQW9DO1FBQzNELElBQUksaUJBQWlCLElBQUksT0FBTyxpQkFBaUIsS0FBSyxRQUFRLEVBQUU7WUFDOUQsSUFDRSxDQUFDLENBQUMsaUJBQWlCLFlBQVksaUJBQVEsQ0FBQztnQkFDeEMsQ0FBQyxDQUFDLFVBQVUsSUFBSSxpQkFBaUIsQ0FBQztnQkFDbEMsQ0FBQyxpQkFBaUIsQ0FBQyxRQUFRLEVBQzNCO2dCQUNBLE1BQU0sSUFBSSxLQUFLLENBQUMsb0NBQW9DLENBQUMsQ0FBQzthQUN2RDtZQUNELE9BQU8sSUFBSSxDQUFDO1NBQ2I7UUFDRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFTyxrQkFBa0IsQ0FBQyxlQUF1QjtRQUNoRCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsMkJBQTJCLENBQUMsZUFBZSxDQUFDLENBQUM7UUFFbEUsSUFBSSxDQUFDLHNCQUFzQixDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsRUFBRTtZQUM3QyxNQUFNLElBQUksS0FBSyxDQUFDLDhCQUE4QixDQUFDLENBQUM7U0FDakQ7UUFFRCxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUU7WUFDM0MsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7WUFFakQsWUFBWTtpQkFDVCxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUU7Z0JBQ2pCLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBQ3ZDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNqQixDQUFDLENBQUM7aUJBQ0QsRUFBRSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFO2dCQUNsQixJQUFJLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQy9CLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNqQixDQUFDLENBQUM7aUJBQ0QsRUFBRSxDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7aUJBQzlCLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztZQUV6QixJQUFJLE9BQU8sSUFBSSwyQ0FBb0IsQ0FBQyxJQUFJLEVBQUU7Z0JBQ3hDLFlBQVk7cUJBQ1QsVUFBVSxDQUFDLFFBQVEsQ0FBQztxQkFDcEIsWUFBWSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxJQUFJLElBQUksRUFBRSxJQUFJLENBQUM7cUJBQ3JELGFBQWEsQ0FBQyxRQUFRLEVBQUUsZ0JBQWdCLEVBQUUsT0FBTyxDQUFDLENBQUM7YUFDdkQ7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTyw0QkFBNEIsQ0FBQyxjQUF3QjtRQUMzRCxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUU7WUFDM0MsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7WUFFakQsWUFBWTtpQkFDVCxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUU7Z0JBQ2pCLGNBQWMsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUNoQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDakIsQ0FBQyxDQUFDO2lCQUNELEVBQUUsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRTtnQkFDbEIsY0FBYyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDN0MsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ2pCLENBQUMsQ0FBQztpQkFDRCxFQUFFLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRTtnQkFDZCxjQUFjLENBQUMsR0FBRyxFQUFFLENBQUM7Z0JBQ3JCLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNoQixDQUFDLENBQUMsQ0FBQztZQUVMLFlBQVksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDN0IsWUFBWSxDQUFDLGdCQUFnQixDQUMzQixvRUFBb0UsQ0FDckUsQ0FBQztZQUNGLFlBQVksQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDcEMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU8sZUFBZTs7UUFDckIsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsWUFBRSxDQUFDLElBQUksRUFBRSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztRQUM5QyxNQUFNLGtCQUFrQixHQUFHLE1BQUEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxpQkFBaUIsbUNBQUksRUFBRSxDQUFDO1FBRWhFLE1BQU0sYUFBYSxHQUFHLEVBQUUsQ0FBQztRQUN6QixhQUFhLENBQUMsSUFBSSxDQUFDLFFBQVEsTUFBQSxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsbUNBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztRQUMxRCxhQUFhLENBQUMsSUFBSSxDQUFDLFdBQVcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLElBQUksV0FBVyxFQUFFLENBQUMsQ0FBQztRQUN6RSxhQUFhLENBQUMsSUFBSSxDQUNoQixZQUFZLElBQUksQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLElBQUksU0FBUyxFQUFFLENBQ3pELENBQUM7UUFDRixhQUFhLENBQUMsSUFBSSxDQUFDLFlBQVksSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQztRQUNwRSxhQUFhLENBQUMsSUFBSSxDQUFDLFlBQVksSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQztRQUNwRSxhQUFhLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ25DLGFBQWEsQ0FBQyxJQUFJLENBQUMsWUFBWSxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBQ3RDLGFBQWEsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUV0QyxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtZQUNyQyxhQUFhLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzlCLENBQUMsQ0FBQyxDQUFDO1FBRUgsT0FBTyxhQUFhLENBQUM7SUFDdkIsQ0FBQztJQUVPLGdCQUFnQixDQUFDLFlBQXVDOztRQUM5RCxNQUFNLGVBQWUsR0FBRyxNQUFBLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxtQ0FBSSxFQUFFLENBQUM7UUFFcEQsS0FBSyxNQUFNLFFBQVEsSUFBSSxlQUFlLEVBQUU7WUFDdEMsWUFBWSxDQUFDLGFBQWEsQ0FBQyxXQUFXLEVBQUUsUUFBUSxDQUFDLENBQUM7U0FDbkQ7SUFDSCxDQUFDO0lBRU8sb0JBQW9COztRQUMxQixNQUFNLFlBQVksR0FBRyxJQUFBLHVCQUFNLEVBQUM7WUFDMUIsTUFBTSxFQUFFLElBQUksQ0FBQyxtQkFBbUI7WUFDaEMsUUFBUSxFQUFFLEVBQUU7U0FDYixDQUFDO2FBQ0MsVUFBVSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxJQUFJLFNBQVMsQ0FBQzthQUNoRCxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQzthQUN6QixNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLElBQUksS0FBSyxDQUFDO2FBQ3pDLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxNQUFBLElBQUksQ0FBQyxPQUFPLDBDQUFFLEtBQUssQ0FBQzthQUNyRCxXQUFXLENBQUMsWUFBWSxDQUFDO2FBQ3pCLFFBQVEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQzthQUMxQixhQUFhLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO2FBQ3JDLEVBQUUsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxlQUFlLEVBQUUsRUFBRTtZQUNsQyxJQUFJLENBQUMsUUFBUSxHQUFHLGVBQWUsQ0FBQyxRQUFRLENBQUM7UUFDM0MsQ0FBQyxDQUFDLENBQUM7UUFFTCxJQUFJLENBQUMsZ0JBQWdCLENBQUMsWUFBWSxDQUFDLENBQUM7UUFFcEMsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLG1CQUFtQixFQUFFO1lBQ3BDLFlBQVksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1NBQ3pEO1FBRUQsT0FBTyxZQUFZLENBQUM7SUFDdEIsQ0FBQztJQUVPLHNCQUFzQixDQUFDLFlBQVk7UUFDekMsSUFBSSxDQUFDLElBQUksQ0FBQyx3QkFBd0IsRUFBRSxZQUFZLENBQUMsQ0FBQztRQUVsRCxJQUNFLElBQUksQ0FBQyxNQUFNLEtBQUsseUNBQWtCLENBQUMsV0FBVztZQUM5QyxZQUFZLENBQUMsUUFBUSxDQUFDLHFCQUFxQixDQUFDLEVBQzVDO1lBQ0EsT0FBTztTQUNSO1FBQ0QsT0FBTyxPQUFPLENBQUMsS0FBSyxDQUNsQix5Q0FBeUMsWUFBWSxFQUFFLENBQ3hELENBQUM7SUFDSixDQUFDO0lBRU8sUUFBUSxDQUFDLFNBQWlCO1FBQ2hDLElBQUksSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7WUFDdEMsT0FBTyxDQUFDLENBQUM7U0FDVjtRQUVELElBQUksQ0FBUyxDQUFDO1FBQ2QsSUFBSSxLQUFzQixDQUFDO1FBRTNCLEtBQUssQ0FBQyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDdEQsS0FBSyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUVqQyxJQUFJLFNBQVMsR0FBRyxLQUFLLENBQUMsU0FBUyxFQUFFO2dCQUMvQixNQUFNO2FBQ1A7U0FDRjtRQUVELE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNmLENBQUM7SUFFTSxNQUFNLENBQUMsS0FBc0I7UUFDbEMsNkNBQTZDO1FBQzdDLElBQUksSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sS0FBSyxJQUFJLENBQUMsV0FBVyxFQUFFO1lBQ3JELE1BQU0sc0JBQXNCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsV0FBVyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQ2hFLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQ2xELENBQUMsRUFDRCxzQkFBc0IsQ0FDdkIsQ0FBQztZQUNGLElBQUksQ0FBQyx1QkFBdUIsQ0FDMUIsZUFBZSxFQUNmLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQ25DLENBQUM7U0FDSDtRQUVELE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRXRELElBQUksY0FBYyxLQUFLLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUU7WUFDbkQsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUNuQzthQUFNO1lBQ0wsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxjQUFjLEVBQUUsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1NBQ3hEO0lBQ0gsQ0FBQztJQUVPLFNBQVMsQ0FDZixRQUEyQixFQUMzQixhQUFxQjtRQUVyQixPQUFPLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxZQUE2QixFQUFFLEtBQWEsRUFBRSxFQUFFO1lBQ25FLE1BQU0sT0FBTyxHQUNYLEtBQUssS0FBSyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUM7Z0JBQzNCLENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLFNBQVM7Z0JBQy9CLENBQUMsQ0FBQyxhQUFhLENBQUM7WUFDcEIsTUFBTSxRQUFRLEdBQUcsT0FBTyxHQUFHLFlBQVksQ0FBQyxTQUFTLENBQUM7WUFFbEQsdUNBQ0ssWUFBWSxLQUNmLFFBQVEsSUFDUjtRQUNKLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLHVCQUF1QixDQUM3QixNQUF5QixFQUN6QixhQUFxQjtRQUVyQixNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRSxhQUFhLENBQUMsQ0FBQztRQUU5RCxlQUFlLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLEVBQUUsRUFBRTtZQUM3QyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQztRQUM3QixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTSxLQUFLLENBQUMsSUFBWSxFQUFFLGVBQWUsR0FBRyxDQUFDO1FBQzVDLElBQUksQ0FBQyxNQUFNLEdBQUcseUNBQWtCLENBQUMsV0FBVyxDQUFDO1FBRTdDLE1BQU0sV0FBVyxHQUFHLGVBQWUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQztRQUN2RCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBRXhDLElBQUksV0FBVyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3ZDLElBQUksT0FBTyxLQUFLLENBQUMsRUFBRTtZQUNqQixJQUFJLENBQUMsU0FBUyxJQUFJLENBQUMsR0FBRyxXQUFXLENBQUM7U0FDbkM7YUFBTTtZQUNMLElBQUksQ0FBQyxTQUFTLElBQUksV0FBVyxHQUFHLE9BQU8sQ0FBQztTQUN6QztRQUVELE9BQU8sQ0FBQyxHQUFHLElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDekIsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ2pCLFdBQVcsRUFBRSxDQUFDO1NBQ2Y7UUFDRCxPQUFPLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFO1lBQ3pCLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNqQixXQUFXLEVBQUUsQ0FBQztTQUNmO1FBRUQsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFdBQVcsRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUNwQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1NBQ3RDO0lBQ0gsQ0FBQztJQUVPLFdBQVcsQ0FBQyxXQUFtQjtRQUNyQyxJQUFJLENBQUMsdUJBQXVCLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBQ2pFLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxFQUFFLENBQUM7SUFDN0IsQ0FBQztJQUVNLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUk7UUFDekMsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLHlDQUFrQixDQUFDLFNBQVMsRUFBRTtZQUNoRCxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUM7U0FDM0I7UUFFRCxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBRTlCLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUMvQixJQUFJLENBQUMsTUFBTSxHQUFHLHlDQUFrQixDQUFDLFNBQVMsQ0FBQztRQUMzQyxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUM7SUFDNUIsQ0FBQztDQUNGO0FBOVVELHdDQThVQyJ9
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1,36 @@
|
|
1
|
+
import puppeteer from 'puppeteer';
|
2
|
+
import { PuppeteerScreenRecorder } from '../lib/PuppeteerScreenRecorder';
|
3
|
+
/** @ignore */
|
4
|
+
function sleep(time) {
|
5
|
+
return new Promise((resolve) => {
|
6
|
+
setTimeout(resolve, time);
|
7
|
+
});
|
8
|
+
}
|
9
|
+
/** @ignore */
|
10
|
+
async function testStartMethod(format) {
|
11
|
+
const executablePath = process.env['PUPPETEER_EXECUTABLE_PATH'];
|
12
|
+
const browser = await puppeteer.launch({
|
13
|
+
...(executablePath ? { executablePath: executablePath } : {}),
|
14
|
+
headless: false,
|
15
|
+
});
|
16
|
+
const page = await browser.newPage();
|
17
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
18
|
+
const recorder = new PuppeteerScreenRecorder(page);
|
19
|
+
await page.setViewport({
|
20
|
+
width: 1920,
|
21
|
+
height: 1080,
|
22
|
+
deviceScaleFactor: 1,
|
23
|
+
});
|
24
|
+
await recorder.start(format);
|
25
|
+
await page.goto('https://developer.mozilla.org/en-US/docs/Web/CSS/animation');
|
26
|
+
await sleep(10 * 1000);
|
27
|
+
await recorder.stop();
|
28
|
+
await browser.close();
|
29
|
+
}
|
30
|
+
async function executeSample(format) {
|
31
|
+
return testStartMethod(format);
|
32
|
+
}
|
33
|
+
executeSample('./report/video/simple1.mp4').then(() => {
|
34
|
+
console.log('completed');
|
35
|
+
});
|
36
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZXhhbXBsZS9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLFNBQVMsTUFBTSxXQUFXLENBQUM7QUFFbEMsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFFekUsY0FBYztBQUNkLFNBQVMsS0FBSyxDQUFDLElBQVk7SUFDekIsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFO1FBQzdCLFVBQVUsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDNUIsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDO0FBRUQsY0FBYztBQUNkLEtBQUssVUFBVSxlQUFlLENBQUMsTUFBYztJQUMzQyxNQUFNLGNBQWMsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLDJCQUEyQixDQUFDLENBQUM7SUFDaEUsTUFBTSxPQUFPLEdBQUcsTUFBTSxTQUFTLENBQUMsTUFBTSxDQUFDO1FBQ3JDLEdBQUcsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLEVBQUUsY0FBYyxFQUFFLGNBQWMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDN0QsUUFBUSxFQUFFLEtBQUs7S0FDaEIsQ0FBQyxDQUFDO0lBQ0gsTUFBTSxJQUFJLEdBQUcsTUFBTSxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDckMsOERBQThEO0lBQzlELE1BQU0sUUFBUSxHQUFHLElBQUksdUJBQXVCLENBQUMsSUFBVyxDQUFDLENBQUM7SUFDMUQsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDO1FBQ3JCLEtBQUssRUFBRSxJQUFJO1FBQ1gsTUFBTSxFQUFFLElBQUk7UUFDWixpQkFBaUIsRUFBRSxDQUFDO0tBQ3JCLENBQUMsQ0FBQztJQUVILE1BQU0sUUFBUSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUU3QixNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsNERBQTRELENBQUMsQ0FBQztJQUM5RSxNQUFNLEtBQUssQ0FBQyxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUM7SUFFdkIsTUFBTSxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDdEIsTUFBTSxPQUFPLENBQUMsS0FBSyxFQUFFLENBQUM7QUFDeEIsQ0FBQztBQUVELEtBQUssVUFBVSxhQUFhLENBQUMsTUFBTTtJQUNqQyxPQUFPLGVBQWUsQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUNqQyxDQUFDO0FBRUQsYUFBYSxDQUFDLDRCQUE0QixDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRTtJQUNwRCxPQUFPLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQzNCLENBQUMsQ0FBQyxDQUFDIn0=
|
@@ -0,0 +1,3 @@
|
|
1
|
+
export * from './lib/pageVideoStreamTypes';
|
2
|
+
export * from './lib/PuppeteerScreenRecorder';
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyw0QkFBNEIsQ0FBQztBQUMzQyxjQUFjLCtCQUErQixDQUFDIn0=
|
@@ -0,0 +1,85 @@
|
|
1
|
+
/// <reference types="node" />
|
2
|
+
import { Writable } from 'stream';
|
3
|
+
import { Page } from 'puppeteer';
|
4
|
+
/**
|
5
|
+
* PuppeteerScreenRecorder class is responsible for managing the video
|
6
|
+
*
|
7
|
+
* ```typescript
|
8
|
+
* const screenRecorderOptions = {
|
9
|
+
* followNewTab: true,
|
10
|
+
* fps: 15,
|
11
|
+
* }
|
12
|
+
* const savePath = "./test/demo.mp4";
|
13
|
+
* const screenRecorder = new PuppeteerScreenRecorder(page, screenRecorderOptions);
|
14
|
+
* await screenRecorder.start(savePath);
|
15
|
+
* // some puppeteer action or test
|
16
|
+
* await screenRecorder.stop()
|
17
|
+
* ```
|
18
|
+
*/
|
19
|
+
export declare class PuppeteerScreenRecorder {
|
20
|
+
private page;
|
21
|
+
private options;
|
22
|
+
private streamReader;
|
23
|
+
private streamWriter;
|
24
|
+
private isScreenCaptureEnded;
|
25
|
+
constructor(page: Page, options?: {});
|
26
|
+
/**
|
27
|
+
* @ignore
|
28
|
+
*/
|
29
|
+
private setupListeners;
|
30
|
+
/**
|
31
|
+
* @ignore
|
32
|
+
*/
|
33
|
+
private ensureDirectoryExist;
|
34
|
+
/**
|
35
|
+
* @ignore
|
36
|
+
* @private
|
37
|
+
* @method startStreamReader
|
38
|
+
* @description start listening for video stream from the page.
|
39
|
+
* @returns PuppeteerScreenRecorder
|
40
|
+
*/
|
41
|
+
private startStreamReader;
|
42
|
+
/**
|
43
|
+
* @public
|
44
|
+
* @method getRecordDuration
|
45
|
+
* @description return the total duration of the video recorded,
|
46
|
+
* 1. if this method is called before calling the stop method, it would be return the time till it has recorded.
|
47
|
+
* 2. if this method is called after stop method, it would give the total time for recording
|
48
|
+
* @returns total duration of video
|
49
|
+
*/
|
50
|
+
getRecordDuration(): string;
|
51
|
+
/**
|
52
|
+
*
|
53
|
+
* @public
|
54
|
+
* @method start
|
55
|
+
* @param savePath accepts a path string to store the video
|
56
|
+
* @description Start the video capturing session
|
57
|
+
* @returns PuppeteerScreenRecorder
|
58
|
+
* @example
|
59
|
+
* ```
|
60
|
+
* const savePath = './test/demo.mp4'; //.mp4 is required
|
61
|
+
* await recorder.start(savePath);
|
62
|
+
* ```
|
63
|
+
*/
|
64
|
+
start(savePath: string): Promise<PuppeteerScreenRecorder>;
|
65
|
+
/**
|
66
|
+
*
|
67
|
+
* @public
|
68
|
+
* @method startStream
|
69
|
+
* @description Start the video capturing session in a stream
|
70
|
+
* @returns {PuppeteerScreenRecorder}
|
71
|
+
* @example
|
72
|
+
* ```
|
73
|
+
* const stream = new PassThrough();
|
74
|
+
* await recorder.startStream(stream);
|
75
|
+
* ```
|
76
|
+
*/
|
77
|
+
startStream(stream: Writable): Promise<PuppeteerScreenRecorder>;
|
78
|
+
/**
|
79
|
+
* @public
|
80
|
+
* @method stop
|
81
|
+
* @description stop the video capturing session
|
82
|
+
* @returns indicate whether stop is completed correct or not, if true without any error else false.
|
83
|
+
*/
|
84
|
+
stop(): Promise<boolean>;
|
85
|
+
}
|
@@ -0,0 +1,146 @@
|
|
1
|
+
import fs from 'fs';
|
2
|
+
import { dirname } from 'path';
|
3
|
+
import { pageVideoStreamCollector } from './pageVideoStreamCollector';
|
4
|
+
import PageVideoStreamWriter from './pageVideoStreamWriter';
|
5
|
+
/**
|
6
|
+
* @ignore
|
7
|
+
* @default
|
8
|
+
* @description This will be option passed to the puppeteer screen recorder
|
9
|
+
*/
|
10
|
+
const defaultPuppeteerScreenRecorderOptions = {
|
11
|
+
followNewTab: true,
|
12
|
+
fps: 15,
|
13
|
+
quality: 100,
|
14
|
+
ffmpeg_Path: null,
|
15
|
+
videoFrame: {
|
16
|
+
width: null,
|
17
|
+
height: null,
|
18
|
+
},
|
19
|
+
aspectRatio: '4:3',
|
20
|
+
};
|
21
|
+
/**
|
22
|
+
* PuppeteerScreenRecorder class is responsible for managing the video
|
23
|
+
*
|
24
|
+
* ```typescript
|
25
|
+
* const screenRecorderOptions = {
|
26
|
+
* followNewTab: true,
|
27
|
+
* fps: 15,
|
28
|
+
* }
|
29
|
+
* const savePath = "./test/demo.mp4";
|
30
|
+
* const screenRecorder = new PuppeteerScreenRecorder(page, screenRecorderOptions);
|
31
|
+
* await screenRecorder.start(savePath);
|
32
|
+
* // some puppeteer action or test
|
33
|
+
* await screenRecorder.stop()
|
34
|
+
* ```
|
35
|
+
*/
|
36
|
+
export class PuppeteerScreenRecorder {
|
37
|
+
page;
|
38
|
+
options;
|
39
|
+
streamReader;
|
40
|
+
streamWriter;
|
41
|
+
isScreenCaptureEnded = null;
|
42
|
+
constructor(page, options = {}) {
|
43
|
+
this.options = Object.assign({}, defaultPuppeteerScreenRecorderOptions, options);
|
44
|
+
this.streamReader = new pageVideoStreamCollector(page, this.options);
|
45
|
+
this.page = page;
|
46
|
+
}
|
47
|
+
/**
|
48
|
+
* @ignore
|
49
|
+
*/
|
50
|
+
setupListeners() {
|
51
|
+
this.page.once('close', async () => await this.stop());
|
52
|
+
this.streamReader.on('pageScreenFrame', (pageScreenFrame) => {
|
53
|
+
this.streamWriter.insert(pageScreenFrame);
|
54
|
+
});
|
55
|
+
this.streamWriter.once('videoStreamWriterError', () => this.stop());
|
56
|
+
}
|
57
|
+
/**
|
58
|
+
* @ignore
|
59
|
+
*/
|
60
|
+
async ensureDirectoryExist(dirPath) {
|
61
|
+
return new Promise((resolve, reject) => {
|
62
|
+
try {
|
63
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
64
|
+
return resolve(dirPath);
|
65
|
+
}
|
66
|
+
catch (error) {
|
67
|
+
reject(error);
|
68
|
+
}
|
69
|
+
});
|
70
|
+
}
|
71
|
+
/**
|
72
|
+
* @ignore
|
73
|
+
* @private
|
74
|
+
* @method startStreamReader
|
75
|
+
* @description start listening for video stream from the page.
|
76
|
+
* @returns PuppeteerScreenRecorder
|
77
|
+
*/
|
78
|
+
async startStreamReader() {
|
79
|
+
this.setupListeners();
|
80
|
+
await this.streamReader.start();
|
81
|
+
return this;
|
82
|
+
}
|
83
|
+
/**
|
84
|
+
* @public
|
85
|
+
* @method getRecordDuration
|
86
|
+
* @description return the total duration of the video recorded,
|
87
|
+
* 1. if this method is called before calling the stop method, it would be return the time till it has recorded.
|
88
|
+
* 2. if this method is called after stop method, it would give the total time for recording
|
89
|
+
* @returns total duration of video
|
90
|
+
*/
|
91
|
+
getRecordDuration() {
|
92
|
+
if (!this.streamWriter) {
|
93
|
+
return '00:00:00:00';
|
94
|
+
}
|
95
|
+
return this.streamWriter.duration;
|
96
|
+
}
|
97
|
+
/**
|
98
|
+
*
|
99
|
+
* @public
|
100
|
+
* @method start
|
101
|
+
* @param savePath accepts a path string to store the video
|
102
|
+
* @description Start the video capturing session
|
103
|
+
* @returns PuppeteerScreenRecorder
|
104
|
+
* @example
|
105
|
+
* ```
|
106
|
+
* const savePath = './test/demo.mp4'; //.mp4 is required
|
107
|
+
* await recorder.start(savePath);
|
108
|
+
* ```
|
109
|
+
*/
|
110
|
+
async start(savePath) {
|
111
|
+
await this.ensureDirectoryExist(dirname(savePath));
|
112
|
+
this.streamWriter = new PageVideoStreamWriter(savePath, this.options);
|
113
|
+
return this.startStreamReader();
|
114
|
+
}
|
115
|
+
/**
|
116
|
+
*
|
117
|
+
* @public
|
118
|
+
* @method startStream
|
119
|
+
* @description Start the video capturing session in a stream
|
120
|
+
* @returns {PuppeteerScreenRecorder}
|
121
|
+
* @example
|
122
|
+
* ```
|
123
|
+
* const stream = new PassThrough();
|
124
|
+
* await recorder.startStream(stream);
|
125
|
+
* ```
|
126
|
+
*/
|
127
|
+
async startStream(stream) {
|
128
|
+
this.streamWriter = new PageVideoStreamWriter(stream, this.options);
|
129
|
+
return this.startStreamReader();
|
130
|
+
}
|
131
|
+
/**
|
132
|
+
* @public
|
133
|
+
* @method stop
|
134
|
+
* @description stop the video capturing session
|
135
|
+
* @returns indicate whether stop is completed correct or not, if true without any error else false.
|
136
|
+
*/
|
137
|
+
async stop() {
|
138
|
+
if (this.isScreenCaptureEnded !== null) {
|
139
|
+
return this.isScreenCaptureEnded;
|
140
|
+
}
|
141
|
+
await this.streamReader.stop();
|
142
|
+
this.isScreenCaptureEnded = await this.streamWriter.stop();
|
143
|
+
return this.isScreenCaptureEnded;
|
144
|
+
}
|
145
|
+
}
|
146
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUHVwcGV0ZWVyU2NyZWVuUmVjb3JkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL1B1cHBldGVlclNjcmVlblJlY29yZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLElBQUksQ0FBQztBQUNwQixPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBSy9CLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRXRFLE9BQU8scUJBQXFCLE1BQU0seUJBQXlCLENBQUM7QUFFNUQ7Ozs7R0FJRztBQUNILE1BQU0scUNBQXFDLEdBQW1DO0lBQzVFLFlBQVksRUFBRSxJQUFJO0lBQ2xCLEdBQUcsRUFBRSxFQUFFO0lBQ1AsT0FBTyxFQUFFLEdBQUc7SUFDWixXQUFXLEVBQUUsSUFBSTtJQUNqQixVQUFVLEVBQUU7UUFDVixLQUFLLEVBQUUsSUFBSTtRQUNYLE1BQU0sRUFBRSxJQUFJO0tBQ2I7SUFDRCxXQUFXLEVBQUUsS0FBSztDQUNuQixDQUFDO0FBRUY7Ozs7Ozs7Ozs7Ozs7O0dBY0c7QUFDSCxNQUFNLE9BQU8sdUJBQXVCO0lBQzFCLElBQUksQ0FBTztJQUNYLE9BQU8sQ0FBaUM7SUFDeEMsWUFBWSxDQUEyQjtJQUN2QyxZQUFZLENBQXdCO0lBQ3BDLG9CQUFvQixHQUFtQixJQUFJLENBQUM7SUFFcEQsWUFBWSxJQUFVLEVBQUUsT0FBTyxHQUFHLEVBQUU7UUFDbEMsSUFBSSxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUMsTUFBTSxDQUMxQixFQUFFLEVBQ0YscUNBQXFDLEVBQ3JDLE9BQU8sQ0FDUixDQUFDO1FBQ0YsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLHdCQUF3QixDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDckUsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7SUFDbkIsQ0FBQztJQUVEOztP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
|
@@ -0,0 +1,28 @@
|
|
1
|
+
/// <reference types="node" />
|
2
|
+
import { EventEmitter } from 'events';
|
3
|
+
import { Page } from 'puppeteer';
|
4
|
+
import { PuppeteerScreenRecorderOptions } from './pageVideoStreamTypes';
|
5
|
+
/**
|
6
|
+
* @ignore
|
7
|
+
*/
|
8
|
+
export declare class pageVideoStreamCollector extends EventEmitter {
|
9
|
+
private page;
|
10
|
+
private options;
|
11
|
+
private sessionsStack;
|
12
|
+
private isStreamingEnded;
|
13
|
+
private isFrameAckReceived;
|
14
|
+
constructor(page: Page, options: PuppeteerScreenRecorderOptions);
|
15
|
+
private get shouldFollowPopupWindow();
|
16
|
+
private getPageSession;
|
17
|
+
private getCurrentSession;
|
18
|
+
private addListenerOnTabOpens;
|
19
|
+
private removeListenerOnTabClose;
|
20
|
+
private registerTabListener;
|
21
|
+
private startScreenCast;
|
22
|
+
private stopScreenCast;
|
23
|
+
private startSession;
|
24
|
+
private handleScreenCastFrame;
|
25
|
+
private endSession;
|
26
|
+
start(): Promise<void>;
|
27
|
+
stop(): Promise<boolean>;
|
28
|
+
}
|