puppeteer-screencorder 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 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,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
|
+
}
|
@@ -0,0 +1,137 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.pageVideoStreamCollector = void 0;
|
4
|
+
const events_1 = require("events");
|
5
|
+
/**
|
6
|
+
* @ignore
|
7
|
+
*/
|
8
|
+
class pageVideoStreamCollector extends events_1.EventEmitter {
|
9
|
+
constructor(page, options) {
|
10
|
+
super();
|
11
|
+
this.sessionsStack = [];
|
12
|
+
this.isStreamingEnded = false;
|
13
|
+
this.page = page;
|
14
|
+
this.options = options;
|
15
|
+
}
|
16
|
+
get shouldFollowPopupWindow() {
|
17
|
+
return this.options.followNewTab;
|
18
|
+
}
|
19
|
+
async getPageSession(page) {
|
20
|
+
try {
|
21
|
+
const context = page.target();
|
22
|
+
return await context.createCDPSession();
|
23
|
+
}
|
24
|
+
catch (error) {
|
25
|
+
console.log('Failed to create CDP Session', error);
|
26
|
+
return null;
|
27
|
+
}
|
28
|
+
}
|
29
|
+
getCurrentSession() {
|
30
|
+
return this.sessionsStack[this.sessionsStack.length - 1];
|
31
|
+
}
|
32
|
+
addListenerOnTabOpens(page) {
|
33
|
+
page.on('popup', (newPage) => this.registerTabListener(newPage));
|
34
|
+
}
|
35
|
+
removeListenerOnTabClose(page) {
|
36
|
+
page.off('popup', (newPage) => this.registerTabListener(newPage));
|
37
|
+
}
|
38
|
+
async registerTabListener(newPage) {
|
39
|
+
await this.startSession(newPage);
|
40
|
+
newPage.once('close', async () => await this.endSession());
|
41
|
+
}
|
42
|
+
async startScreenCast(shouldDeleteSessionOnFailure = false) {
|
43
|
+
const currentSession = this.getCurrentSession();
|
44
|
+
const quality = Number.isNaN(this.options.quality)
|
45
|
+
? 100
|
46
|
+
: Math.max(Math.min(this.options.quality, 100), 0);
|
47
|
+
try {
|
48
|
+
await currentSession.send('Animation.setPlaybackRate', {
|
49
|
+
playbackRate: 1,
|
50
|
+
});
|
51
|
+
await currentSession.send('Page.startScreencast', {
|
52
|
+
everyNthFrame: 1,
|
53
|
+
format: this.options.format || 'jpeg',
|
54
|
+
quality: quality,
|
55
|
+
});
|
56
|
+
}
|
57
|
+
catch (e) {
|
58
|
+
if (shouldDeleteSessionOnFailure) {
|
59
|
+
this.endSession();
|
60
|
+
}
|
61
|
+
}
|
62
|
+
}
|
63
|
+
async stopScreenCast() {
|
64
|
+
const currentSession = this.getCurrentSession();
|
65
|
+
if (!currentSession) {
|
66
|
+
return;
|
67
|
+
}
|
68
|
+
await currentSession.send('Page.stopScreencast');
|
69
|
+
}
|
70
|
+
async startSession(page) {
|
71
|
+
const pageSession = await this.getPageSession(page);
|
72
|
+
if (!pageSession) {
|
73
|
+
return;
|
74
|
+
}
|
75
|
+
await this.stopScreenCast();
|
76
|
+
this.sessionsStack.push(pageSession);
|
77
|
+
this.handleScreenCastFrame(pageSession);
|
78
|
+
await this.startScreenCast(true);
|
79
|
+
}
|
80
|
+
async handleScreenCastFrame(session) {
|
81
|
+
this.isFrameAckReceived = new Promise((resolve) => {
|
82
|
+
session.on('Page.screencastFrame', async ({ metadata, data, sessionId }) => {
|
83
|
+
if (!metadata.timestamp || this.isStreamingEnded) {
|
84
|
+
return resolve();
|
85
|
+
}
|
86
|
+
const ackPromise = session.send('Page.screencastFrameAck', {
|
87
|
+
sessionId: sessionId,
|
88
|
+
});
|
89
|
+
this.emit('pageScreenFrame', {
|
90
|
+
blob: Buffer.from(data, 'base64'),
|
91
|
+
timestamp: metadata.timestamp,
|
92
|
+
});
|
93
|
+
try {
|
94
|
+
await ackPromise;
|
95
|
+
}
|
96
|
+
catch (error) {
|
97
|
+
console.error('Error in sending Acknowledgment for PageScreenCast', error.message);
|
98
|
+
}
|
99
|
+
});
|
100
|
+
});
|
101
|
+
}
|
102
|
+
async endSession() {
|
103
|
+
this.sessionsStack.pop();
|
104
|
+
await this.startScreenCast();
|
105
|
+
}
|
106
|
+
async start() {
|
107
|
+
await this.startSession(this.page);
|
108
|
+
this.page.once('close', async () => await this.endSession());
|
109
|
+
if (this.shouldFollowPopupWindow) {
|
110
|
+
this.addListenerOnTabOpens(this.page);
|
111
|
+
}
|
112
|
+
}
|
113
|
+
async stop() {
|
114
|
+
if (this.isStreamingEnded) {
|
115
|
+
return this.isStreamingEnded;
|
116
|
+
}
|
117
|
+
if (this.shouldFollowPopupWindow) {
|
118
|
+
this.removeListenerOnTabClose(this.page);
|
119
|
+
}
|
120
|
+
await Promise.race([
|
121
|
+
this.isFrameAckReceived,
|
122
|
+
new Promise((resolve) => setTimeout(resolve, 1000)),
|
123
|
+
]);
|
124
|
+
this.isStreamingEnded = true;
|
125
|
+
try {
|
126
|
+
for (const currentSession of this.sessionsStack) {
|
127
|
+
await currentSession.detach();
|
128
|
+
}
|
129
|
+
}
|
130
|
+
catch (e) {
|
131
|
+
console.warn('Error detaching session', e.message);
|
132
|
+
}
|
133
|
+
return true;
|
134
|
+
}
|
135
|
+
}
|
136
|
+
exports.pageVideoStreamCollector = pageVideoStreamCollector;
|
137
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFnZVZpZGVvU3RyZWFtQ29sbGVjdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpYi9wYWdlVmlkZW9TdHJlYW1Db2xsZWN0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsbUNBQXNDO0FBTXRDOztHQUVHO0FBQ0gsTUFBYSx3QkFBeUIsU0FBUSxxQkFBWTtJQVF4RCxZQUFZLElBQVUsRUFBRSxPQUF1QztRQUM3RCxLQUFLLEVBQUUsQ0FBQztRQU5GLGtCQUFhLEdBQWtCLEVBQUUsQ0FBQztRQUNsQyxxQkFBZ0IsR0FBRyxLQUFLLENBQUM7UUFNL0IsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFDakIsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7SUFDekIsQ0FBQztJQUVELElBQVksdUJBQXVCO1FBQ2pDLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUM7SUFDbkMsQ0FBQztJQUVPLEtBQUssQ0FBQyxjQUFjLENBQUMsSUFBVTtRQUNyQyxJQUFJO1lBQ0YsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQzlCLE9BQU8sTUFBTSxPQUFPLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztTQUN6QztRQUFDLE9BQU8sS0FBSyxFQUFFO1lBQ2QsT0FBTyxDQUFDLEdBQUcsQ0FBQyw4QkFBOEIsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNuRCxPQUFPLElBQUksQ0FBQztTQUNiO0lBQ0gsQ0FBQztJQUVPLGlCQUFpQjtRQUN2QixPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDM0QsQ0FBQztJQUVPLHFCQUFxQixDQUFDLElBQVU7UUFDdEMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO0lBQ25FLENBQUM7SUFFTyx3QkFBd0IsQ0FBQyxJQUFVO1FBQ3pDLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztJQUNwRSxDQUFDO0lBRU8sS0FBSyxDQUFDLG1CQUFtQixDQUFDLE9BQWE7UUFDN0MsTUFBTSxJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2pDLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEtBQUssSUFBSSxFQUFFLENBQUMsTUFBTSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQztJQUM3RCxDQUFDO0lBRU8sS0FBSyxDQUFDLGVBQWUsQ0FBQyw0QkFBNEIsR0FBRyxLQUFLO1FBQ2hFLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQ2hELE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUM7WUFDaEQsQ0FBQyxDQUFDLEdBQUc7WUFDTCxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3JELElBQUk7WUFDRixNQUFNLGNBQWMsQ0FBQyxJQUFJLENBQUMsMkJBQTJCLEVBQUU7Z0JBQ3JELFlBQVksRUFBRSxDQUFDO2FBQ2hCLENBQUMsQ0FBQztZQUNILE1BQU0sY0FBYyxDQUFDLElBQUksQ0FBQyxzQkFBc0IsRUFBRTtnQkFDaEQsYUFBYSxFQUFFLENBQUM7Z0JBQ2hCLE1BQU0sRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sSUFBSSxNQUFNO2dCQUNyQyxPQUFPLEVBQUUsT0FBTzthQUNqQixDQUFDLENBQUM7U0FDSjtRQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQ1YsSUFBSSw0QkFBNEIsRUFBRTtnQkFDaEMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO2FBQ25CO1NBQ0Y7SUFDSCxDQUFDO0lBRU8sS0FBSyxDQUFDLGNBQWM7UUFDMUIsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFDaEQsSUFBSSxDQUFDLGNBQWMsRUFBRTtZQUNuQixPQUFPO1NBQ1I7UUFDRCxNQUFNLGNBQWMsQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQztJQUNuRCxDQUFDO0lBRU8sS0FBSyxDQUFDLFlBQVksQ0FBQyxJQUFVO1FBQ25DLE1BQU0sV0FBVyxHQUFHLE1BQU0sSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNwRCxJQUFJLENBQUMsV0FBVyxFQUFFO1lBQ2hCLE9BQU87U0FDUjtRQUNELE1BQU0sSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQzVCLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ3JDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUN4QyxNQUFNLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDbkMsQ0FBQztJQUVPLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxPQUFPO1FBQ3pDLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFO1lBQ2hELE9BQU8sQ0FBQyxFQUFFLENBQ1Isc0JBQXNCLEVBQ3RCLEtBQUssRUFBRSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLEVBQUUsRUFBRTtnQkFDdEMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLGdCQUFnQixFQUFFO29CQUNoRCxPQUFPLE9BQU8sRUFBRSxDQUFDO2lCQUNsQjtnQkFFRCxNQUFNLFVBQVUsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLHlCQUF5QixFQUFFO29CQUN6RCxTQUFTLEVBQUUsU0FBUztpQkFDckIsQ0FBQyxDQUFDO2dCQUVILElBQUksQ0FBQyxJQUFJLENBQUMsaUJBQWlCLEVBQUU7b0JBQzNCLElBQUksRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUM7b0JBQ2pDLFNBQVMsRUFBRSxRQUFRLENBQUMsU0FBUztpQkFDOUIsQ0FBQyxDQUFDO2dCQUVILElBQUk7b0JBQ0YsTUFBTSxVQUFVLENBQUM7aUJBQ2xCO2dCQUFDLE9BQU8sS0FBSyxFQUFFO29CQUNkLE9BQU8sQ0FBQyxLQUFLLENBQ1gsb0RBQW9ELEVBQ3BELEtBQUssQ0FBQyxPQUFPLENBQ2QsQ0FBQztpQkFDSDtZQUNILENBQUMsQ0FDRixDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU8sS0FBSyxDQUFDLFVBQVU7UUFDdEIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUN6QixNQUFNLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztJQUMvQixDQUFDO0lBRU0sS0FBSyxDQUFDLEtBQUs7UUFDaEIsTUFBTSxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNuQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsS0FBSyxJQUFJLEVBQUUsQ0FBQyxNQUFNLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDO1FBRTdELElBQUksSUFBSSxDQUFDLHVCQUF1QixFQUFFO1lBQ2hDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDdkM7SUFDSCxDQUFDO0lBRU0sS0FBSyxDQUFDLElBQUk7UUFDZixJQUFJLElBQUksQ0FBQyxnQkFBZ0IsRUFBRTtZQUN6QixPQUFPLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQztTQUM5QjtRQUVELElBQUksSUFBSSxDQUFDLHVCQUF1QixFQUFFO1lBQ2hDLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDMUM7UUFFRCxNQUFNLE9BQU8sQ0FBQyxJQUFJLENBQUM7WUFDakIsSUFBSSxDQUFDLGtCQUFrQjtZQUN2QixJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsVUFBVSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQztTQUNwRCxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDO1FBRTdCLElBQUk7WUFDRixLQUFLLE1BQU0sY0FBYyxJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUU7Z0JBQy9DLE1BQU0sY0FBYyxDQUFDLE1BQU0sRUFBRSxDQUFDO2FBQy9CO1NBQ0Y7UUFBQyxPQUFPLENBQUMsRUFBRTtZQUNWLE9BQU8sQ0FBQyxJQUFJLENBQUMseUJBQXlCLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1NBQ3BEO1FBRUQsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0NBQ0Y7QUE1SkQsNERBNEpDIn0=
|
@@ -0,0 +1,147 @@
|
|
1
|
+
/// <reference types="node" />
|
2
|
+
/**
|
3
|
+
* @ignore
|
4
|
+
* @enum VIDEO_WRITE_STATUS
|
5
|
+
*/
|
6
|
+
export declare enum VIDEO_WRITE_STATUS {
|
7
|
+
'NOT_STARTED' = 0,
|
8
|
+
'IN_PROGRESS' = 1,
|
9
|
+
'COMPLETED' = 2,
|
10
|
+
'ERROR' = 3
|
11
|
+
}
|
12
|
+
/**
|
13
|
+
* @ignore
|
14
|
+
* @type PageScreen
|
15
|
+
*/
|
16
|
+
export type pageScreenFrame = {
|
17
|
+
readonly blob: Buffer;
|
18
|
+
readonly timestamp: number;
|
19
|
+
readonly duration?: number;
|
20
|
+
};
|
21
|
+
export type PuppeteerScreenRecorderOptions = {
|
22
|
+
/**
|
23
|
+
* @name followNewTab
|
24
|
+
* @member PuppeteerScreenRecorderOptions
|
25
|
+
* @description Boolean value which is indicate whether to follow the tab or not. Default value is true.
|
26
|
+
* @default true
|
27
|
+
* */
|
28
|
+
readonly followNewTab: boolean;
|
29
|
+
/**
|
30
|
+
* @name fps
|
31
|
+
* @member PuppeteerScreenRecorderOptions
|
32
|
+
* @description Numeric value which denotes no.of Frames per second in which the video should be recorded. default value is 25.
|
33
|
+
* @default 25
|
34
|
+
*/
|
35
|
+
readonly fps?: number;
|
36
|
+
/**
|
37
|
+
* @name quality
|
38
|
+
* @member PuppeteerScreenRecorderOptions
|
39
|
+
* @description Numeric value which denotes no.of quality of individual frame captured by chrome. Value accepted 0 - 100. 100 denotes the highest quality and 0 denotes the lowest quality
|
40
|
+
* @default 100
|
41
|
+
*/
|
42
|
+
readonly quality?: number;
|
43
|
+
/**
|
44
|
+
* @name format
|
45
|
+
* @member PuppeteerScreenRecorderOptions
|
46
|
+
* @description specify the format for recording the video
|
47
|
+
* @default jpeg
|
48
|
+
*/
|
49
|
+
readonly format?: 'jpeg' | 'png';
|
50
|
+
/**
|
51
|
+
* @name ffmpeg_Path
|
52
|
+
* @member PuppeteerScreenRecorderOptions
|
53
|
+
* @description String value pointing to the installation of FFMPEG. Default is null (Automatically install the FFMPEG and use it).
|
54
|
+
* @default null
|
55
|
+
*/
|
56
|
+
readonly ffmpeg_Path?: string | null;
|
57
|
+
/**
|
58
|
+
* @name videoFrame
|
59
|
+
* @member PuppeteerScreenRecorderOptions
|
60
|
+
* @description An object which specifies the width and height of the output video frame.
|
61
|
+
* Note: VideoFrame option is not applicable for capturing the video.
|
62
|
+
*/
|
63
|
+
readonly videoFrame?: {
|
64
|
+
width: number | null;
|
65
|
+
height: number | null;
|
66
|
+
};
|
67
|
+
/**
|
68
|
+
* @name aspectRatio
|
69
|
+
* @member PuppeteerScreenRecorderOptions
|
70
|
+
* @description Specify the aspect ratio of the video. Default value is 4:3.
|
71
|
+
* @default 4:3
|
72
|
+
*/
|
73
|
+
readonly aspectRatio?: '3:2' | '4:3' | '16:9';
|
74
|
+
/**
|
75
|
+
* @name videoCodec
|
76
|
+
* @member PuppeteerScreenRecorderOptions
|
77
|
+
* @description Specify the codec used by FFMPEG when creating the final video file. The default value is libx264.
|
78
|
+
*/
|
79
|
+
readonly videoCodec?: string;
|
80
|
+
/**
|
81
|
+
* @name videoBitrate
|
82
|
+
* @member PuppeteerScreenRecorderOptions
|
83
|
+
* @description Specify the target bitrate of the final video file in bits/s. The default value is 1000.
|
84
|
+
*/
|
85
|
+
readonly videoBitrate?: number;
|
86
|
+
/**
|
87
|
+
* @name videoCrf
|
88
|
+
* @member PuppeteerScreenRecorderOptions
|
89
|
+
* @description Specify the crf of the final video file. The default value is 23.
|
90
|
+
*/
|
91
|
+
readonly videoCrf?: number;
|
92
|
+
/**
|
93
|
+
* @name videoPreset
|
94
|
+
* @member PuppeteerScreenRecorderOptions
|
95
|
+
* @description Specify the preset to use when encoding the video file. The default value is 'ultrafast'.
|
96
|
+
*/
|
97
|
+
readonly videoPreset?: string;
|
98
|
+
/**
|
99
|
+
* @name videoPixelFormat
|
100
|
+
* @member PuppeteerScreenRecorderOptions
|
101
|
+
* @description Specify the pixel format to use when encoding the video file. The default value is 'yuv420p'.
|
102
|
+
*/
|
103
|
+
readonly videoPixelFormat?: string;
|
104
|
+
/**
|
105
|
+
* @name videOutputOptions
|
106
|
+
* @member PuppeteerScreenRecorderOptions
|
107
|
+
* @description Allows you to pass additional options to the ffmpeg encoder -
|
108
|
+
* @example you might want to pass "-movflags +faststart"
|
109
|
+
*/
|
110
|
+
readonly videOutputOptions?: string[];
|
111
|
+
/**
|
112
|
+
* @name autopad
|
113
|
+
* @member PuppeteerScreenRecorderOptions
|
114
|
+
* @description Specify whether autopad option is used and its color. Default to autopad deactivation mode.
|
115
|
+
*/
|
116
|
+
readonly autopad?: {
|
117
|
+
color?: string;
|
118
|
+
};
|
119
|
+
/**
|
120
|
+
* @name recordDurationLimit
|
121
|
+
* @member PuppeteerScreenRecorderOptions
|
122
|
+
* @description Numerical value specify duration (in seconds) to record the video. By default video is recorded till stop method is invoked`. (Note: It's mandatory to invoke Stop() method even if this value is set)
|
123
|
+
*/
|
124
|
+
readonly recordDurationLimit?: number;
|
125
|
+
/**
|
126
|
+
* @name metadata
|
127
|
+
* @member PuppeteerScreenRecorderOptions
|
128
|
+
* @description Specify metadata information as key value pairs.
|
129
|
+
*/
|
130
|
+
readonly metadata?: string[];
|
131
|
+
};
|
132
|
+
/** @ignore */
|
133
|
+
export type VideoOptions = Omit<PuppeteerScreenRecorderOptions, 'followNewTab'>;
|
134
|
+
/**
|
135
|
+
* @description supported video format for recording.
|
136
|
+
* @example
|
137
|
+
* recording.start('./video.mp4');
|
138
|
+
* recording.start('./video.mov');
|
139
|
+
* recording.start('./video.webm');
|
140
|
+
* recording.start('./video.avi');
|
141
|
+
*/
|
142
|
+
export declare enum SupportedFileFormats {
|
143
|
+
MP4 = "mp4",
|
144
|
+
MOV = "mov",
|
145
|
+
AVI = "avi",
|
146
|
+
WEBM = "webm"
|
147
|
+
}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.SupportedFileFormats = exports.VIDEO_WRITE_STATUS = void 0;
|
4
|
+
/**
|
5
|
+
* @ignore
|
6
|
+
* @enum VIDEO_WRITE_STATUS
|
7
|
+
*/
|
8
|
+
var VIDEO_WRITE_STATUS;
|
9
|
+
(function (VIDEO_WRITE_STATUS) {
|
10
|
+
VIDEO_WRITE_STATUS[VIDEO_WRITE_STATUS["NOT_STARTED"] = 0] = "NOT_STARTED";
|
11
|
+
VIDEO_WRITE_STATUS[VIDEO_WRITE_STATUS["IN_PROGRESS"] = 1] = "IN_PROGRESS";
|
12
|
+
VIDEO_WRITE_STATUS[VIDEO_WRITE_STATUS["COMPLETED"] = 2] = "COMPLETED";
|
13
|
+
VIDEO_WRITE_STATUS[VIDEO_WRITE_STATUS["ERROR"] = 3] = "ERROR";
|
14
|
+
})(VIDEO_WRITE_STATUS || (exports.VIDEO_WRITE_STATUS = VIDEO_WRITE_STATUS = {}));
|
15
|
+
/**
|
16
|
+
* @description supported video format for recording.
|
17
|
+
* @example
|
18
|
+
* recording.start('./video.mp4');
|
19
|
+
* recording.start('./video.mov');
|
20
|
+
* recording.start('./video.webm');
|
21
|
+
* recording.start('./video.avi');
|
22
|
+
*/
|
23
|
+
var SupportedFileFormats;
|
24
|
+
(function (SupportedFileFormats) {
|
25
|
+
SupportedFileFormats["MP4"] = "mp4";
|
26
|
+
SupportedFileFormats["MOV"] = "mov";
|
27
|
+
SupportedFileFormats["AVI"] = "avi";
|
28
|
+
SupportedFileFormats["WEBM"] = "webm";
|
29
|
+
})(SupportedFileFormats || (exports.SupportedFileFormats = SupportedFileFormats = {}));
|
30
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFnZVZpZGVvU3RyZWFtVHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL3BhZ2VWaWRlb1N0cmVhbVR5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBOzs7R0FHRztBQUNILElBQVksa0JBS1g7QUFMRCxXQUFZLGtCQUFrQjtJQUM1Qix5RUFBYSxDQUFBO0lBQ2IseUVBQWEsQ0FBQTtJQUNiLHFFQUFXLENBQUE7SUFDWCw2REFBTyxDQUFBO0FBQ1QsQ0FBQyxFQUxXLGtCQUFrQixrQ0FBbEIsa0JBQWtCLFFBSzdCO0FBOElEOzs7Ozs7O0dBT0c7QUFDSCxJQUFZLG9CQUtYO0FBTEQsV0FBWSxvQkFBb0I7SUFDOUIsbUNBQVcsQ0FBQTtJQUNYLG1DQUFXLENBQUE7SUFDWCxtQ0FBVyxDQUFBO0lBQ1gscUNBQWEsQ0FBQTtBQUNmLENBQUMsRUFMVyxvQkFBb0Isb0NBQXBCLG9CQUFvQixRQUsvQiJ9
|
@@ -0,0 +1,40 @@
|
|
1
|
+
/// <reference types="node" />
|
2
|
+
/// <reference types="node" />
|
3
|
+
/// <reference types="node" />
|
4
|
+
import { EventEmitter } from 'events';
|
5
|
+
import { Writable } from 'stream';
|
6
|
+
import { pageScreenFrame, VideoOptions } from './pageVideoStreamTypes';
|
7
|
+
/**
|
8
|
+
* @ignore
|
9
|
+
*/
|
10
|
+
export default class PageVideoStreamWriter extends EventEmitter {
|
11
|
+
private readonly screenLimit;
|
12
|
+
private screenCastFrames;
|
13
|
+
duration: string;
|
14
|
+
frameGain: number;
|
15
|
+
frameLoss: number;
|
16
|
+
private status;
|
17
|
+
private options;
|
18
|
+
private videoMediatorStream;
|
19
|
+
private writerPromise;
|
20
|
+
constructor(destinationSource: string | Writable, options?: VideoOptions);
|
21
|
+
private get videoFrameSize();
|
22
|
+
private get autopad();
|
23
|
+
private getFfmpegPath;
|
24
|
+
private getDestinationPathExtension;
|
25
|
+
private configureFFmPegPath;
|
26
|
+
private isWritableStream;
|
27
|
+
private configureVideoFile;
|
28
|
+
private configureVideoWritableStream;
|
29
|
+
private getOutputOption;
|
30
|
+
private addVideoMetadata;
|
31
|
+
private getDestinationStream;
|
32
|
+
private handleWriteStreamError;
|
33
|
+
private findSlot;
|
34
|
+
insert(frame: pageScreenFrame): void;
|
35
|
+
private trimFrame;
|
36
|
+
private processFrameBeforeWrite;
|
37
|
+
write(data: Buffer, durationSeconds?: number): void;
|
38
|
+
private drainFrames;
|
39
|
+
stop(stoppedTime?: number): Promise<boolean>;
|
40
|
+
}
|