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.

@@ -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,2 @@
1
+ export * from './lib/pageVideoStreamTypes';
2
+ export * from './lib/PuppeteerScreenRecorder';
@@ -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
+ }