@vforsh/argus-watcher 0.5.2 → 0.5.4
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.
- package/dist/.tsbuildinfo +1 -1
- package/dist/cdp/ffmpeg.d.ts +22 -6
- package/dist/cdp/ffmpeg.d.ts.map +1 -1
- package/dist/cdp/ffmpeg.js +90 -30
- package/dist/cdp/ffmpeg.js.map +1 -1
- package/dist/cdp/recording.d.ts +3 -1
- package/dist/cdp/recording.d.ts.map +1 -1
- package/dist/cdp/recording.js +237 -132
- package/dist/cdp/recording.js.map +1 -1
- package/dist/cdp/recordingSession.d.ts +97 -0
- package/dist/cdp/recordingSession.d.ts.map +1 -0
- package/dist/cdp/recordingSession.js +157 -0
- package/dist/cdp/recordingSession.js.map +1 -0
- package/dist/cdp/scenarioBridge.d.ts +2 -0
- package/dist/cdp/scenarioBridge.d.ts.map +1 -1
- package/dist/cdp/scenarioBridge.js +49 -3
- package/dist/cdp/scenarioBridge.js.map +1 -1
- package/dist/cdp/screenshot.d.ts.map +1 -1
- package/dist/cdp/screenshot.js +3 -2
- package/dist/cdp/screenshot.js.map +1 -1
- package/dist/cdp/visualCapture.d.ts +20 -0
- package/dist/cdp/visualCapture.d.ts.map +1 -1
- package/dist/cdp/visualCapture.js +53 -42
- package/dist/cdp/visualCapture.js.map +1 -1
- package/dist/http/endpoints.d.ts +1 -1
- package/dist/http/endpoints.d.ts.map +1 -1
- package/dist/http/endpoints.js +1 -0
- package/dist/http/endpoints.js.map +1 -1
- package/dist/http/routes/getStatus.js +1 -0
- package/dist/http/routes/getStatus.js.map +1 -1
- package/dist/http/routes/postEval.d.ts.map +1 -1
- package/dist/http/routes/postEval.js +1 -0
- package/dist/http/routes/postEval.js.map +1 -1
- package/dist/http/routes/postRecord.d.ts.map +1 -1
- package/dist/http/routes/postRecord.js +9 -0
- package/dist/http/routes/postRecord.js.map +1 -1
- package/dist/internal.d.ts +1 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +1 -0
- package/dist/internal.js.map +1 -1
- package/dist/sourcemaps/scriptFetcher.d.ts +27 -0
- package/dist/sourcemaps/scriptFetcher.d.ts.map +1 -0
- package/dist/sourcemaps/scriptFetcher.js +69 -0
- package/dist/sourcemaps/scriptFetcher.js.map +1 -0
- package/dist/sourcemaps/sourcemapResolver.d.ts +4 -1
- package/dist/sourcemaps/sourcemapResolver.d.ts.map +1 -1
- package/dist/sourcemaps/sourcemapResolver.js +5 -14
- package/dist/sourcemaps/sourcemapResolver.js.map +1 -1
- package/package.json +1 -1
package/dist/cdp/recording.js
CHANGED
|
@@ -1,146 +1,273 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import crypto from 'node:crypto';
|
|
3
3
|
import fs from 'node:fs/promises';
|
|
4
|
+
import { RECORD_DEFAULT_MAX_DURATION_MS, RECORD_DEFAULT_POLL_INTERVAL_MS, RECORD_GIF_DEFAULT_FPS, RECORD_GIF_MAX_FPS } from '@vforsh/argus-core';
|
|
4
5
|
import { ensureArtifactsDir, ensureParentDir, moveArtifactFile, resolveArtifactPath } from '../artifacts.js';
|
|
5
6
|
import { createDeferred } from '../deferred.js';
|
|
6
|
-
import { formatFfmpegError,
|
|
7
|
+
import { formatFfmpegError, readFrameInfo, startFfmpeg } from './ffmpeg.js';
|
|
7
8
|
import { createVisualCapturePlan } from './visualCapture.js';
|
|
8
|
-
import {
|
|
9
|
+
import { evaluateInPage } from './pageState.js';
|
|
10
|
+
import { armScreencast, assertClipIsVisible, clearRecordingTimers, flushFrames, pumpFrames, scrollSelectorIntoView, subscribeToScreencast, } from './recordingSession.js';
|
|
9
11
|
const DEFAULT_RECORD_FPS = 30;
|
|
10
|
-
const
|
|
12
|
+
const DEFAULT_FRAME_QUALITY = 90;
|
|
13
|
+
/**
|
|
14
|
+
* How long to wait for Chrome's first screencast frame.
|
|
15
|
+
*
|
|
16
|
+
* Generous because the recorder now brings the page to the front first: the common cause of a
|
|
17
|
+
* missing first frame is a backgrounded tab, and once that is handled the remaining causes
|
|
18
|
+
* (a heavy first paint, a canvas warming up) deserve more than a couple of seconds.
|
|
19
|
+
*/
|
|
20
|
+
const FIRST_FRAME_TIMEOUT_MS = 5_000;
|
|
21
|
+
/** Deadline for the encoder to finish after its input closes, so a wedged ffmpeg cannot hang a stop. */
|
|
22
|
+
const ENCODER_DRAIN_TIMEOUT_MS = 30_000;
|
|
11
23
|
export const createRecorder = (options) => {
|
|
12
24
|
let active = null;
|
|
13
|
-
const capture = async (request) => {
|
|
14
|
-
await start(request);
|
|
15
|
-
await delay(request.durationMs);
|
|
16
|
-
return stop({});
|
|
17
|
-
};
|
|
18
25
|
const start = async (request) => {
|
|
19
|
-
if (active) {
|
|
26
|
+
if (active && active.state !== 'stopped') {
|
|
20
27
|
throw new Error('Recording already active');
|
|
21
28
|
}
|
|
22
29
|
await ensureArtifactsDir(options.artifactsDir);
|
|
23
30
|
const format = resolveRecordFormat(request);
|
|
24
|
-
const fps = normalizeFps(request.fps);
|
|
25
|
-
const recordId = crypto.randomUUID();
|
|
31
|
+
const fps = normalizeFps(request.fps, format);
|
|
26
32
|
const sessionName = `record-${new Date().toISOString().replace(/[:.]/g, '-')}`;
|
|
27
|
-
const
|
|
28
|
-
const absolutePath = resolveArtifactPath(options.artifactsDir, request.outFile, defaultName);
|
|
33
|
+
const absolutePath = resolveArtifactPath(options.artifactsDir, request.outFile, `recordings/${sessionName}.${format}`);
|
|
29
34
|
validateOutputPathFormat(absolutePath, format);
|
|
30
35
|
await ensureParentDir(absolutePath);
|
|
36
|
+
if (request.selector) {
|
|
37
|
+
await scrollSelectorIntoView(options.session, request.selector);
|
|
38
|
+
}
|
|
31
39
|
const capturePlan = await createVisualCapturePlan(options.session, options.pageSession, request);
|
|
40
|
+
if (capturePlan.clip) {
|
|
41
|
+
assertClipIsVisible(capturePlan.clip, capturePlan.viewport, request.selector ? `Selector "${request.selector}"` : 'The requested clip');
|
|
42
|
+
}
|
|
32
43
|
const firstFrameDeferred = createDeferred();
|
|
33
44
|
const state = {
|
|
34
|
-
recordId,
|
|
45
|
+
recordId: crypto.randomUUID(),
|
|
35
46
|
sessionName,
|
|
36
47
|
absolutePath: path.resolve(absolutePath),
|
|
37
48
|
outFile: absolutePath,
|
|
38
49
|
session: capturePlan.session,
|
|
50
|
+
evalSession: options.session,
|
|
39
51
|
removeFrameHandler: () => { },
|
|
52
|
+
removeNavigationHandler: () => { },
|
|
40
53
|
ffmpeg: null,
|
|
54
|
+
frameCodec: resolveFrameCodec(request),
|
|
55
|
+
quality: normalizeQuality(request.quality),
|
|
41
56
|
firstFrame: firstFrameDeferred.promise,
|
|
42
57
|
resolveFirstFrame: firstFrameDeferred.resolve,
|
|
43
58
|
rejectFirstFrame: firstFrameDeferred.reject,
|
|
44
|
-
firstFrameTimer:
|
|
45
|
-
firstFrameDeferred.reject(new Error('No screencast frames received. Make the page visible with `argus page show <id>` and try again.'));
|
|
46
|
-
}, FIRST_FRAME_TIMEOUT_MS),
|
|
59
|
+
firstFrameTimer: null,
|
|
47
60
|
sampleTimer: null,
|
|
61
|
+
maxDurationTimer: null,
|
|
62
|
+
endTimer: null,
|
|
63
|
+
untilTimer: null,
|
|
48
64
|
latestFrame: null,
|
|
49
|
-
pendingFrameCount: 0,
|
|
50
65
|
pumpBlocked: false,
|
|
51
66
|
frameCount: 0,
|
|
52
67
|
startedAt: Date.now(),
|
|
53
68
|
capturedDurationMs: null,
|
|
54
69
|
fps,
|
|
55
70
|
format,
|
|
71
|
+
maxDurationMs: normalizeMaxDuration(request.maxDurationMs),
|
|
56
72
|
clip: capturePlan.clip,
|
|
57
73
|
viewport: capturePlan.viewport,
|
|
74
|
+
navigations: 0,
|
|
75
|
+
stopReason: 'requested',
|
|
76
|
+
partial: false,
|
|
77
|
+
encodeError: null,
|
|
78
|
+
finalizePromise: null,
|
|
79
|
+
finished: createDeferred(),
|
|
80
|
+
sizeBytes: 0,
|
|
58
81
|
state: 'starting',
|
|
59
82
|
};
|
|
60
83
|
active = state;
|
|
61
84
|
try {
|
|
62
|
-
|
|
63
|
-
handleScreencastFrame(state, params);
|
|
64
|
-
});
|
|
65
|
-
await state.session.sendAndWait('Page.startScreencast', { format: 'png', everyNthFrame: 1 });
|
|
66
|
-
const firstFrame = await state.firstFrame;
|
|
67
|
-
clearTimeout(state.firstFrameTimer);
|
|
68
|
-
const frameSize = readPngSize(firstFrame);
|
|
69
|
-
state.ffmpeg = await startFfmpeg({
|
|
70
|
-
absolutePath: state.absolutePath,
|
|
71
|
-
fps,
|
|
72
|
-
format,
|
|
73
|
-
clip: state.clip,
|
|
74
|
-
viewport: state.viewport,
|
|
75
|
-
frameSize,
|
|
76
|
-
});
|
|
77
|
-
state.state = 'recording';
|
|
78
|
-
state.startedAt = Date.now();
|
|
79
|
-
queueFrameSample(state);
|
|
80
|
-
state.sampleTimer = setInterval(() => queueFrameSample(state), Math.round(1000 / fps));
|
|
85
|
+
await beginCapture(state);
|
|
81
86
|
options.onRecordingStateChange?.(true);
|
|
82
87
|
return {
|
|
83
88
|
ok: true,
|
|
84
|
-
recordId,
|
|
89
|
+
recordId: state.recordId,
|
|
85
90
|
sessionName,
|
|
86
91
|
outFile: absolutePath,
|
|
87
92
|
format,
|
|
88
93
|
fps,
|
|
89
94
|
clipped: Boolean(state.clip),
|
|
95
|
+
maxDurationMs: state.maxDurationMs,
|
|
90
96
|
};
|
|
91
97
|
}
|
|
92
98
|
catch (error) {
|
|
93
99
|
active = null;
|
|
94
|
-
await cleanupFailedStart(state
|
|
95
|
-
throw error;
|
|
100
|
+
await cleanupFailedStart(state);
|
|
101
|
+
throw normalizeStartError(error);
|
|
96
102
|
}
|
|
97
103
|
};
|
|
98
|
-
|
|
104
|
+
/** Bring the page forward, arm the screencast, size the encoder from the first real frame. */
|
|
105
|
+
const beginCapture = async (state) => {
|
|
106
|
+
subscribeToScreencast(state);
|
|
107
|
+
state.firstFrameTimer = setTimeout(() => {
|
|
108
|
+
state.rejectFirstFrame(new Error('No screencast frames received. Make the page visible with `argus page show <id>` and try again.'));
|
|
109
|
+
}, FIRST_FRAME_TIMEOUT_MS);
|
|
110
|
+
// A backgrounded tab never paints, which is the single most common cause of an empty capture.
|
|
111
|
+
await state.session.sendAndWait('Page.bringToFront', undefined, { timeoutMs: 2_000 }).catch(() => { });
|
|
112
|
+
await armScreencast(state);
|
|
113
|
+
const firstFrame = await state.firstFrame;
|
|
114
|
+
clearTimeout(state.firstFrameTimer);
|
|
115
|
+
state.firstFrameTimer = null;
|
|
116
|
+
state.ffmpeg = await startFfmpeg({
|
|
117
|
+
absolutePath: state.absolutePath,
|
|
118
|
+
fps: state.fps,
|
|
119
|
+
format: state.format,
|
|
120
|
+
clip: state.clip,
|
|
121
|
+
viewport: state.viewport,
|
|
122
|
+
frame: readFrameInfo(firstFrame),
|
|
123
|
+
});
|
|
124
|
+
state.state = 'recording';
|
|
125
|
+
state.startedAt = Date.now();
|
|
126
|
+
pumpFrames(state);
|
|
127
|
+
state.sampleTimer = setInterval(() => pumpFrames(state), Math.max(1, Math.round(1000 / state.fps)));
|
|
128
|
+
state.maxDurationTimer = setTimeout(() => {
|
|
129
|
+
void finalize(state, 'max-duration');
|
|
130
|
+
}, state.maxDurationMs);
|
|
131
|
+
};
|
|
132
|
+
const capture = async (request) => {
|
|
133
|
+
await start(request);
|
|
99
134
|
const state = active;
|
|
100
135
|
if (!state) {
|
|
101
|
-
throw new Error('
|
|
102
|
-
}
|
|
103
|
-
if (request.recordId && request.recordId !== state.recordId) {
|
|
104
|
-
throw new Error('Record id does not match active recording');
|
|
136
|
+
throw new Error('Recording ended before it began');
|
|
105
137
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
138
|
+
scheduleCaptureEnd(state, request);
|
|
139
|
+
await state.finished.promise;
|
|
140
|
+
return stop({});
|
|
141
|
+
};
|
|
142
|
+
/** Arm whichever end condition this capture asked for: a fixed window or a page predicate. */
|
|
143
|
+
const scheduleCaptureEnd = (state, request) => {
|
|
144
|
+
const { until } = request;
|
|
145
|
+
if (until != null) {
|
|
146
|
+
const intervalMs = Math.max(10, request.pollIntervalMs ?? RECORD_DEFAULT_POLL_INTERVAL_MS);
|
|
147
|
+
state.untilTimer = setInterval(createUntilPoller(state, until), intervalMs);
|
|
148
|
+
return;
|
|
110
149
|
}
|
|
150
|
+
state.endTimer = setTimeout(() => {
|
|
151
|
+
void finalize(state, 'duration');
|
|
152
|
+
}, request.durationMs ?? state.maxDurationMs);
|
|
153
|
+
};
|
|
154
|
+
/**
|
|
155
|
+
* Poll a page predicate, skipping ticks while a previous evaluation is still running.
|
|
156
|
+
*
|
|
157
|
+
* The in-flight guard is per poller rather than per recorder so a slow evaluation left over
|
|
158
|
+
* from one recording cannot suppress the first ticks of the next.
|
|
159
|
+
*/
|
|
160
|
+
const createUntilPoller = (state, expression) => {
|
|
161
|
+
let inFlight = false;
|
|
162
|
+
return () => {
|
|
163
|
+
if (inFlight || state.state !== 'recording') {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
inFlight = true;
|
|
167
|
+
void evaluateInPage(state.evalSession, `(${expression})`, { awaitPromise: true, timeoutMs: 5_000 })
|
|
168
|
+
.then((value) => {
|
|
169
|
+
if (value) {
|
|
170
|
+
return finalize(state, 'until');
|
|
171
|
+
}
|
|
172
|
+
})
|
|
173
|
+
.catch(() => {
|
|
174
|
+
// A navigating or busy page throws; the condition is simply not met yet.
|
|
175
|
+
})
|
|
176
|
+
.finally(() => {
|
|
177
|
+
inFlight = false;
|
|
178
|
+
});
|
|
179
|
+
};
|
|
180
|
+
};
|
|
181
|
+
/**
|
|
182
|
+
* Shut the capture down exactly once, and make every caller wait for that one shutdown.
|
|
183
|
+
*
|
|
184
|
+
* Three independent things race to end a recording: the caller's `stop`, the duration/`until`
|
|
185
|
+
* timer, and CDP detaching underneath both. Returning early for the losers is not enough —
|
|
186
|
+
* `stop` would then move the output file while ffmpeg was still writing it — so they all await
|
|
187
|
+
* the same promise.
|
|
188
|
+
*/
|
|
189
|
+
const finalize = (state, reason) => {
|
|
190
|
+
state.finalizePromise ??= runFinalize(state, reason);
|
|
191
|
+
return state.finalizePromise;
|
|
192
|
+
};
|
|
193
|
+
const runFinalize = async (state, reason) => {
|
|
111
194
|
state.state = 'stopping';
|
|
195
|
+
state.stopReason = reason;
|
|
196
|
+
// Only losing the page truncates a recording; every other reason is a bound being reached.
|
|
197
|
+
state.partial = reason === 'detached';
|
|
198
|
+
state.capturedDurationMs = Math.max(0, Date.now() - state.startedAt);
|
|
112
199
|
clearRecordingTimers(state);
|
|
113
200
|
state.removeFrameHandler();
|
|
114
|
-
state.
|
|
201
|
+
state.removeNavigationHandler();
|
|
115
202
|
try {
|
|
116
|
-
await state.session.sendAndWait('Page.stopScreencast',
|
|
117
|
-
|
|
118
|
-
await flushQueuedFrames(state);
|
|
203
|
+
await state.session.sendAndWait('Page.stopScreencast', undefined, { timeoutMs: 5_000 }).catch(() => { });
|
|
204
|
+
await flushFrames(state, state.capturedDurationMs);
|
|
119
205
|
state.ffmpeg?.child.stdin.end();
|
|
120
|
-
await state.ffmpeg?.completion;
|
|
121
|
-
|
|
122
|
-
|
|
206
|
+
await withTimeout(state.ffmpeg?.completion, ENCODER_DRAIN_TIMEOUT_MS);
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
// A failed encode still leaves whatever ffmpeg wrote; report it as partial rather than
|
|
210
|
+
// throwing away a repro clip the caller may already have watched being made.
|
|
211
|
+
state.partial = true;
|
|
212
|
+
state.encodeError = error;
|
|
123
213
|
}
|
|
124
214
|
finally {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
}
|
|
215
|
+
state.state = 'stopped';
|
|
216
|
+
state.sizeBytes = await fileSize(state.absolutePath);
|
|
128
217
|
options.onRecordingStateChange?.(false);
|
|
218
|
+
state.finished.resolve();
|
|
129
219
|
}
|
|
130
220
|
};
|
|
131
|
-
const
|
|
221
|
+
const stop = async (request) => {
|
|
132
222
|
const state = active;
|
|
133
223
|
if (!state) {
|
|
134
|
-
|
|
224
|
+
throw new Error('No active recording to stop');
|
|
135
225
|
}
|
|
226
|
+
if (request.recordId && request.recordId !== state.recordId) {
|
|
227
|
+
throw new Error('Record id does not match active recording');
|
|
228
|
+
}
|
|
229
|
+
await finalize(state, 'requested');
|
|
136
230
|
active = null;
|
|
137
|
-
|
|
138
|
-
|
|
231
|
+
if (state.encodeError && state.sizeBytes === 0) {
|
|
232
|
+
throw state.encodeError;
|
|
233
|
+
}
|
|
234
|
+
await resolveFinalPath(state, request.outFile);
|
|
235
|
+
return buildStopResponse(state);
|
|
236
|
+
};
|
|
237
|
+
const status = () => {
|
|
238
|
+
const state = active;
|
|
239
|
+
if (!state || state.state === 'stopped') {
|
|
240
|
+
return null;
|
|
241
|
+
}
|
|
242
|
+
return {
|
|
243
|
+
recordId: state.recordId,
|
|
244
|
+
sessionName: state.sessionName,
|
|
245
|
+
outFile: state.outFile,
|
|
246
|
+
format: state.format,
|
|
247
|
+
fps: state.fps,
|
|
248
|
+
clipped: Boolean(state.clip),
|
|
249
|
+
startedAt: state.startedAt,
|
|
250
|
+
elapsedMs: Math.max(0, Date.now() - state.startedAt),
|
|
251
|
+
frameCount: state.frameCount,
|
|
252
|
+
maxDurationMs: state.maxDurationMs,
|
|
253
|
+
navigations: state.navigations,
|
|
254
|
+
};
|
|
255
|
+
};
|
|
256
|
+
/**
|
|
257
|
+
* Close the encoder cleanly when the page goes away, instead of killing it.
|
|
258
|
+
*
|
|
259
|
+
* SIGTERM on an mp4 encode loses the moov atom, so every detached recording used to produce an
|
|
260
|
+
* unplayable file. Finalizing keeps the frames captured up to the detach and marks them partial.
|
|
261
|
+
*/
|
|
262
|
+
const onDetached = (reason) => {
|
|
263
|
+
const state = active;
|
|
264
|
+
if (!state || state.state === 'stopped') {
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
139
267
|
state.rejectFirstFrame(new Error(reason ?? 'CDP detached while recording'));
|
|
140
|
-
state
|
|
141
|
-
options.onRecordingStateChange?.(false);
|
|
268
|
+
void finalize(state, 'detached');
|
|
142
269
|
};
|
|
143
|
-
return { capture, start, stop, onDetached };
|
|
270
|
+
return { capture, start, stop, status, onDetached };
|
|
144
271
|
async function resolveFinalPath(state, outFile) {
|
|
145
272
|
if (!outFile?.trim()) {
|
|
146
273
|
return;
|
|
@@ -155,68 +282,38 @@ export const createRecorder = (options) => {
|
|
|
155
282
|
state.outFile = absolutePath;
|
|
156
283
|
}
|
|
157
284
|
};
|
|
158
|
-
const
|
|
159
|
-
|
|
160
|
-
if (typeof payload.data !== 'string') {
|
|
285
|
+
const withTimeout = async (promise, timeoutMs) => {
|
|
286
|
+
if (!promise) {
|
|
161
287
|
return;
|
|
162
288
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
if (!state.latestFrame || state.state !== 'recording') {
|
|
172
|
-
return;
|
|
173
|
-
}
|
|
174
|
-
state.pendingFrameCount += 1;
|
|
175
|
-
pumpQueuedFrames(state);
|
|
176
|
-
};
|
|
177
|
-
const queueMissingDurationFrames = (state) => {
|
|
178
|
-
if (!state.latestFrame) {
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
181
|
-
const elapsedMs = state.capturedDurationMs ?? Math.max(0, Date.now() - state.startedAt);
|
|
182
|
-
const targetFrameCount = Math.max(1, Math.round((elapsedMs / 1000) * state.fps));
|
|
183
|
-
const queuedOrWritten = state.frameCount + state.pendingFrameCount;
|
|
184
|
-
if (queuedOrWritten < targetFrameCount) {
|
|
185
|
-
state.pendingFrameCount += targetFrameCount - queuedOrWritten;
|
|
289
|
+
let timer;
|
|
290
|
+
try {
|
|
291
|
+
await Promise.race([
|
|
292
|
+
promise,
|
|
293
|
+
new Promise((_resolve, reject) => {
|
|
294
|
+
timer = setTimeout(() => reject(new Error(`ffmpeg did not finish within ${timeoutMs}ms`)), timeoutMs);
|
|
295
|
+
}),
|
|
296
|
+
]);
|
|
186
297
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
while (state.pendingFrameCount > 0 || state.pumpBlocked) {
|
|
191
|
-
if (!state.ffmpeg || state.ffmpeg.child.stdin.destroyed) {
|
|
192
|
-
return;
|
|
298
|
+
finally {
|
|
299
|
+
if (timer) {
|
|
300
|
+
clearTimeout(timer);
|
|
193
301
|
}
|
|
194
|
-
await delay(10);
|
|
195
|
-
pumpQueuedFrames(state);
|
|
196
302
|
}
|
|
197
303
|
};
|
|
198
|
-
const
|
|
199
|
-
|
|
200
|
-
return;
|
|
304
|
+
const fileSize = async (absolutePath) => {
|
|
305
|
+
try {
|
|
306
|
+
return (await fs.stat(absolutePath)).size;
|
|
201
307
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
state.frameCount += 1;
|
|
205
|
-
const ready = state.ffmpeg.child.stdin.write(state.latestFrame);
|
|
206
|
-
if (!ready) {
|
|
207
|
-
state.pumpBlocked = true;
|
|
208
|
-
state.ffmpeg.child.stdin.once('drain', () => {
|
|
209
|
-
state.pumpBlocked = false;
|
|
210
|
-
pumpQueuedFrames(state);
|
|
211
|
-
});
|
|
212
|
-
return;
|
|
213
|
-
}
|
|
308
|
+
catch {
|
|
309
|
+
return 0;
|
|
214
310
|
}
|
|
215
311
|
};
|
|
216
|
-
const cleanupFailedStart = async (state
|
|
312
|
+
const cleanupFailedStart = async (state) => {
|
|
217
313
|
clearRecordingTimers(state);
|
|
218
314
|
state.removeFrameHandler();
|
|
219
|
-
|
|
315
|
+
state.removeNavigationHandler();
|
|
316
|
+
await state.session.sendAndWait('Page.stopScreencast', undefined, { timeoutMs: 5_000 }).catch(() => { });
|
|
220
317
|
state.ffmpeg?.child.kill('SIGTERM');
|
|
221
318
|
state.ffmpeg?.child.stdin.destroy();
|
|
222
319
|
try {
|
|
@@ -225,17 +322,8 @@ const cleanupFailedStart = async (state, error) => {
|
|
|
225
322
|
catch {
|
|
226
323
|
// Best effort: the encoder may not have created the file yet.
|
|
227
324
|
}
|
|
228
|
-
if (error instanceof Error && error.message.startsWith('spawn ffmpeg ENOENT')) {
|
|
229
|
-
throw formatFfmpegError(error);
|
|
230
|
-
}
|
|
231
|
-
};
|
|
232
|
-
const clearRecordingTimers = (state) => {
|
|
233
|
-
clearTimeout(state.firstFrameTimer);
|
|
234
|
-
if (state.sampleTimer) {
|
|
235
|
-
clearInterval(state.sampleTimer);
|
|
236
|
-
state.sampleTimer = null;
|
|
237
|
-
}
|
|
238
325
|
};
|
|
326
|
+
const normalizeStartError = (error) => error instanceof Error && error.message.startsWith('spawn ffmpeg ENOENT') ? formatFfmpegError(error) : error;
|
|
239
327
|
const buildStopResponse = (state) => ({
|
|
240
328
|
ok: true,
|
|
241
329
|
recordId: state.recordId,
|
|
@@ -246,13 +334,28 @@ const buildStopResponse = (state) => ({
|
|
|
246
334
|
durationMs: state.capturedDurationMs ?? Math.max(0, Date.now() - state.startedAt),
|
|
247
335
|
fps: state.fps,
|
|
248
336
|
clipped: Boolean(state.clip),
|
|
337
|
+
stopReason: state.stopReason,
|
|
338
|
+
partial: state.partial,
|
|
339
|
+
navigations: state.navigations,
|
|
340
|
+
sizeBytes: state.sizeBytes,
|
|
249
341
|
});
|
|
250
|
-
const normalizeFps = (fps) => {
|
|
342
|
+
const normalizeFps = (fps, format) => {
|
|
251
343
|
if (fps == null) {
|
|
252
|
-
return DEFAULT_RECORD_FPS;
|
|
344
|
+
return format === 'gif' ? RECORD_GIF_DEFAULT_FPS : DEFAULT_RECORD_FPS;
|
|
253
345
|
}
|
|
254
|
-
|
|
346
|
+
const rounded = Math.min(60, Math.max(1, Math.round(fps)));
|
|
347
|
+
return format === 'gif' ? Math.min(RECORD_GIF_MAX_FPS, rounded) : rounded;
|
|
255
348
|
};
|
|
349
|
+
const normalizeQuality = (quality) => quality == null ? DEFAULT_FRAME_QUALITY : Math.min(100, Math.max(1, Math.round(quality)));
|
|
350
|
+
const normalizeMaxDuration = (maxDurationMs) => maxDurationMs == null || !Number.isFinite(maxDurationMs) || maxDurationMs <= 0 ? RECORD_DEFAULT_MAX_DURATION_MS : maxDurationMs;
|
|
351
|
+
/**
|
|
352
|
+
* JPEG frames unless the caller explicitly wants lossless.
|
|
353
|
+
*
|
|
354
|
+
* PNG screencast frames cost several times more to encode and serialize in the renderer than JPEG,
|
|
355
|
+
* and the output is re-encoded lossily anyway. GIF is the exception: its palette quantization
|
|
356
|
+
* amplifies JPEG ringing on flat UI, so it keeps PNG frames.
|
|
357
|
+
*/
|
|
358
|
+
const resolveFrameCodec = (request) => resolveRecordFormat(request) === 'gif' && request.quality == null ? 'png' : 'jpeg';
|
|
256
359
|
const resolveRecordFormat = (request) => request.format ?? inferRecordFormatFromPath(request.outFile) ?? 'mp4';
|
|
257
360
|
const inferRecordFormatFromPath = (outFile) => {
|
|
258
361
|
const ext = path.extname(outFile?.trim() ?? '').toLowerCase();
|
|
@@ -260,12 +363,14 @@ const inferRecordFormatFromPath = (outFile) => {
|
|
|
260
363
|
return 'mp4';
|
|
261
364
|
if (ext === '.webm')
|
|
262
365
|
return 'webm';
|
|
366
|
+
if (ext === '.gif')
|
|
367
|
+
return 'gif';
|
|
263
368
|
return undefined;
|
|
264
369
|
};
|
|
265
370
|
const validateOutputPathFormat = (outFile, format) => {
|
|
266
371
|
const ext = path.extname(outFile.trim()).toLowerCase();
|
|
267
|
-
if (ext && ext !== '.mp4' && ext !== '.webm') {
|
|
268
|
-
throw new Error('Recording output must use .mp4 or .
|
|
372
|
+
if (ext && ext !== '.mp4' && ext !== '.webm' && ext !== '.gif') {
|
|
373
|
+
throw new Error('Recording output must use .mp4, .webm, or .gif when an extension is provided');
|
|
269
374
|
}
|
|
270
375
|
const inferred = inferRecordFormatFromPath(outFile);
|
|
271
376
|
if (inferred && inferred !== format) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recording.js","sourceRoot":"","sources":["../../src/cdp/recording.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"recording.js","sourceRoot":"","sources":["../../src/cdp/recording.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import type { RecordFormat, RecordStopReason } from '@vforsh/argus-core';
|
|
2
|
+
import type { CdpSessionHandle } from './connection.js';
|
|
3
|
+
import type { Deferred } from '../deferred.js';
|
|
4
|
+
import type { FfmpegProcess, FrameCodec } from './ffmpeg.js';
|
|
5
|
+
import type { VisualCaptureClip, VisualCaptureViewport } from './visualCapture.js';
|
|
6
|
+
/**
|
|
7
|
+
* Screencast frame plumbing for {@link createRecorder}: the live recording's state, the wall-clock
|
|
8
|
+
* frame pump that feeds ffmpeg, and the screencast (re-)arming that survives navigation.
|
|
9
|
+
*
|
|
10
|
+
* Separate from `recording.ts` because the lifecycle (start/stop/finalize/status) and the pacing
|
|
11
|
+
* are independently tricky and neither wants to be read through the other.
|
|
12
|
+
*/
|
|
13
|
+
/** Everything one in-flight recording needs. Mutable by design — the pump runs on timers. */
|
|
14
|
+
export type RecordingState = {
|
|
15
|
+
recordId: string;
|
|
16
|
+
sessionName: string;
|
|
17
|
+
absolutePath: string;
|
|
18
|
+
outFile: string;
|
|
19
|
+
/** Page-scoped session that produces pixels. For an iframe target this is the top-level page. */
|
|
20
|
+
session: CdpSessionHandle;
|
|
21
|
+
/** Selected target, where an `until` expression is evaluated. Same session for page targets. */
|
|
22
|
+
evalSession: CdpSessionHandle;
|
|
23
|
+
removeFrameHandler: () => void;
|
|
24
|
+
removeNavigationHandler: () => void;
|
|
25
|
+
ffmpeg: FfmpegProcess | null;
|
|
26
|
+
frameCodec: FrameCodec;
|
|
27
|
+
quality: number;
|
|
28
|
+
firstFrame: Promise<Buffer>;
|
|
29
|
+
resolveFirstFrame: (frame: Buffer) => void;
|
|
30
|
+
rejectFirstFrame: (error: Error) => void;
|
|
31
|
+
firstFrameTimer: NodeJS.Timeout | null;
|
|
32
|
+
sampleTimer: NodeJS.Timeout | null;
|
|
33
|
+
/** Backstop that stops an open-ended recording. Always armed. */
|
|
34
|
+
maxDurationTimer: NodeJS.Timeout | null;
|
|
35
|
+
/** The requested end condition for a fixed-duration capture. */
|
|
36
|
+
endTimer: NodeJS.Timeout | null;
|
|
37
|
+
untilTimer: NodeJS.Timeout | null;
|
|
38
|
+
latestFrame: Buffer | null;
|
|
39
|
+
pumpBlocked: boolean;
|
|
40
|
+
/** Frames handed to the encoder so far. */
|
|
41
|
+
frameCount: number;
|
|
42
|
+
startedAt: number;
|
|
43
|
+
capturedDurationMs: number | null;
|
|
44
|
+
fps: number;
|
|
45
|
+
format: RecordFormat;
|
|
46
|
+
maxDurationMs: number;
|
|
47
|
+
clip: VisualCaptureClip | undefined;
|
|
48
|
+
viewport: VisualCaptureViewport | undefined;
|
|
49
|
+
navigations: number;
|
|
50
|
+
stopReason: RecordStopReason;
|
|
51
|
+
partial: boolean;
|
|
52
|
+
/** Encoder failure kept for the stop response; a partial file still beats an exception. */
|
|
53
|
+
encodeError: unknown;
|
|
54
|
+
/** In-flight shutdown, so every racing caller awaits the same encode instead of racing it. */
|
|
55
|
+
finalizePromise: Promise<void> | null;
|
|
56
|
+
/** Settled once the encoder has finished, whichever end condition got there first. */
|
|
57
|
+
finished: Deferred<void>;
|
|
58
|
+
sizeBytes: number;
|
|
59
|
+
state: 'starting' | 'recording' | 'stopping' | 'stopped';
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Scroll a selector target into view before the capture plan measures it.
|
|
63
|
+
*
|
|
64
|
+
* A screencast only ever carries the visible viewport, so an element below the fold has no pixels
|
|
65
|
+
* to crop. `Page.captureScreenshot` has no such limit, which is why `screenshot --selector` works
|
|
66
|
+
* on an off-screen element and `record --selector` cannot — it used to silently emit a 2px sliver.
|
|
67
|
+
*
|
|
68
|
+
* Best-effort: a selector that matches nothing is reported by the capture plan, which produces a
|
|
69
|
+
* better message than anything this could throw.
|
|
70
|
+
*/
|
|
71
|
+
export declare const scrollSelectorIntoView: (session: CdpSessionHandle, selector: string) => Promise<void>;
|
|
72
|
+
/**
|
|
73
|
+
* Reject a crop the screencast cannot actually deliver.
|
|
74
|
+
*
|
|
75
|
+
* The encoder clamps an out-of-frame rectangle to the nearest legal one, so an off-screen target
|
|
76
|
+
* used to encode cleanly as a 2-pixel sliver and only look wrong when someone played the file.
|
|
77
|
+
*
|
|
78
|
+
* @throws {Error} When the crop lies (almost) entirely outside the captured viewport.
|
|
79
|
+
*/
|
|
80
|
+
export declare const assertClipIsVisible: (clip: VisualCaptureClip, viewport: VisualCaptureViewport | undefined, subject: string) => void;
|
|
81
|
+
/**
|
|
82
|
+
* Start (or restart) Chrome's screencast for this recording.
|
|
83
|
+
*
|
|
84
|
+
* Called once at start and again after every top-frame navigation: Chrome tears the screencast
|
|
85
|
+
* down on a cross-process navigation and never says so, which used to leave the encoder repeating
|
|
86
|
+
* the last pre-navigation frame for the rest of the capture.
|
|
87
|
+
*/
|
|
88
|
+
export declare const armScreencast: (state: RecordingState) => Promise<void>;
|
|
89
|
+
/** Subscribe to screencast frames and top-frame navigations for the lifetime of the recording. */
|
|
90
|
+
export declare const subscribeToScreencast: (state: RecordingState) => void;
|
|
91
|
+
/** Bring the encoder up to date with how long the recording has been running. */
|
|
92
|
+
export declare const pumpFrames: (state: RecordingState) => void;
|
|
93
|
+
/** Write the frames the final capture window still owes, then wait for the encoder to drain them. */
|
|
94
|
+
export declare const flushFrames: (state: RecordingState, elapsedMs: number) => Promise<void>;
|
|
95
|
+
/** Clear every timer the recording owns. Safe to call more than once. */
|
|
96
|
+
export declare const clearRecordingTimers: (state: RecordingState) => void;
|
|
97
|
+
//# sourceMappingURL=recordingSession.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recordingSession.d.ts","sourceRoot":"","sources":["../../src/cdp/recordingSession.ts"],"names":[],"mappings":"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"}
|