puppeteer-screencorder 3.0.6
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puppeteer-screencorder might be problematic. Click here for more details.
- package/CHANGELOG.md +77 -0
- package/LICENSE +21 -0
- package/README.md +271 -0
- 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/lyom9lmp.cjs +1 -0
- package/package.json +140 -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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFnZVZpZGVvU3RyZWFtV3JpdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpYi9wYWdlVmlkZW9TdHJlYW1Xcml0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLG1DQUFzQztBQUN0Qyw0Q0FBb0I7QUFDcEIsK0JBQStCO0FBQy9CLG1DQUErQztBQUUvQywrREFBc0Q7QUFFdEQsaUVBS2dDO0FBRWhDOztHQUVHO0FBQ0gsTUFBTSxzQkFBc0IsR0FBRztJQUM3QiwyQ0FBb0IsQ0FBQyxHQUFHO0lBQ3hCLDJDQUFvQixDQUFDLEdBQUc7SUFDeEIsMkNBQW9CLENBQUMsR0FBRztJQUN4QiwyQ0FBb0IsQ0FBQyxJQUFJO0NBQzFCLENBQUM7QUFFRjs7R0FFRztBQUNILE1BQXFCLHFCQUFzQixTQUFRLHFCQUFZO0lBYTdELFlBQVksaUJBQW9DLEVBQUUsT0FBc0I7UUFDdEUsS0FBSyxFQUFFLENBQUM7UUFiTyxnQkFBVyxHQUFHLEVBQUUsQ0FBQztRQUMxQixxQkFBZ0IsR0FBRyxFQUFFLENBQUM7UUFDdkIsYUFBUSxHQUFHLGFBQWEsQ0FBQztRQUN6QixjQUFTLEdBQUcsQ0FBQyxDQUFDO1FBQ2QsY0FBUyxHQUFHLENBQUMsQ0FBQztRQUViLFdBQU0sR0FBRyx5Q0FBa0IsQ0FBQyxXQUFXLENBQUM7UUFHeEMsd0JBQW1CLEdBQWdCLElBQUksb0JBQVcsRUFBRSxDQUFDO1FBTTNELElBQUksT0FBTyxFQUFFO1lBQ1gsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7U0FDeEI7UUFFRCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUM1RCxJQUFJLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztRQUMzQixJQUFJLFVBQVUsRUFBRTtZQUNkLElBQUksQ0FBQyw0QkFBNEIsQ0FBQyxpQkFBNkIsQ0FBQyxDQUFD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
|
@@ -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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUHVwcGV0ZWVyU2NyZWVuUmVjb3JkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL1B1cHBldGVlclNjcmVlblJlY29yZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLElBQUksQ0FBQztBQUNwQixPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBSy9CLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRXRFLE9BQU8scUJBQXFCLE1BQU0seUJBQXlCLENBQUM7QUFFNUQ7Ozs7R0FJRztBQUNILE1BQU0scUNBQXFDLEdBQW1DO0lBQzVFLFlBQVksRUFBRSxJQUFJO0lBQ2xCLEdBQUcsRUFBRSxFQUFFO0lBQ1AsT0FBTyxFQUFFLEdBQUc7SUFDWixXQUFXLEVBQUUsSUFBSTtJQUNqQixVQUFVLEVBQUU7UUFDVixLQUFLLEVBQUUsSUFBSTtRQUNYLE1BQU0sRUFBRSxJQUFJO0tBQ2I7SUFDRCxXQUFXLEVBQUUsS0FBSztDQUNuQixDQUFDO0FBRUY7Ozs7Ozs7Ozs7Ozs7O0dBY0c7QUFDSCxNQUFNLE9BQU8sdUJBQXVCO0lBQzFCLElBQUksQ0FBTztJQUNYLE9BQU8sQ0FBaUM7SUFDeEMsWUFBWSxDQUEyQjtJQUN2QyxZQUFZLENBQXdCO0lBQ3BDLG9CQUFvQixHQUFtQixJQUFJLENBQUM7SUFFcEQsWUFBWSxJQUFVLEVBQUUsT0FBTyxHQUFHLEVBQUU7UUFDbEMsSUFBSSxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUMsTUFBTSxDQUMxQixFQUFFLEVBQ0YscUNBQXFDLEVBQ3JDLE9BQU8sQ0FDUixDQUFDO1FBQ0YsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLHdCQUF3QixDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDckUsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7SUFDbkIsQ0FBQztJQUVEOztPQUVHO0lBQ0ssY0FBYztRQUNwQixJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsS0FBSyxJQUFJLEVBQUUsQ0FBQyxNQUFNLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBRXZELElBQUksQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDLGlCQUFpQixFQUFFLENBQUMsZUFBZSxFQUFFLEVBQUU7WUFDMUQsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDNUMsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyx3QkFBd0IsRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUN0RSxDQUFDO0lBRUQ7O09BRUc7SUFDSyxLQUFLLENBQUMsb0JBQW9CLENBQUMsT0FBTztRQUN4QyxPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQ3JDLElBQUk7Z0JBQ0YsRUFBRSxDQUFDLFNBQVMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztnQkFDM0MsT0FBTyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7YUFDekI7WUFBQyxPQUFPLEtBQUssRUFBRTtnQkFDZCxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7YUFDZjtRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNLLEtBQUssQ0FBQyxpQkFBaUI7UUFDN0IsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBRXRCLE1BQU0sSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNoQyxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0ksaUJBQWlCO1FBQ3RCLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFO1lBQ3RCLE9BQU8sYUFBYSxDQUFDO1NBQ3RCO1FBQ0QsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQztJQUNwQyxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7OztPQVlHO0lBQ0ksS0FBSyxDQUFDLEtBQUssQ0FBQyxRQUFnQjtRQUNqQyxNQUFNLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztRQUVuRCxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUkscUJBQXFCLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUN0RSxPQUFPLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO0lBQ2xDLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7T0FXRztJQUNJLEtBQUssQ0FBQyxXQUFXLENBQUMsTUFBZ0I7UUFDdkMsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLHFCQUFxQixDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDcEUsT0FBTyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztJQUNsQyxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSSxLQUFLLENBQUMsSUFBSTtRQUNmLElBQUksSUFBSSxDQUFDLG9CQUFvQixLQUFLLElBQUksRUFBRTtZQUN0QyxPQUFPLElBQUksQ0FBQyxvQkFBb0IsQ0FBQztTQUNsQztRQUVELE1BQU0sSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUMvQixJQUFJLENBQUMsb0JBQW9CLEdBQUcsTUFBTSxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQzNELE9BQU8sSUFBSSxDQUFDLG9CQUFvQixDQUFDO0lBQ25DLENBQUM7Q0FDRiJ9
|
@@ -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
|
+
}
|