@hyperframes/engine 0.1.1 → 0.1.2

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 (96) hide show
  1. package/README.md +78 -0
  2. package/package.json +9 -9
  3. package/src/config.ts +32 -8
  4. package/src/index.ts +15 -17
  5. package/src/services/audioMixer.ts +33 -8
  6. package/src/services/browserManager.ts +7 -2
  7. package/src/services/chunkEncoder.ts +24 -3
  8. package/src/services/fileServer.ts +3 -1
  9. package/src/services/frameCapture.ts +46 -13
  10. package/src/services/parallelCoordinator.ts +25 -5
  11. package/src/services/screenshotService.ts +4 -1
  12. package/src/services/videoFrameExtractor.ts +19 -4
  13. package/src/services/videoFrameInjector.ts +9 -3
  14. package/src/utils/ffprobe.ts +25 -4
  15. package/src/utils/urlDownloader.ts +5 -1
  16. package/LICENSE +0 -21
  17. package/dist/config.d.ts +0 -62
  18. package/dist/config.d.ts.map +0 -1
  19. package/dist/config.js +0 -92
  20. package/dist/config.js.map +0 -1
  21. package/dist/index.d.ts +0 -49
  22. package/dist/index.d.ts.map +0 -1
  23. package/dist/index.js +0 -55
  24. package/dist/index.js.map +0 -1
  25. package/dist/services/audioMixer.d.ts +0 -11
  26. package/dist/services/audioMixer.d.ts.map +0 -1
  27. package/dist/services/audioMixer.js +0 -306
  28. package/dist/services/audioMixer.js.map +0 -1
  29. package/dist/services/audioMixer.types.d.ts +0 -27
  30. package/dist/services/audioMixer.types.d.ts.map +0 -1
  31. package/dist/services/audioMixer.types.js +0 -2
  32. package/dist/services/audioMixer.types.js.map +0 -1
  33. package/dist/services/browserManager.d.ts +0 -29
  34. package/dist/services/browserManager.d.ts.map +0 -1
  35. package/dist/services/browserManager.js +0 -175
  36. package/dist/services/browserManager.js.map +0 -1
  37. package/dist/services/chunkEncoder.d.ts +0 -32
  38. package/dist/services/chunkEncoder.d.ts.map +0 -1
  39. package/dist/services/chunkEncoder.js +0 -347
  40. package/dist/services/chunkEncoder.js.map +0 -1
  41. package/dist/services/chunkEncoder.types.d.ts +0 -26
  42. package/dist/services/chunkEncoder.types.d.ts.map +0 -1
  43. package/dist/services/chunkEncoder.types.js +0 -2
  44. package/dist/services/chunkEncoder.types.js.map +0 -1
  45. package/dist/services/fileServer.d.ts +0 -25
  46. package/dist/services/fileServer.d.ts.map +0 -1
  47. package/dist/services/fileServer.js +0 -138
  48. package/dist/services/fileServer.js.map +0 -1
  49. package/dist/services/frameCapture.d.ts +0 -52
  50. package/dist/services/frameCapture.d.ts.map +0 -1
  51. package/dist/services/frameCapture.js +0 -317
  52. package/dist/services/frameCapture.js.map +0 -1
  53. package/dist/services/parallelCoordinator.d.ts +0 -40
  54. package/dist/services/parallelCoordinator.d.ts.map +0 -1
  55. package/dist/services/parallelCoordinator.js +0 -192
  56. package/dist/services/parallelCoordinator.js.map +0 -1
  57. package/dist/services/screenshotService.d.ts +0 -28
  58. package/dist/services/screenshotService.d.ts.map +0 -1
  59. package/dist/services/screenshotService.js +0 -190
  60. package/dist/services/screenshotService.js.map +0 -1
  61. package/dist/services/streamingEncoder.d.ts +0 -49
  62. package/dist/services/streamingEncoder.d.ts.map +0 -1
  63. package/dist/services/streamingEncoder.js +0 -227
  64. package/dist/services/streamingEncoder.js.map +0 -1
  65. package/dist/services/videoFrameExtractor.d.ts +0 -65
  66. package/dist/services/videoFrameExtractor.d.ts.map +0 -1
  67. package/dist/services/videoFrameExtractor.js +0 -302
  68. package/dist/services/videoFrameExtractor.js.map +0 -1
  69. package/dist/services/videoFrameInjector.d.ts +0 -17
  70. package/dist/services/videoFrameInjector.d.ts.map +0 -1
  71. package/dist/services/videoFrameInjector.js +0 -92
  72. package/dist/services/videoFrameInjector.js.map +0 -1
  73. package/dist/types.d.ts +0 -79
  74. package/dist/types.d.ts.map +0 -1
  75. package/dist/types.js +0 -8
  76. package/dist/types.js.map +0 -1
  77. package/dist/utils/ffprobe.d.ts +0 -18
  78. package/dist/utils/ffprobe.d.ts.map +0 -1
  79. package/dist/utils/ffprobe.js +0 -137
  80. package/dist/utils/ffprobe.js.map +0 -1
  81. package/dist/utils/gpuEncoder.d.ts +0 -11
  82. package/dist/utils/gpuEncoder.d.ts.map +0 -1
  83. package/dist/utils/gpuEncoder.js +0 -55
  84. package/dist/utils/gpuEncoder.js.map +0 -1
  85. package/dist/utils/parityContract.d.ts +0 -3
  86. package/dist/utils/parityContract.d.ts.map +0 -1
  87. package/dist/utils/parityContract.js +0 -35
  88. package/dist/utils/parityContract.js.map +0 -1
  89. package/dist/utils/runFfmpeg.d.ts +0 -19
  90. package/dist/utils/runFfmpeg.d.ts.map +0 -1
  91. package/dist/utils/runFfmpeg.js +0 -62
  92. package/dist/utils/runFfmpeg.js.map +0 -1
  93. package/dist/utils/urlDownloader.d.ts +0 -3
  94. package/dist/utils/urlDownloader.d.ts.map +0 -1
  95. package/dist/utils/urlDownloader.js +0 -68
  96. package/dist/utils/urlDownloader.js.map +0 -1
@@ -1,302 +0,0 @@
1
- /**
2
- * Video Frame Extractor Service
3
- *
4
- * Pre-extracts video frames using FFmpeg for frame-accurate rendering.
5
- * Videos are replaced with <img> elements during capture.
6
- */
7
- import { spawn } from "child_process";
8
- import { existsSync, mkdirSync, readdirSync, rmSync } from "fs";
9
- import { join } from "path";
10
- import { parseHTML } from "linkedom";
11
- import { extractVideoMetadata } from "../utils/ffprobe.js";
12
- import { downloadToTemp, isHttpUrl } from "../utils/urlDownloader.js";
13
- import { DEFAULT_CONFIG } from "../config.js";
14
- export function parseVideoElements(html) {
15
- const videos = [];
16
- const { document } = parseHTML(html);
17
- const videoEls = document.querySelectorAll("video[id][src]");
18
- for (const el of videoEls) {
19
- const id = el.getAttribute("id");
20
- const src = el.getAttribute("src");
21
- if (!id || !src)
22
- continue;
23
- const startAttr = el.getAttribute("data-start");
24
- const endAttr = el.getAttribute("data-end");
25
- const mediaStartAttr = el.getAttribute("data-media-start");
26
- const hasAudioAttr = el.getAttribute("data-has-audio");
27
- videos.push({
28
- id,
29
- src,
30
- start: startAttr ? parseFloat(startAttr) : 0,
31
- end: endAttr ? parseFloat(endAttr) : 0,
32
- mediaStart: mediaStartAttr ? parseFloat(mediaStartAttr) : 0,
33
- hasAudio: hasAudioAttr === "true",
34
- });
35
- }
36
- return videos;
37
- }
38
- export async function extractVideoFramesRange(videoPath, videoId, startTime, duration, options, signal, config) {
39
- const ffmpegProcessTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
40
- const { fps, outputDir, quality = 95, format = "jpg" } = options;
41
- const videoOutputDir = join(outputDir, videoId);
42
- if (!existsSync(videoOutputDir))
43
- mkdirSync(videoOutputDir, { recursive: true });
44
- const metadata = await extractVideoMetadata(videoPath);
45
- const framePattern = `frame_%05d.${format}`;
46
- const outputPattern = join(videoOutputDir, framePattern);
47
- const args = [
48
- "-ss",
49
- String(startTime),
50
- "-i",
51
- videoPath,
52
- "-t",
53
- String(duration),
54
- "-vf",
55
- `fps=${fps}`,
56
- "-q:v",
57
- format === "jpg" ? String(Math.ceil((100 - quality) / 3)) : "0",
58
- ];
59
- if (format === "png")
60
- args.push("-compression_level", "6");
61
- args.push("-y", outputPattern);
62
- return new Promise((resolve, reject) => {
63
- const ffmpeg = spawn("ffmpeg", args);
64
- let stderr = "";
65
- const onAbort = () => {
66
- ffmpeg.kill("SIGTERM");
67
- };
68
- if (signal) {
69
- if (signal.aborted) {
70
- ffmpeg.kill("SIGTERM");
71
- }
72
- else {
73
- signal.addEventListener("abort", onAbort, { once: true });
74
- }
75
- }
76
- const timer = setTimeout(() => {
77
- ffmpeg.kill("SIGTERM");
78
- }, ffmpegProcessTimeout);
79
- ffmpeg.stderr.on("data", (data) => {
80
- stderr += data.toString();
81
- });
82
- ffmpeg.on("close", (code) => {
83
- clearTimeout(timer);
84
- if (signal)
85
- signal.removeEventListener("abort", onAbort);
86
- if (signal?.aborted) {
87
- reject(new Error("Video frame extraction cancelled"));
88
- return;
89
- }
90
- if (code !== 0) {
91
- reject(new Error(`FFmpeg exited with code ${code}: ${stderr.slice(-500)}`));
92
- return;
93
- }
94
- const framePaths = new Map();
95
- const files = readdirSync(videoOutputDir)
96
- .filter((f) => f.startsWith("frame_") && f.endsWith(`.${format}`))
97
- .sort();
98
- files.forEach((file, index) => {
99
- framePaths.set(index, join(videoOutputDir, file));
100
- });
101
- resolve({
102
- videoId,
103
- srcPath: videoPath,
104
- outputDir: videoOutputDir,
105
- framePattern,
106
- fps,
107
- totalFrames: framePaths.size,
108
- metadata,
109
- framePaths,
110
- });
111
- });
112
- ffmpeg.on("error", (err) => {
113
- clearTimeout(timer);
114
- if (signal)
115
- signal.removeEventListener("abort", onAbort);
116
- if (err.code === "ENOENT") {
117
- reject(new Error("[FFmpeg] ffmpeg not found"));
118
- }
119
- else {
120
- reject(err);
121
- }
122
- });
123
- });
124
- }
125
- export async function extractAllVideoFrames(videos, baseDir, options, signal, config) {
126
- const startTime = Date.now();
127
- const extracted = [];
128
- const errors = [];
129
- let totalFramesExtracted = 0;
130
- // Process videos in parallel for better performance
131
- const results = await Promise.all(videos.map(async (video) => {
132
- if (signal?.aborted) {
133
- throw new Error("Video frame extraction cancelled");
134
- }
135
- try {
136
- let videoPath = video.src;
137
- if (!videoPath.startsWith("/") && !isHttpUrl(videoPath)) {
138
- videoPath = join(baseDir, videoPath);
139
- }
140
- if (isHttpUrl(videoPath)) {
141
- const downloadDir = join(options.outputDir, "_downloads");
142
- mkdirSync(downloadDir, { recursive: true });
143
- videoPath = await downloadToTemp(videoPath, downloadDir);
144
- }
145
- if (!existsSync(videoPath)) {
146
- return { error: { videoId: video.id, error: `Video file not found: ${videoPath}` } };
147
- }
148
- let videoDuration = video.end - video.start;
149
- // Fallback: if no data-duration/data-end was specified, probe the actual file
150
- if (videoDuration <= 0) {
151
- const metadata = await extractVideoMetadata(videoPath);
152
- const sourceDuration = metadata.durationSeconds - video.mediaStart;
153
- videoDuration = sourceDuration > 0 ? sourceDuration : metadata.durationSeconds;
154
- video.end = video.start + videoDuration;
155
- }
156
- const result = await extractVideoFramesRange(videoPath, video.id, video.mediaStart, videoDuration, options, signal, config);
157
- return { result };
158
- }
159
- catch (err) {
160
- return {
161
- error: {
162
- videoId: video.id,
163
- error: err instanceof Error ? err.message : String(err),
164
- },
165
- };
166
- }
167
- }));
168
- // Collect results and errors
169
- for (const item of results) {
170
- if ("error" in item && item.error) {
171
- errors.push(item.error);
172
- }
173
- else if ("result" in item) {
174
- extracted.push(item.result);
175
- totalFramesExtracted += item.result.totalFrames;
176
- }
177
- }
178
- return { success: errors.length === 0, extracted, errors, totalFramesExtracted, durationMs: Date.now() - startTime };
179
- }
180
- export function getFrameAtTime(extracted, globalTime, videoStart) {
181
- const localTime = globalTime - videoStart;
182
- if (localTime < 0)
183
- return null;
184
- const frameIndex = Math.floor(localTime * extracted.fps);
185
- if (frameIndex < 0 || frameIndex >= extracted.totalFrames)
186
- return null;
187
- return extracted.framePaths.get(frameIndex) || null;
188
- }
189
- export class FrameLookupTable {
190
- videos = new Map();
191
- orderedVideos = [];
192
- activeVideoIds = new Set();
193
- startCursor = 0;
194
- lastTime = null;
195
- addVideo(extracted, start, end, mediaStart) {
196
- this.videos.set(extracted.videoId, { extracted, start, end, mediaStart });
197
- this.orderedVideos = Array.from(this.videos.entries())
198
- .map(([videoId, video]) => ({ videoId, ...video }))
199
- .sort((a, b) => a.start - b.start);
200
- this.resetActiveState();
201
- }
202
- getFrame(videoId, globalTime) {
203
- const video = this.videos.get(videoId);
204
- if (!video)
205
- return null;
206
- if (globalTime < video.start || globalTime >= video.end)
207
- return null;
208
- return getFrameAtTime(video.extracted, globalTime, video.start);
209
- }
210
- resetActiveState() {
211
- this.activeVideoIds.clear();
212
- this.startCursor = 0;
213
- this.lastTime = null;
214
- }
215
- refreshActiveSet(globalTime) {
216
- if (this.lastTime == null || globalTime < this.lastTime) {
217
- this.activeVideoIds.clear();
218
- this.startCursor = 0;
219
- for (const entry of this.orderedVideos) {
220
- if (entry.start <= globalTime && globalTime < entry.end) {
221
- this.activeVideoIds.add(entry.videoId);
222
- }
223
- if (entry.start <= globalTime) {
224
- this.startCursor += 1;
225
- }
226
- else {
227
- break;
228
- }
229
- }
230
- this.lastTime = globalTime;
231
- return;
232
- }
233
- while (this.startCursor < this.orderedVideos.length) {
234
- const candidate = this.orderedVideos[this.startCursor];
235
- if (!candidate)
236
- break;
237
- if (candidate.start > globalTime) {
238
- break;
239
- }
240
- if (globalTime < candidate.end) {
241
- this.activeVideoIds.add(candidate.videoId);
242
- }
243
- this.startCursor += 1;
244
- }
245
- for (const videoId of Array.from(this.activeVideoIds)) {
246
- const video = this.videos.get(videoId);
247
- if (!video || globalTime < video.start || globalTime >= video.end) {
248
- this.activeVideoIds.delete(videoId);
249
- }
250
- }
251
- this.lastTime = globalTime;
252
- }
253
- getActiveFramePayloads(globalTime) {
254
- const frames = new Map();
255
- this.refreshActiveSet(globalTime);
256
- for (const videoId of this.activeVideoIds) {
257
- const video = this.videos.get(videoId);
258
- if (!video)
259
- continue;
260
- const localTime = globalTime - video.start;
261
- const frameIndex = Math.floor(localTime * video.extracted.fps);
262
- if (frameIndex < 0 || frameIndex >= video.extracted.totalFrames)
263
- continue;
264
- const framePath = video.extracted.framePaths.get(frameIndex);
265
- if (!framePath)
266
- continue;
267
- frames.set(videoId, { framePath, frameIndex });
268
- }
269
- return frames;
270
- }
271
- getActiveFrames(globalTime) {
272
- const payloads = this.getActiveFramePayloads(globalTime);
273
- const frames = new Map();
274
- for (const [videoId, payload] of payloads) {
275
- frames.set(videoId, payload.framePath);
276
- }
277
- return frames;
278
- }
279
- cleanup() {
280
- for (const video of this.videos.values()) {
281
- if (existsSync(video.extracted.outputDir)) {
282
- rmSync(video.extracted.outputDir, { recursive: true, force: true });
283
- }
284
- }
285
- this.videos.clear();
286
- this.orderedVideos = [];
287
- this.resetActiveState();
288
- }
289
- }
290
- export function createFrameLookupTable(videos, extracted) {
291
- const table = new FrameLookupTable();
292
- const extractedMap = new Map();
293
- for (const ext of extracted)
294
- extractedMap.set(ext.videoId, ext);
295
- for (const video of videos) {
296
- const ext = extractedMap.get(video.id);
297
- if (ext)
298
- table.addVideo(ext, video.start, video.end, video.mediaStart);
299
- }
300
- return table;
301
- }
302
- //# sourceMappingURL=videoFrameExtractor.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"videoFrameExtractor.js","sourceRoot":"","sources":["../../src/services/videoFrameExtractor.ts"],"names":[],"mappings":"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"}
@@ -1,17 +0,0 @@
1
- /**
2
- * Video Frame Injector
3
- *
4
- * Creates a BeforeCaptureHook that replaces native <video> elements with
5
- * pre-extracted frame images during rendering. This is the Hyperframes-specific
6
- * video handling strategy — OSS users with different video pipelines can
7
- * provide their own hook or skip video injection entirely.
8
- */
9
- import { type FrameLookupTable } from "./videoFrameExtractor.js";
10
- import { type BeforeCaptureHook } from "./frameCapture.js";
11
- import { type EngineConfig } from "../config.js";
12
- /**
13
- * Creates a BeforeCaptureHook that injects pre-extracted video frames
14
- * into the page, replacing native <video> elements with frame images.
15
- */
16
- export declare function createVideoFrameInjector(frameLookup: FrameLookupTable | null, config?: Partial<Pick<EngineConfig, "frameDataUriCacheLimit">>): BeforeCaptureHook | null;
17
- //# sourceMappingURL=videoFrameInjector.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"videoFrameInjector.d.ts","sourceRoot":"","sources":["../../src/services/videoFrameInjector.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAiDjE;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,gBAAgB,GAAG,IAAI,EACpC,MAAM,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,wBAAwB,CAAC,CAAC,GAC7D,iBAAiB,GAAG,IAAI,CA0C1B"}
@@ -1,92 +0,0 @@
1
- /**
2
- * Video Frame Injector
3
- *
4
- * Creates a BeforeCaptureHook that replaces native <video> elements with
5
- * pre-extracted frame images during rendering. This is the Hyperframes-specific
6
- * video handling strategy — OSS users with different video pipelines can
7
- * provide their own hook or skip video injection entirely.
8
- */
9
- import { promises as fs } from "fs";
10
- import { injectVideoFramesBatch, syncVideoFrameVisibility } from "./screenshotService.js";
11
- import { DEFAULT_CONFIG } from "../config.js";
12
- function createFrameDataUriCache(cacheLimit) {
13
- const cache = new Map();
14
- const inFlight = new Map();
15
- function remember(framePath, dataUri) {
16
- if (cache.has(framePath)) {
17
- cache.delete(framePath);
18
- }
19
- cache.set(framePath, dataUri);
20
- if (cache.size > cacheLimit) {
21
- const oldestKey = cache.keys().next().value;
22
- if (oldestKey) {
23
- cache.delete(oldestKey);
24
- }
25
- }
26
- return dataUri;
27
- }
28
- async function get(framePath) {
29
- const cached = cache.get(framePath);
30
- if (cached) {
31
- remember(framePath, cached);
32
- return cached;
33
- }
34
- const existing = inFlight.get(framePath);
35
- if (existing) {
36
- return existing;
37
- }
38
- const pending = fs
39
- .readFile(framePath)
40
- .then((frameData) => {
41
- const mimeType = framePath.endsWith(".png") ? "image/png" : "image/jpeg";
42
- const dataUri = `data:${mimeType};base64,${frameData.toString("base64")}`;
43
- return remember(framePath, dataUri);
44
- })
45
- .finally(() => {
46
- inFlight.delete(framePath);
47
- });
48
- inFlight.set(framePath, pending);
49
- return pending;
50
- }
51
- return { get };
52
- }
53
- /**
54
- * Creates a BeforeCaptureHook that injects pre-extracted video frames
55
- * into the page, replacing native <video> elements with frame images.
56
- */
57
- export function createVideoFrameInjector(frameLookup, config) {
58
- if (!frameLookup)
59
- return null;
60
- const cacheLimit = Math.max(32, config?.frameDataUriCacheLimit ?? DEFAULT_CONFIG.frameDataUriCacheLimit);
61
- const frameCache = createFrameDataUriCache(cacheLimit);
62
- const lastInjectedFrameByVideo = new Map();
63
- return async (page, time) => {
64
- const activePayloads = frameLookup.getActiveFramePayloads(time);
65
- const updates = [];
66
- const activeIds = new Set();
67
- if (activePayloads.size > 0) {
68
- const pendingReads = [];
69
- for (const [videoId, payload] of activePayloads) {
70
- activeIds.add(videoId);
71
- const lastFrameIndex = lastInjectedFrameByVideo.get(videoId);
72
- if (lastFrameIndex === payload.frameIndex)
73
- continue;
74
- pendingReads.push(frameCache.get(payload.framePath).then((dataUri) => ({ videoId, dataUri, frameIndex: payload.frameIndex })));
75
- }
76
- updates.push(...(await Promise.all(pendingReads)));
77
- }
78
- for (const videoId of Array.from(lastInjectedFrameByVideo.keys())) {
79
- if (!activeIds.has(videoId)) {
80
- lastInjectedFrameByVideo.delete(videoId);
81
- }
82
- }
83
- await syncVideoFrameVisibility(page, Array.from(activeIds));
84
- if (updates.length > 0) {
85
- await injectVideoFramesBatch(page, updates.map((u) => ({ videoId: u.videoId, dataUri: u.dataUri })));
86
- for (const update of updates) {
87
- lastInjectedFrameByVideo.set(update.videoId, update.frameIndex);
88
- }
89
- }
90
- };
91
- }
92
- //# sourceMappingURL=videoFrameInjector.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"videoFrameInjector.js","sourceRoot":"","sources":["../../src/services/videoFrameInjector.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts DELETED
@@ -1,79 +0,0 @@
1
- /**
2
- * @hyperframes/engine — Protocol Types
3
- *
4
- * The engine's page contract. Any web page that wants to be rendered
5
- * as video must expose `window.__hf` implementing the HfProtocol interface.
6
- */
7
- /**
8
- * Declares a media element the engine should handle.
9
- *
10
- * Headless Chrome in BeginFrame mode cannot play <video> or produce audio.
11
- * The engine pre-extracts video frames and audio tracks from declared media
12
- * elements and handles injection/mixing automatically.
13
- */
14
- export interface HfMediaElement {
15
- /** DOM id of the <video> or <audio> element */
16
- elementId: string;
17
- /** Source file path or URL */
18
- src: string;
19
- /** When in the composition this element appears (seconds) */
20
- startTime: number;
21
- /** When in the composition this element disappears (seconds) */
22
- endTime: number;
23
- /** Offset into the source file (seconds, default: 0) */
24
- mediaOffset?: number;
25
- /** Audio volume 0-1 (default: 1) */
26
- volume?: number;
27
- /** Whether this element has audio that should be extracted */
28
- hasAudio?: boolean;
29
- }
30
- /**
31
- * The seek protocol. The only contract between the engine and a page.
32
- *
33
- * The engine reads `duration` to calculate total frames, calls `seek(time)`
34
- * before each frame capture, and uses `media` (if provided) to handle
35
- * video frame injection and audio mixing.
36
- *
37
- * The engine does NOT care what animation framework drives the page.
38
- * GSAP, Framer Motion, CSS animations, Three.js — anything works as long
39
- * as `seek()` produces deterministic visual output for a given time.
40
- */
41
- export interface HfProtocol {
42
- /** Total duration of the composition in seconds */
43
- duration: number;
44
- /** Seek to a specific time. Must produce deterministic visual output. */
45
- seek(time: number): void;
46
- /** Optional: media elements the engine should handle */
47
- media?: HfMediaElement[];
48
- }
49
- export interface CaptureOptions {
50
- width: number;
51
- height: number;
52
- fps: number;
53
- format?: "jpeg" | "png";
54
- quality?: number;
55
- deviceScaleFactor?: number;
56
- }
57
- export interface CaptureResult {
58
- frameIndex: number;
59
- time: number;
60
- path: string;
61
- captureTimeMs: number;
62
- }
63
- export interface CaptureBufferResult {
64
- buffer: Buffer;
65
- captureTimeMs: number;
66
- }
67
- export interface CapturePerfSummary {
68
- frames: number;
69
- avgTotalMs: number;
70
- avgSeekMs: number;
71
- avgBeforeCaptureMs: number;
72
- avgScreenshotMs: number;
73
- }
74
- declare global {
75
- interface Window {
76
- __hf?: HfProtocol;
77
- }
78
- }
79
- //# sourceMappingURL=types.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,8BAA8B;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,6DAA6D;IAC7D,SAAS,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,OAAO,EAAE,MAAM,CAAC;IAChB,wDAAwD;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oCAAoC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,UAAU;IACzB,mDAAmD;IACnD,QAAQ,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,wDAAwD;IACxD,KAAK,CAAC,EAAE,cAAc,EAAE,CAAC;CAC1B;AAID,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;CACzB;AAID,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,IAAI,CAAC,EAAE,UAAU,CAAC;KACnB;CACF"}
package/dist/types.js DELETED
@@ -1,8 +0,0 @@
1
- /**
2
- * @hyperframes/engine — Protocol Types
3
- *
4
- * The engine's page contract. Any web page that wants to be rendered
5
- * as video must expose `window.__hf` implementing the HfProtocol interface.
6
- */
7
- export {};
8
- //# sourceMappingURL=types.js.map
package/dist/types.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
@@ -1,18 +0,0 @@
1
- export interface VideoMetadata {
2
- durationSeconds: number;
3
- width: number;
4
- height: number;
5
- fps: number;
6
- videoCodec: string;
7
- hasAudio: boolean;
8
- }
9
- export interface AudioMetadata {
10
- durationSeconds: number;
11
- sampleRate: number;
12
- channels: number;
13
- audioCodec: string;
14
- bitrate?: number;
15
- }
16
- export declare function extractVideoMetadata(filePath: string): Promise<VideoMetadata>;
17
- export declare function extractAudioMetadata(filePath: string): Promise<AudioMetadata>;
18
- //# sourceMappingURL=ffprobe.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ffprobe.d.ts","sourceRoot":"","sources":["../../src/utils/ffprobe.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,aAAa;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAkCD,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAmEnF;AAED,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAoEnF"}