@hyperframes/engine 0.1.2 → 0.1.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.
Files changed (82) hide show
  1. package/LICENSE +21 -0
  2. package/dist/config.d.ts +62 -0
  3. package/dist/config.d.ts.map +1 -0
  4. package/dist/config.js +92 -0
  5. package/dist/config.js.map +1 -0
  6. package/dist/index.d.ts +49 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +55 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/services/audioMixer.d.ts +11 -0
  11. package/dist/services/audioMixer.d.ts.map +1 -0
  12. package/dist/services/audioMixer.js +327 -0
  13. package/dist/services/audioMixer.js.map +1 -0
  14. package/dist/services/audioMixer.types.d.ts +27 -0
  15. package/dist/services/audioMixer.types.d.ts.map +1 -0
  16. package/dist/services/audioMixer.types.js +2 -0
  17. package/dist/services/audioMixer.types.js.map +1 -0
  18. package/dist/services/browserManager.d.ts +29 -0
  19. package/dist/services/browserManager.d.ts.map +1 -0
  20. package/dist/services/browserManager.js +175 -0
  21. package/dist/services/browserManager.js.map +1 -0
  22. package/dist/services/chunkEncoder.d.ts +32 -0
  23. package/dist/services/chunkEncoder.d.ts.map +1 -0
  24. package/dist/services/chunkEncoder.js +368 -0
  25. package/dist/services/chunkEncoder.js.map +1 -0
  26. package/dist/services/chunkEncoder.types.d.ts +26 -0
  27. package/dist/services/chunkEncoder.types.d.ts.map +1 -0
  28. package/dist/services/chunkEncoder.types.js +2 -0
  29. package/dist/services/chunkEncoder.types.js.map +1 -0
  30. package/dist/services/fileServer.d.ts +25 -0
  31. package/dist/services/fileServer.d.ts.map +1 -0
  32. package/dist/services/fileServer.js +138 -0
  33. package/dist/services/fileServer.js.map +1 -0
  34. package/dist/services/frameCapture.d.ts +52 -0
  35. package/dist/services/frameCapture.d.ts.map +1 -0
  36. package/dist/services/frameCapture.js +317 -0
  37. package/dist/services/frameCapture.js.map +1 -0
  38. package/dist/services/parallelCoordinator.d.ts +40 -0
  39. package/dist/services/parallelCoordinator.d.ts.map +1 -0
  40. package/dist/services/parallelCoordinator.js +192 -0
  41. package/dist/services/parallelCoordinator.js.map +1 -0
  42. package/dist/services/screenshotService.d.ts +28 -0
  43. package/dist/services/screenshotService.d.ts.map +1 -0
  44. package/dist/services/screenshotService.js +190 -0
  45. package/dist/services/screenshotService.js.map +1 -0
  46. package/dist/services/streamingEncoder.d.ts +49 -0
  47. package/dist/services/streamingEncoder.d.ts.map +1 -0
  48. package/dist/services/streamingEncoder.js +227 -0
  49. package/dist/services/streamingEncoder.js.map +1 -0
  50. package/dist/services/videoFrameExtractor.d.ts +65 -0
  51. package/dist/services/videoFrameExtractor.d.ts.map +1 -0
  52. package/dist/services/videoFrameExtractor.js +308 -0
  53. package/dist/services/videoFrameExtractor.js.map +1 -0
  54. package/dist/services/videoFrameInjector.d.ts +17 -0
  55. package/dist/services/videoFrameInjector.d.ts.map +1 -0
  56. package/dist/services/videoFrameInjector.js +94 -0
  57. package/dist/services/videoFrameInjector.js.map +1 -0
  58. package/dist/types.d.ts +79 -0
  59. package/dist/types.d.ts.map +1 -0
  60. package/dist/types.js +8 -0
  61. package/dist/types.js.map +1 -0
  62. package/dist/utils/ffprobe.d.ts +18 -0
  63. package/dist/utils/ffprobe.d.ts.map +1 -0
  64. package/dist/utils/ffprobe.js +153 -0
  65. package/dist/utils/ffprobe.js.map +1 -0
  66. package/dist/utils/gpuEncoder.d.ts +11 -0
  67. package/dist/utils/gpuEncoder.d.ts.map +1 -0
  68. package/dist/utils/gpuEncoder.js +55 -0
  69. package/dist/utils/gpuEncoder.js.map +1 -0
  70. package/dist/utils/parityContract.d.ts +3 -0
  71. package/dist/utils/parityContract.d.ts.map +1 -0
  72. package/dist/utils/parityContract.js +35 -0
  73. package/dist/utils/parityContract.js.map +1 -0
  74. package/dist/utils/runFfmpeg.d.ts +19 -0
  75. package/dist/utils/runFfmpeg.d.ts.map +1 -0
  76. package/dist/utils/runFfmpeg.js +62 -0
  77. package/dist/utils/runFfmpeg.js.map +1 -0
  78. package/dist/utils/urlDownloader.d.ts +3 -0
  79. package/dist/utils/urlDownloader.d.ts.map +1 -0
  80. package/dist/utils/urlDownloader.js +68 -0
  81. package/dist/utils/urlDownloader.js.map +1 -0
  82. package/package.json +9 -9
@@ -0,0 +1,368 @@
1
+ /**
2
+ * Chunk Encoder Service
3
+ *
4
+ * Encodes captured frames into video using FFmpeg.
5
+ * Supports CPU (libx264) and GPU encoding.
6
+ */
7
+ import { spawn } from "child_process";
8
+ import { existsSync, mkdirSync, readdirSync, statSync, writeFileSync } from "fs";
9
+ import { join, dirname } from "path";
10
+ import { DEFAULT_CONFIG } from "../config.js";
11
+ import { getCachedGpuEncoder, getGpuEncoderName } from "../utils/gpuEncoder.js";
12
+ import { runFfmpeg } from "../utils/runFfmpeg.js";
13
+ export const ENCODER_PRESETS = {
14
+ draft: { preset: "ultrafast", quality: 28, codec: "h264" },
15
+ standard: { preset: "medium", quality: 23, codec: "h264" },
16
+ high: { preset: "slow", quality: 18, codec: "h264" },
17
+ };
18
+ // Re-export GPU utilities so existing consumers that import from chunkEncoder still work.
19
+ export { detectGpuEncoder } from "../utils/gpuEncoder.js";
20
+ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
21
+ const { fps, codec = "h264", preset = "medium", quality = 23, bitrate, pixelFormat = "yuv420p", useGpu = false, } = options;
22
+ const args = [...inputArgs, "-r", String(fps)];
23
+ const shouldUseGpu = useGpu && gpuEncoder !== null;
24
+ if (codec === "h264" || codec === "h265") {
25
+ if (shouldUseGpu) {
26
+ const encoderName = getGpuEncoderName(gpuEncoder, codec);
27
+ args.push("-c:v", encoderName);
28
+ switch (gpuEncoder) {
29
+ case "nvenc":
30
+ args.push("-preset", preset);
31
+ if (bitrate)
32
+ args.push("-b:v", bitrate);
33
+ else
34
+ args.push("-cq", String(quality));
35
+ break;
36
+ case "videotoolbox":
37
+ if (bitrate)
38
+ args.push("-b:v", bitrate);
39
+ else {
40
+ const vtQuality = Math.max(0, Math.min(100, 100 - quality * 2));
41
+ args.push("-q:v", String(vtQuality));
42
+ }
43
+ args.push("-allow_sw", "1");
44
+ break;
45
+ case "vaapi":
46
+ args.unshift("-vaapi_device", "/dev/dri/renderD128");
47
+ args.push("-vf", "format=nv12,hwupload");
48
+ if (bitrate)
49
+ args.push("-b:v", bitrate);
50
+ else
51
+ args.push("-qp", String(quality));
52
+ break;
53
+ case "qsv":
54
+ args.push("-preset", preset);
55
+ if (bitrate)
56
+ args.push("-b:v", bitrate);
57
+ else
58
+ args.push("-global_quality", String(quality));
59
+ break;
60
+ }
61
+ }
62
+ else {
63
+ const encoderName = codec === "h264" ? "libx264" : "libx265";
64
+ args.push("-c:v", encoderName, "-preset", preset);
65
+ if (bitrate)
66
+ args.push("-b:v", bitrate);
67
+ else
68
+ args.push("-crf", String(quality));
69
+ }
70
+ }
71
+ else if (codec === "vp9") {
72
+ args.push("-c:v", "libvpx-vp9", "-b:v", bitrate || "0", "-crf", String(quality));
73
+ args.push("-deadline", preset === "ultrafast" ? "realtime" : "good");
74
+ }
75
+ else if (codec === "prores") {
76
+ args.push("-c:v", "prores_ks", "-profile:v", preset, "-vendor", "apl0");
77
+ return [...args, "-y", outputPath];
78
+ }
79
+ if (gpuEncoder !== "vaapi") {
80
+ args.push("-pix_fmt", pixelFormat);
81
+ }
82
+ args.push("-y", outputPath);
83
+ return args;
84
+ }
85
+ export async function encodeFramesFromDir(framesDir, framePattern, outputPath, options, signal, config) {
86
+ const startTime = Date.now();
87
+ const outputDir = dirname(outputPath);
88
+ if (!existsSync(outputDir))
89
+ mkdirSync(outputDir, { recursive: true });
90
+ const files = readdirSync(framesDir).filter((f) => f.match(/\.(jpg|jpeg|png)$/i));
91
+ const frameCount = files.length;
92
+ if (frameCount === 0) {
93
+ return {
94
+ success: false,
95
+ outputPath,
96
+ durationMs: Date.now() - startTime,
97
+ framesEncoded: 0,
98
+ fileSize: 0,
99
+ error: "[FFmpeg] No frame files found in directory",
100
+ };
101
+ }
102
+ let gpuEncoder = null;
103
+ if (options.useGpu) {
104
+ gpuEncoder = await getCachedGpuEncoder();
105
+ }
106
+ const inputPath = join(framesDir, framePattern);
107
+ const inputArgs = ["-framerate", String(options.fps), "-i", inputPath];
108
+ const args = buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder);
109
+ return new Promise((resolve) => {
110
+ const ffmpeg = spawn("ffmpeg", args);
111
+ let stderr = "";
112
+ const onAbort = () => {
113
+ ffmpeg.kill("SIGTERM");
114
+ };
115
+ if (signal) {
116
+ if (signal.aborted) {
117
+ ffmpeg.kill("SIGTERM");
118
+ }
119
+ else {
120
+ signal.addEventListener("abort", onAbort, { once: true });
121
+ }
122
+ }
123
+ const encodeTimeout = config?.ffmpegEncodeTimeout ?? DEFAULT_CONFIG.ffmpegEncodeTimeout;
124
+ const timer = setTimeout(() => {
125
+ ffmpeg.kill("SIGTERM");
126
+ }, encodeTimeout);
127
+ ffmpeg.stderr.on("data", (data) => {
128
+ stderr += data.toString();
129
+ });
130
+ ffmpeg.on("close", (code) => {
131
+ clearTimeout(timer);
132
+ if (signal)
133
+ signal.removeEventListener("abort", onAbort);
134
+ const durationMs = Date.now() - startTime;
135
+ if (signal?.aborted) {
136
+ resolve({
137
+ success: false,
138
+ outputPath,
139
+ durationMs,
140
+ framesEncoded: 0,
141
+ fileSize: 0,
142
+ error: "FFmpeg encode cancelled",
143
+ });
144
+ return;
145
+ }
146
+ if (code !== 0) {
147
+ resolve({
148
+ success: false,
149
+ outputPath,
150
+ durationMs,
151
+ framesEncoded: 0,
152
+ fileSize: 0,
153
+ error: `FFmpeg exited with code ${code}`,
154
+ });
155
+ return;
156
+ }
157
+ const fileSize = existsSync(outputPath) ? statSync(outputPath).size : 0;
158
+ resolve({ success: true, outputPath, durationMs, framesEncoded: frameCount, fileSize });
159
+ });
160
+ ffmpeg.on("error", (err) => {
161
+ clearTimeout(timer);
162
+ if (signal)
163
+ signal.removeEventListener("abort", onAbort);
164
+ resolve({
165
+ success: false,
166
+ outputPath,
167
+ durationMs: Date.now() - startTime,
168
+ framesEncoded: 0,
169
+ fileSize: 0,
170
+ error: `[FFmpeg] ${err.message}`,
171
+ });
172
+ });
173
+ });
174
+ }
175
+ export async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, options, chunkSizeFrames, signal) {
176
+ const start = Date.now();
177
+ const files = readdirSync(framesDir)
178
+ .filter((f) => f.match(/\.(jpg|jpeg|png)$/i))
179
+ .sort();
180
+ if (files.length === 0) {
181
+ return {
182
+ success: false,
183
+ outputPath,
184
+ durationMs: Date.now() - start,
185
+ framesEncoded: 0,
186
+ fileSize: 0,
187
+ error: "[FFmpeg] No frame files found in directory",
188
+ };
189
+ }
190
+ const chunkSize = Math.max(30, Math.floor(chunkSizeFrames));
191
+ const chunkCount = Math.ceil(files.length / chunkSize);
192
+ const chunkDir = join(dirname(outputPath), "chunk-encode");
193
+ if (!existsSync(chunkDir))
194
+ mkdirSync(chunkDir, { recursive: true });
195
+ const chunkPaths = [];
196
+ for (let i = 0; i < chunkCount; i++) {
197
+ if (signal?.aborted) {
198
+ return {
199
+ success: false,
200
+ outputPath,
201
+ durationMs: Date.now() - start,
202
+ framesEncoded: 0,
203
+ fileSize: 0,
204
+ error: "Chunked encode cancelled",
205
+ };
206
+ }
207
+ const startNumber = i * chunkSize;
208
+ const framesInChunk = Math.min(chunkSize, files.length - startNumber);
209
+ const chunkPath = join(chunkDir, `chunk_${String(i).padStart(4, "0")}.mp4`);
210
+ const inputPath = join(framesDir, framePattern);
211
+ const inputArgs = [
212
+ "-framerate",
213
+ String(options.fps),
214
+ "-start_number",
215
+ String(startNumber),
216
+ "-i",
217
+ inputPath,
218
+ "-frames:v",
219
+ String(framesInChunk),
220
+ ];
221
+ let gpuEncoder = null;
222
+ if (options.useGpu)
223
+ gpuEncoder = await getCachedGpuEncoder();
224
+ const args = buildEncoderArgs(options, inputArgs, chunkPath, gpuEncoder);
225
+ const chunkResult = await new Promise((resolve) => {
226
+ const ffmpeg = spawn("ffmpeg", args);
227
+ let stderr = "";
228
+ ffmpeg.stderr.on("data", (d) => {
229
+ stderr += d.toString();
230
+ });
231
+ ffmpeg.on("close", (code) => {
232
+ if (code === 0)
233
+ resolve({ success: true });
234
+ else
235
+ resolve({ success: false, error: `Chunk ${i} encode failed: ${stderr.slice(-400)}` });
236
+ });
237
+ ffmpeg.on("error", (err) => {
238
+ resolve({ success: false, error: `Chunk ${i} encode error: ${err.message}` });
239
+ });
240
+ });
241
+ if (!chunkResult.success) {
242
+ return {
243
+ success: false,
244
+ outputPath,
245
+ durationMs: Date.now() - start,
246
+ framesEncoded: 0,
247
+ fileSize: 0,
248
+ error: chunkResult.error,
249
+ };
250
+ }
251
+ chunkPaths.push(chunkPath);
252
+ }
253
+ const concatListPath = join(chunkDir, "concat-list.txt");
254
+ const concatInput = chunkPaths.map((path) => `file '${path.replace(/'/g, "'\\''")}'`).join("\n");
255
+ writeFileSync(concatListPath, concatInput, "utf-8");
256
+ const concatArgs = [
257
+ "-f",
258
+ "concat",
259
+ "-safe",
260
+ "0",
261
+ "-i",
262
+ concatListPath,
263
+ "-c",
264
+ "copy",
265
+ "-y",
266
+ outputPath,
267
+ ];
268
+ const concatResult = await new Promise((resolve) => {
269
+ const ffmpeg = spawn("ffmpeg", concatArgs);
270
+ let stderr = "";
271
+ ffmpeg.stderr.on("data", (d) => {
272
+ stderr += d.toString();
273
+ });
274
+ ffmpeg.on("close", (code) => {
275
+ if (code === 0)
276
+ resolve({ success: true });
277
+ else
278
+ resolve({ success: false, error: `Chunk concat failed: ${stderr.slice(-400)}` });
279
+ });
280
+ ffmpeg.on("error", (err) => {
281
+ resolve({ success: false, error: `Chunk concat error: ${err.message}` });
282
+ });
283
+ });
284
+ if (!concatResult.success) {
285
+ return {
286
+ success: false,
287
+ outputPath,
288
+ durationMs: Date.now() - start,
289
+ framesEncoded: 0,
290
+ fileSize: 0,
291
+ error: concatResult.error,
292
+ };
293
+ }
294
+ const fileSize = existsSync(outputPath) ? statSync(outputPath).size : 0;
295
+ return {
296
+ success: true,
297
+ outputPath,
298
+ durationMs: Date.now() - start,
299
+ framesEncoded: files.length,
300
+ fileSize,
301
+ };
302
+ }
303
+ export async function muxVideoWithAudio(videoPath, audioPath, outputPath, signal, config) {
304
+ const outputDir = dirname(outputPath);
305
+ if (!existsSync(outputDir))
306
+ mkdirSync(outputDir, { recursive: true });
307
+ const args = [
308
+ "-i",
309
+ videoPath,
310
+ "-i",
311
+ audioPath,
312
+ "-c:v",
313
+ "copy",
314
+ "-c:a",
315
+ "aac",
316
+ "-b:a",
317
+ "192k",
318
+ "-shortest",
319
+ "-movflags",
320
+ "+faststart",
321
+ "-y",
322
+ outputPath,
323
+ ];
324
+ const processTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
325
+ const result = await runFfmpeg(args, { signal, timeout: processTimeout });
326
+ if (signal?.aborted) {
327
+ return {
328
+ success: false,
329
+ outputPath,
330
+ durationMs: result.durationMs,
331
+ error: "FFmpeg mux cancelled",
332
+ };
333
+ }
334
+ return {
335
+ success: result.success,
336
+ outputPath,
337
+ durationMs: result.durationMs,
338
+ error: !result.success
339
+ ? result.exitCode !== null
340
+ ? `FFmpeg exited with code ${result.exitCode}`
341
+ : `[FFmpeg] ${result.stderr}`
342
+ : undefined,
343
+ };
344
+ }
345
+ export async function applyFaststart(inputPath, outputPath, signal, config) {
346
+ const args = ["-i", inputPath, "-c", "copy", "-movflags", "+faststart", "-y", outputPath];
347
+ const processTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
348
+ const result = await runFfmpeg(args, { signal, timeout: processTimeout });
349
+ if (signal?.aborted) {
350
+ return {
351
+ success: false,
352
+ outputPath,
353
+ durationMs: result.durationMs,
354
+ error: "FFmpeg faststart cancelled",
355
+ };
356
+ }
357
+ return {
358
+ success: result.success,
359
+ outputPath,
360
+ durationMs: result.durationMs,
361
+ error: !result.success
362
+ ? result.exitCode !== null
363
+ ? `FFmpeg exited with code ${result.exitCode}`
364
+ : `[FFmpeg] ${result.stderr}`
365
+ : undefined,
366
+ };
367
+ }
368
+ //# sourceMappingURL=chunkEncoder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunkEncoder.js","sourceRoot":"","sources":["../../src/services/chunkEncoder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ export interface EncoderOptions {
2
+ fps: number;
3
+ width: number;
4
+ height: number;
5
+ codec?: "h264" | "h265" | "vp9" | "prores";
6
+ preset?: string;
7
+ quality?: number;
8
+ bitrate?: string;
9
+ pixelFormat?: string;
10
+ useGpu?: boolean;
11
+ }
12
+ export interface EncodeResult {
13
+ success: boolean;
14
+ outputPath: string;
15
+ durationMs: number;
16
+ framesEncoded: number;
17
+ fileSize: number;
18
+ error?: string;
19
+ }
20
+ export interface MuxResult {
21
+ success: boolean;
22
+ outputPath: string;
23
+ durationMs: number;
24
+ error?: string;
25
+ }
26
+ //# sourceMappingURL=chunkEncoder.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunkEncoder.types.d.ts","sourceRoot":"","sources":["../../src/services/chunkEncoder.types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC;IAC3C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=chunkEncoder.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunkEncoder.types.js","sourceRoot":"","sources":["../../src/services/chunkEncoder.types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * File Server
3
+ *
4
+ * Lightweight HTTP server that serves a project directory to headless Chrome.
5
+ * Optionally injects scripts into index.html on-the-fly (e.g. runtime, bridge).
6
+ * Framework-agnostic — the caller decides what scripts to inject.
7
+ */
8
+ export interface FileServerOptions {
9
+ projectDir: string;
10
+ compiledDir?: string;
11
+ port?: number;
12
+ /** Scripts injected into <head> of index.html. Default: none. */
13
+ headScripts?: string[];
14
+ /** Scripts injected before </body> of index.html. Default: none. */
15
+ bodyScripts?: string[];
16
+ /** Strip embedded runtime scripts from HTML before injection. Default: true. */
17
+ stripEmbeddedRuntime?: boolean;
18
+ }
19
+ export interface FileServerHandle {
20
+ url: string;
21
+ port: number;
22
+ close: () => void;
23
+ }
24
+ export declare function createFileServer(options: FileServerOptions): Promise<FileServerHandle>;
25
+ //# sourceMappingURL=fileServer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fileServer.d.ts","sourceRoot":"","sources":["../../src/services/fileServer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAkGH,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iEAAiE;IACjE,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,oEAAoE;IACpE,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,gFAAgF;IAChF,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAsDtF"}
@@ -0,0 +1,138 @@
1
+ /**
2
+ * File Server
3
+ *
4
+ * Lightweight HTTP server that serves a project directory to headless Chrome.
5
+ * Optionally injects scripts into index.html on-the-fly (e.g. runtime, bridge).
6
+ * Framework-agnostic — the caller decides what scripts to inject.
7
+ */
8
+ import { Hono } from "hono";
9
+ import { serve } from "@hono/node-server";
10
+ import { readFileSync, existsSync, statSync } from "node:fs";
11
+ import { join, extname } from "node:path";
12
+ const MIME_TYPES = {
13
+ ".html": "text/html; charset=utf-8",
14
+ ".css": "text/css; charset=utf-8",
15
+ ".js": "application/javascript; charset=utf-8",
16
+ ".json": "application/json; charset=utf-8",
17
+ ".png": "image/png",
18
+ ".jpg": "image/jpeg",
19
+ ".jpeg": "image/jpeg",
20
+ ".gif": "image/gif",
21
+ ".svg": "image/svg+xml",
22
+ ".webp": "image/webp",
23
+ ".mp4": "video/mp4",
24
+ ".webm": "video/webm",
25
+ ".mp3": "audio/mpeg",
26
+ ".wav": "audio/wav",
27
+ ".ogg": "audio/ogg",
28
+ ".aac": "audio/aac",
29
+ ".woff": "font/woff",
30
+ ".woff2": "font/woff2",
31
+ ".ttf": "font/ttf",
32
+ ".otf": "font/otf",
33
+ };
34
+ function stripEmbeddedRuntimeScripts(html) {
35
+ if (!html)
36
+ return html;
37
+ const scriptRe = /<script\b[^>]*>[\s\S]*?<\/script>/gi;
38
+ const runtimeSrcMarkers = [
39
+ "hyperframe.runtime.iife.js",
40
+ "hyperframes-runtime.modular.inline.js",
41
+ "data-hyperframes-preview-runtime",
42
+ ];
43
+ const runtimeInlineMarkers = [
44
+ "__hyperframeRuntimeBootstrapped",
45
+ "__hyperframeRuntime",
46
+ "__hyperframeRuntimeTeardown",
47
+ "window.__player =",
48
+ "window.__playerReady",
49
+ "window.__renderReady",
50
+ ];
51
+ const shouldStrip = (block) => {
52
+ const lowered = block.toLowerCase();
53
+ for (const marker of runtimeSrcMarkers) {
54
+ if (lowered.includes(marker.toLowerCase())) {
55
+ return true;
56
+ }
57
+ }
58
+ for (const marker of runtimeInlineMarkers) {
59
+ if (block.includes(marker)) {
60
+ return true;
61
+ }
62
+ }
63
+ return false;
64
+ };
65
+ return html.replace(scriptRe, (block) => (shouldStrip(block) ? "" : block));
66
+ }
67
+ function injectScriptsIntoHtml(html, headScripts, bodyScripts, stripEmbedded) {
68
+ if (stripEmbedded) {
69
+ html = stripEmbeddedRuntimeScripts(html);
70
+ }
71
+ if (headScripts.length > 0) {
72
+ const headTags = headScripts.map((src) => `<script>${src}</script>`).join("\n");
73
+ if (html.includes("</head>")) {
74
+ html = html.replace("</head>", () => `${headTags}\n</head>`);
75
+ }
76
+ else if (html.includes("<body")) {
77
+ html = html.replace("<body", () => `${headTags}\n<body`);
78
+ }
79
+ else {
80
+ html = headTags + "\n" + html;
81
+ }
82
+ }
83
+ if (bodyScripts.length > 0) {
84
+ const bodyTags = bodyScripts.map((src) => `<script>${src}</script>`).join("\n");
85
+ if (html.includes("</body>")) {
86
+ html = html.replace("</body>", () => `${bodyTags}\n</body>`);
87
+ }
88
+ else {
89
+ html = html + "\n" + bodyTags;
90
+ }
91
+ }
92
+ return html;
93
+ }
94
+ export function createFileServer(options) {
95
+ const { projectDir, compiledDir, port = 0, stripEmbeddedRuntime = true } = options;
96
+ const headScripts = options.headScripts ?? [];
97
+ const bodyScripts = options.bodyScripts ?? [];
98
+ const app = new Hono();
99
+ app.get("/*", (c) => {
100
+ let requestPath = c.req.path;
101
+ if (requestPath === "/")
102
+ requestPath = "/index.html";
103
+ // Remove leading slash
104
+ const relativePath = requestPath.replace(/^\//, "");
105
+ const compiledPath = compiledDir ? join(compiledDir, relativePath) : null;
106
+ const hasCompiledFile = Boolean(compiledPath && existsSync(compiledPath) && statSync(compiledPath).isFile());
107
+ const filePath = hasCompiledFile ? compiledPath : join(projectDir, relativePath);
108
+ if (!existsSync(filePath) || !statSync(filePath).isFile()) {
109
+ return c.text("Not found", 404);
110
+ }
111
+ const ext = extname(filePath).toLowerCase();
112
+ const contentType = MIME_TYPES[ext] || "application/octet-stream";
113
+ if (ext === ".html") {
114
+ const rawHtml = readFileSync(filePath, "utf-8");
115
+ const html = relativePath === "index.html"
116
+ ? injectScriptsIntoHtml(rawHtml, headScripts, bodyScripts, stripEmbeddedRuntime)
117
+ : rawHtml;
118
+ return c.text(html, 200, { "Content-Type": contentType });
119
+ }
120
+ const content = readFileSync(filePath);
121
+ return new Response(content, {
122
+ status: 200,
123
+ headers: { "Content-Type": contentType },
124
+ });
125
+ });
126
+ return new Promise((resolve) => {
127
+ const server = serve({ fetch: app.fetch, port }, (info) => {
128
+ const actualPort = info.port;
129
+ const url = `http://localhost:${actualPort}`;
130
+ resolve({
131
+ url,
132
+ port: actualPort,
133
+ close: () => server.close(),
134
+ });
135
+ });
136
+ });
137
+ }
138
+ //# sourceMappingURL=fileServer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fileServer.js","sourceRoot":"","sources":["../../src/services/fileServer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Frame Capture Service
3
+ *
4
+ * Uses Puppeteer to capture frames from any web page implementing the
5
+ * window.__hf seek protocol. Navigates to a file server URL, waits for
6
+ * the page to expose window.__hf, then captures frames deterministically
7
+ * via Chrome's BeginFrame API or Page.captureScreenshot fallback.
8
+ */
9
+ import { type Browser, type Page } from "puppeteer-core";
10
+ import { type CaptureMode } from "./browserManager.js";
11
+ import { type EngineConfig } from "../config.js";
12
+ import type { CaptureOptions, CaptureResult, CaptureBufferResult, CapturePerfSummary } from "../types.js";
13
+ export type { CaptureOptions, CaptureResult, CaptureBufferResult, CapturePerfSummary };
14
+ /** Called after seeking, before screenshot. Use for video frame injection or other pre-capture work. */
15
+ export type BeforeCaptureHook = (page: Page, time: number) => Promise<void>;
16
+ export interface CaptureSession {
17
+ browser: Browser;
18
+ page: Page;
19
+ options: CaptureOptions;
20
+ serverUrl: string;
21
+ outputDir: string;
22
+ onBeforeCapture: BeforeCaptureHook | null;
23
+ isInitialized: boolean;
24
+ browserConsoleBuffer: string[];
25
+ capturePerf: {
26
+ frames: number;
27
+ seekMs: number;
28
+ beforeCaptureMs: number;
29
+ screenshotMs: number;
30
+ totalMs: number;
31
+ };
32
+ captureMode: CaptureMode;
33
+ beginFrameTimeTicks: number;
34
+ beginFrameIntervalMs: number;
35
+ beginFrameHasDamageCount: number;
36
+ beginFrameNoDamageCount: number;
37
+ /** Optional producer config — when set, overrides module-level env var constants. */
38
+ config?: Partial<EngineConfig>;
39
+ }
40
+ export declare function createCaptureSession(serverUrl: string, outputDir: string, options: CaptureOptions, onBeforeCapture?: BeforeCaptureHook | null, config?: Partial<EngineConfig>): Promise<CaptureSession>;
41
+ export declare function initializeSession(session: CaptureSession): Promise<void>;
42
+ export declare function captureFrame(session: CaptureSession, frameIndex: number, time: number): Promise<CaptureResult>;
43
+ /**
44
+ * Capture a frame and return the screenshot as a Buffer instead of writing to disk.
45
+ * Used by the streaming encode pipeline to pipe frames directly to FFmpeg stdin.
46
+ */
47
+ export declare function captureFrameToBuffer(session: CaptureSession, frameIndex: number, time: number): Promise<CaptureBufferResult>;
48
+ export declare function closeCaptureSession(session: CaptureSession): Promise<void>;
49
+ export declare function prepareCaptureSessionForReuse(session: CaptureSession, outputDir: string, onBeforeCapture: BeforeCaptureHook | null): void;
50
+ export declare function getCompositionDuration(session: CaptureSession): Promise<number>;
51
+ export declare function getCapturePerfSummary(session: CaptureSession): CapturePerfSummary;
52
+ //# sourceMappingURL=frameCapture.d.ts.map