@studiomeyer/mcp-video 1.0.0
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/.github/ISSUE_TEMPLATE/bug_report.md +31 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +19 -0
- package/.github/workflows/ci.yml +34 -0
- package/CHANGELOG.md +24 -0
- package/CONTRIBUTING.md +75 -0
- package/LICENSE +21 -0
- package/README.md +198 -0
- package/USAGE.md +144 -0
- package/dist/handlers/capcut.d.ts +6 -0
- package/dist/handlers/capcut.js +229 -0
- package/dist/handlers/capcut.js.map +1 -0
- package/dist/handlers/editing.d.ts +6 -0
- package/dist/handlers/editing.js +242 -0
- package/dist/handlers/editing.js.map +1 -0
- package/dist/handlers/index.d.ts +2 -0
- package/dist/handlers/index.js +33 -0
- package/dist/handlers/index.js.map +1 -0
- package/dist/handlers/post-production.d.ts +5 -0
- package/dist/handlers/post-production.js +109 -0
- package/dist/handlers/post-production.js.map +1 -0
- package/dist/handlers/smart-screenshot.d.ts +5 -0
- package/dist/handlers/smart-screenshot.js +83 -0
- package/dist/handlers/smart-screenshot.js.map +1 -0
- package/dist/handlers/tts.d.ts +5 -0
- package/dist/handlers/tts.js +83 -0
- package/dist/handlers/tts.js.map +1 -0
- package/dist/handlers/video.d.ts +5 -0
- package/dist/handlers/video.js +127 -0
- package/dist/handlers/video.js.map +1 -0
- package/dist/lib/dual-transport.d.ts +42 -0
- package/dist/lib/dual-transport.js +208 -0
- package/dist/lib/dual-transport.js.map +1 -0
- package/dist/lib/logger.d.ts +12 -0
- package/dist/lib/logger.js +42 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/types.d.ts +16 -0
- package/dist/lib/types.js +15 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/schemas/capcut.d.ts +608 -0
- package/dist/schemas/capcut.js +411 -0
- package/dist/schemas/capcut.js.map +1 -0
- package/dist/schemas/editing.d.ts +822 -0
- package/dist/schemas/editing.js +466 -0
- package/dist/schemas/editing.js.map +1 -0
- package/dist/schemas/index.d.ts +2366 -0
- package/dist/schemas/index.js +15 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/post-production.d.ts +379 -0
- package/dist/schemas/post-production.js +268 -0
- package/dist/schemas/post-production.js.map +1 -0
- package/dist/schemas/smart-screenshot.d.ts +127 -0
- package/dist/schemas/smart-screenshot.js +122 -0
- package/dist/schemas/smart-screenshot.js.map +1 -0
- package/dist/schemas/tts.d.ts +220 -0
- package/dist/schemas/tts.js +194 -0
- package/dist/schemas/tts.js.map +1 -0
- package/dist/schemas/video.d.ts +236 -0
- package/dist/schemas/video.js +210 -0
- package/dist/schemas/video.js.map +1 -0
- package/dist/server.d.ts +11 -0
- package/dist/server.js +239 -0
- package/dist/server.js.map +1 -0
- package/dist/server.test.d.ts +1 -0
- package/dist/server.test.js +87 -0
- package/dist/server.test.js.map +1 -0
- package/dist/tools/engine/audio-mixer.d.ts +40 -0
- package/dist/tools/engine/audio-mixer.js +169 -0
- package/dist/tools/engine/audio-mixer.js.map +1 -0
- package/dist/tools/engine/audio.d.ts +22 -0
- package/dist/tools/engine/audio.js +73 -0
- package/dist/tools/engine/audio.js.map +1 -0
- package/dist/tools/engine/beat-sync.d.ts +31 -0
- package/dist/tools/engine/beat-sync.js +270 -0
- package/dist/tools/engine/beat-sync.js.map +1 -0
- package/dist/tools/engine/capture.d.ts +12 -0
- package/dist/tools/engine/capture.js +290 -0
- package/dist/tools/engine/capture.js.map +1 -0
- package/dist/tools/engine/chroma-key.d.ts +27 -0
- package/dist/tools/engine/chroma-key.js +154 -0
- package/dist/tools/engine/chroma-key.js.map +1 -0
- package/dist/tools/engine/concat.d.ts +49 -0
- package/dist/tools/engine/concat.js +149 -0
- package/dist/tools/engine/concat.js.map +1 -0
- package/dist/tools/engine/cursor.d.ts +26 -0
- package/dist/tools/engine/cursor.js +185 -0
- package/dist/tools/engine/cursor.js.map +1 -0
- package/dist/tools/engine/easing.d.ts +15 -0
- package/dist/tools/engine/easing.js +100 -0
- package/dist/tools/engine/easing.js.map +1 -0
- package/dist/tools/engine/editing.d.ts +158 -0
- package/dist/tools/engine/editing.js +541 -0
- package/dist/tools/engine/editing.js.map +1 -0
- package/dist/tools/engine/encoder.d.ts +31 -0
- package/dist/tools/engine/encoder.js +154 -0
- package/dist/tools/engine/encoder.js.map +1 -0
- package/dist/tools/engine/index.d.ts +30 -0
- package/dist/tools/engine/index.js +23 -0
- package/dist/tools/engine/index.js.map +1 -0
- package/dist/tools/engine/lut-presets.d.ts +25 -0
- package/dist/tools/engine/lut-presets.js +141 -0
- package/dist/tools/engine/lut-presets.js.map +1 -0
- package/dist/tools/engine/narrated-video.d.ts +63 -0
- package/dist/tools/engine/narrated-video.js +163 -0
- package/dist/tools/engine/narrated-video.js.map +1 -0
- package/dist/tools/engine/scenes.d.ts +17 -0
- package/dist/tools/engine/scenes.js +223 -0
- package/dist/tools/engine/scenes.js.map +1 -0
- package/dist/tools/engine/smart-screenshot.d.ts +80 -0
- package/dist/tools/engine/smart-screenshot.js +744 -0
- package/dist/tools/engine/smart-screenshot.js.map +1 -0
- package/dist/tools/engine/social-format.d.ts +66 -0
- package/dist/tools/engine/social-format.js +107 -0
- package/dist/tools/engine/social-format.js.map +1 -0
- package/dist/tools/engine/template-renderer.d.ts +45 -0
- package/dist/tools/engine/template-renderer.js +233 -0
- package/dist/tools/engine/template-renderer.js.map +1 -0
- package/dist/tools/engine/templates.d.ts +87 -0
- package/dist/tools/engine/templates.js +272 -0
- package/dist/tools/engine/templates.js.map +1 -0
- package/dist/tools/engine/text-animations.d.ts +33 -0
- package/dist/tools/engine/text-animations.js +192 -0
- package/dist/tools/engine/text-animations.js.map +1 -0
- package/dist/tools/engine/text-overlay.d.ts +27 -0
- package/dist/tools/engine/text-overlay.js +84 -0
- package/dist/tools/engine/text-overlay.js.map +1 -0
- package/dist/tools/engine/tts.d.ts +54 -0
- package/dist/tools/engine/tts.js +186 -0
- package/dist/tools/engine/tts.js.map +1 -0
- package/dist/tools/engine/types.d.ts +166 -0
- package/dist/tools/engine/types.js +13 -0
- package/dist/tools/engine/types.js.map +1 -0
- package/dist/tools/engine/voice-effects.d.ts +18 -0
- package/dist/tools/engine/voice-effects.js +215 -0
- package/dist/tools/engine/voice-effects.js.map +1 -0
- package/dist/tools/index.d.ts +32 -0
- package/dist/tools/index.js +23 -0
- package/dist/tools/index.js.map +1 -0
- package/package.json +56 -0
- package/scripts/check-deps.js +39 -0
- package/src/handlers/capcut.ts +245 -0
- package/src/handlers/editing.ts +260 -0
- package/src/handlers/index.ts +34 -0
- package/src/handlers/post-production.ts +136 -0
- package/src/handlers/smart-screenshot.ts +86 -0
- package/src/handlers/tts.ts +103 -0
- package/src/handlers/video.ts +137 -0
- package/src/lib/dual-transport.ts +272 -0
- package/src/lib/logger.ts +59 -0
- package/src/lib/types.ts +25 -0
- package/src/schemas/capcut.ts +418 -0
- package/src/schemas/editing.ts +476 -0
- package/src/schemas/index.ts +15 -0
- package/src/schemas/post-production.ts +273 -0
- package/src/schemas/smart-screenshot.ts +122 -0
- package/src/schemas/tts.ts +197 -0
- package/src/schemas/video.ts +211 -0
- package/src/server.test.ts +99 -0
- package/src/server.ts +289 -0
- package/src/tools/engine/audio-mixer.ts +244 -0
- package/src/tools/engine/audio.ts +115 -0
- package/src/tools/engine/beat-sync.ts +356 -0
- package/src/tools/engine/capture.ts +360 -0
- package/src/tools/engine/chroma-key.ts +202 -0
- package/src/tools/engine/concat.ts +242 -0
- package/src/tools/engine/cursor.ts +222 -0
- package/src/tools/engine/easing.ts +120 -0
- package/src/tools/engine/editing.ts +809 -0
- package/src/tools/engine/encoder.ts +208 -0
- package/src/tools/engine/index.ts +33 -0
- package/src/tools/engine/lut-presets.ts +235 -0
- package/src/tools/engine/narrated-video.ts +267 -0
- package/src/tools/engine/scenes.ts +309 -0
- package/src/tools/engine/smart-screenshot.ts +923 -0
- package/src/tools/engine/social-format.ts +146 -0
- package/src/tools/engine/template-renderer.ts +294 -0
- package/src/tools/engine/templates.ts +370 -0
- package/src/tools/engine/text-animations.ts +282 -0
- package/src/tools/engine/text-overlay.ts +143 -0
- package/src/tools/engine/tts.ts +284 -0
- package/src/tools/engine/types.ts +191 -0
- package/src/tools/engine/voice-effects.ts +258 -0
- package/src/tools/index.ts +67 -0
- package/tsconfig.json +19 -0
- package/vitest.config.ts +7 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scene execution engine — processes scene definitions into frame captures
|
|
3
|
+
*/
|
|
4
|
+
import type { Page } from 'playwright';
|
|
5
|
+
import type { Scene } from './types.js';
|
|
6
|
+
interface FrameCallback {
|
|
7
|
+
(frameIndex: number): Promise<void>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Execute all scenes and capture frames
|
|
11
|
+
*/
|
|
12
|
+
export declare function executeScenes(page: Page, scenes: Scene[], fps: number, captureFrame: FrameCallback, cursorEnabled: boolean): Promise<number>;
|
|
13
|
+
/**
|
|
14
|
+
* Create default scenes for a simple scroll-through video
|
|
15
|
+
*/
|
|
16
|
+
export declare function createDefaultScenes(scrollDuration?: number): Scene[];
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scene execution engine — processes scene definitions into frame captures
|
|
3
|
+
*/
|
|
4
|
+
import { applyEasing } from './easing.js';
|
|
5
|
+
import { moveCursorToElement, animateClick } from './cursor.js';
|
|
6
|
+
import { logger } from '../../lib/logger.js';
|
|
7
|
+
/**
|
|
8
|
+
* Execute all scenes and capture frames
|
|
9
|
+
*/
|
|
10
|
+
export async function executeScenes(page, scenes, fps, captureFrame, cursorEnabled) {
|
|
11
|
+
let totalFramesCaptured = 0;
|
|
12
|
+
for (let i = 0; i < scenes.length; i++) {
|
|
13
|
+
const scene = scenes[i];
|
|
14
|
+
logger.info(`Scene ${i + 1}/${scenes.length}: ${scene.type}`);
|
|
15
|
+
let framesInScene = 0;
|
|
16
|
+
switch (scene.type) {
|
|
17
|
+
case 'scroll':
|
|
18
|
+
framesInScene = await executeScrollScene(page, scene, fps, async (fi) => {
|
|
19
|
+
await captureFrame(totalFramesCaptured + fi);
|
|
20
|
+
});
|
|
21
|
+
break;
|
|
22
|
+
case 'pause':
|
|
23
|
+
framesInScene = await executePauseScene(page, scene.duration, fps, async (fi) => {
|
|
24
|
+
await captureFrame(totalFramesCaptured + fi);
|
|
25
|
+
});
|
|
26
|
+
break;
|
|
27
|
+
case 'hover':
|
|
28
|
+
framesInScene = await executeHoverScene(page, scene, fps, cursorEnabled, async (fi) => {
|
|
29
|
+
await captureFrame(totalFramesCaptured + fi);
|
|
30
|
+
});
|
|
31
|
+
break;
|
|
32
|
+
case 'click':
|
|
33
|
+
framesInScene = await executeClickScene(page, scene, fps, cursorEnabled, async (fi) => {
|
|
34
|
+
await captureFrame(totalFramesCaptured + fi);
|
|
35
|
+
});
|
|
36
|
+
break;
|
|
37
|
+
case 'type':
|
|
38
|
+
framesInScene = await executeTypeScene(page, scene, fps, async (fi) => {
|
|
39
|
+
await captureFrame(totalFramesCaptured + fi);
|
|
40
|
+
});
|
|
41
|
+
break;
|
|
42
|
+
case 'wait':
|
|
43
|
+
framesInScene = await executeWaitScene(page, scene, fps, async (fi) => {
|
|
44
|
+
await captureFrame(totalFramesCaptured + fi);
|
|
45
|
+
});
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
totalFramesCaptured += framesInScene;
|
|
49
|
+
logger.debug(`Scene ${i + 1} captured ${framesInScene} frames (total: ${totalFramesCaptured})`);
|
|
50
|
+
}
|
|
51
|
+
return totalFramesCaptured;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Execute a scroll scene — the core of cinema-quality videos
|
|
55
|
+
*/
|
|
56
|
+
async function executeScrollScene(page, scene, fps, captureFrame) {
|
|
57
|
+
const easingName = scene.easing ?? 'easeInOutCubic';
|
|
58
|
+
const totalFrames = Math.ceil(scene.duration * fps);
|
|
59
|
+
// Resolve scroll target
|
|
60
|
+
const scrollInfo = await page.evaluate((target) => {
|
|
61
|
+
const docHeight = document.documentElement.scrollHeight;
|
|
62
|
+
const viewportHeight = window.innerHeight;
|
|
63
|
+
const currentScroll = window.scrollY;
|
|
64
|
+
const maxScroll = Math.max(0, docHeight - viewportHeight);
|
|
65
|
+
if (target === 'bottom')
|
|
66
|
+
return { from: currentScroll, to: maxScroll };
|
|
67
|
+
if (target === 'top')
|
|
68
|
+
return { from: currentScroll, to: 0 };
|
|
69
|
+
if (typeof target === 'number')
|
|
70
|
+
return { from: currentScroll, to: Math.min(target, maxScroll) };
|
|
71
|
+
// CSS selector — scroll to element
|
|
72
|
+
const el = document.querySelector(target);
|
|
73
|
+
if (el) {
|
|
74
|
+
const rect = el.getBoundingClientRect();
|
|
75
|
+
const targetY = Math.min(currentScroll + rect.top - 100, maxScroll);
|
|
76
|
+
return { from: currentScroll, to: targetY };
|
|
77
|
+
}
|
|
78
|
+
return { from: currentScroll, to: maxScroll };
|
|
79
|
+
}, scene.to);
|
|
80
|
+
const scrollDistance = scrollInfo.to - scrollInfo.from;
|
|
81
|
+
for (let frame = 0; frame <= totalFrames; frame++) {
|
|
82
|
+
const progress = frame / totalFrames;
|
|
83
|
+
const easedScroll = scrollInfo.from + applyEasing(progress, scrollDistance, easingName);
|
|
84
|
+
await page.evaluate((y) => window.scrollTo(0, y), easedScroll);
|
|
85
|
+
// Small delay to let scroll-triggered animations render
|
|
86
|
+
await page.waitForTimeout(8);
|
|
87
|
+
await captureFrame(frame);
|
|
88
|
+
}
|
|
89
|
+
return totalFrames + 1;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Execute a pause scene — captures static frames
|
|
93
|
+
*/
|
|
94
|
+
async function executePauseScene(_page, duration, fps, captureFrame) {
|
|
95
|
+
const totalFrames = Math.ceil(duration * fps);
|
|
96
|
+
for (let frame = 0; frame < totalFrames; frame++) {
|
|
97
|
+
await captureFrame(frame);
|
|
98
|
+
}
|
|
99
|
+
return totalFrames;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Execute a hover scene — move cursor to element and hold
|
|
103
|
+
*/
|
|
104
|
+
async function executeHoverScene(page, scene, fps, cursorEnabled, captureFrame) {
|
|
105
|
+
let frameCount = 0;
|
|
106
|
+
// Move cursor to element (animated)
|
|
107
|
+
if (cursorEnabled && scene.animateCursor !== false) {
|
|
108
|
+
const moveDuration = 600; // ms
|
|
109
|
+
const moveFrames = Math.ceil((moveDuration / 1000) * fps);
|
|
110
|
+
await moveCursorToElement(page, scene.selector, moveDuration, fps);
|
|
111
|
+
// Capture frames during cursor movement — take snapshots
|
|
112
|
+
for (let i = 0; i < moveFrames; i++) {
|
|
113
|
+
await captureFrame(frameCount++);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
// Instant hover
|
|
118
|
+
const pos = await page.evaluate((sel) => {
|
|
119
|
+
const el = document.querySelector(sel);
|
|
120
|
+
if (!el)
|
|
121
|
+
return null;
|
|
122
|
+
const rect = el.getBoundingClientRect();
|
|
123
|
+
return { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 };
|
|
124
|
+
}, scene.selector);
|
|
125
|
+
if (pos) {
|
|
126
|
+
await page.mouse.move(pos.x, pos.y);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// Hold hover — capture frames
|
|
130
|
+
const holdFrames = Math.ceil(scene.duration * fps);
|
|
131
|
+
for (let i = 0; i < holdFrames; i++) {
|
|
132
|
+
await captureFrame(frameCount++);
|
|
133
|
+
}
|
|
134
|
+
return frameCount;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Execute a click scene
|
|
138
|
+
*/
|
|
139
|
+
async function executeClickScene(page, scene, fps, cursorEnabled, captureFrame) {
|
|
140
|
+
let frameCount = 0;
|
|
141
|
+
// Move cursor to element
|
|
142
|
+
if (cursorEnabled) {
|
|
143
|
+
const moveFrames = Math.ceil(0.5 * fps);
|
|
144
|
+
await moveCursorToElement(page, scene.selector, 500, fps);
|
|
145
|
+
for (let i = 0; i < moveFrames; i++) {
|
|
146
|
+
await captureFrame(frameCount++);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
// Click animation
|
|
150
|
+
if (cursorEnabled) {
|
|
151
|
+
await animateClick(page);
|
|
152
|
+
}
|
|
153
|
+
// Actual click
|
|
154
|
+
await page.click(scene.selector);
|
|
155
|
+
// Wait for navigation/content
|
|
156
|
+
if (scene.waitFor === 'networkidle') {
|
|
157
|
+
await page.waitForLoadState('networkidle').catch(() => { });
|
|
158
|
+
}
|
|
159
|
+
else if (scene.waitFor === 'load') {
|
|
160
|
+
await page.waitForLoadState('load').catch(() => { });
|
|
161
|
+
}
|
|
162
|
+
else if (typeof scene.waitFor === 'number') {
|
|
163
|
+
await page.waitForTimeout(scene.waitFor);
|
|
164
|
+
}
|
|
165
|
+
// Pause after click
|
|
166
|
+
const pauseDuration = scene.pauseAfter ?? 1;
|
|
167
|
+
const pauseFrames = Math.ceil(pauseDuration * fps);
|
|
168
|
+
for (let i = 0; i < pauseFrames; i++) {
|
|
169
|
+
await captureFrame(frameCount++);
|
|
170
|
+
}
|
|
171
|
+
return frameCount;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Execute a type scene
|
|
175
|
+
*/
|
|
176
|
+
async function executeTypeScene(page, scene, fps, captureFrame) {
|
|
177
|
+
let frameCount = 0;
|
|
178
|
+
const delay = scene.delay ?? 80;
|
|
179
|
+
const framesPerKeystroke = Math.max(1, Math.ceil((delay / 1000) * fps));
|
|
180
|
+
// Focus the input
|
|
181
|
+
await page.click(scene.selector);
|
|
182
|
+
await captureFrame(frameCount++);
|
|
183
|
+
// Type character by character
|
|
184
|
+
for (const char of scene.text) {
|
|
185
|
+
await page.keyboard.type(char, { delay: 0 });
|
|
186
|
+
for (let i = 0; i < framesPerKeystroke; i++) {
|
|
187
|
+
await captureFrame(frameCount++);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return frameCount;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Execute a wait scene — wait for selector, capturing frames
|
|
194
|
+
*/
|
|
195
|
+
async function executeWaitScene(page, scene, fps, captureFrame) {
|
|
196
|
+
const timeout = scene.timeout ?? 5000;
|
|
197
|
+
const maxFrames = Math.ceil((timeout / 1000) * fps);
|
|
198
|
+
let frameCount = 0;
|
|
199
|
+
const waitPromise = page.waitForSelector(scene.selector, { timeout }).catch(() => null);
|
|
200
|
+
// Capture frames while waiting
|
|
201
|
+
const startTime = Date.now();
|
|
202
|
+
while (Date.now() - startTime < timeout && frameCount < maxFrames) {
|
|
203
|
+
await captureFrame(frameCount++);
|
|
204
|
+
await page.waitForTimeout(Math.floor(1000 / fps));
|
|
205
|
+
// Check if element appeared
|
|
206
|
+
const found = await page.$(scene.selector);
|
|
207
|
+
if (found)
|
|
208
|
+
break;
|
|
209
|
+
}
|
|
210
|
+
await waitPromise;
|
|
211
|
+
return frameCount;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Create default scenes for a simple scroll-through video
|
|
215
|
+
*/
|
|
216
|
+
export function createDefaultScenes(scrollDuration = 18) {
|
|
217
|
+
return [
|
|
218
|
+
{ type: 'pause', duration: 1.5 },
|
|
219
|
+
{ type: 'scroll', to: 'bottom', duration: scrollDuration, easing: 'showcase' },
|
|
220
|
+
{ type: 'pause', duration: 2 },
|
|
221
|
+
];
|
|
222
|
+
}
|
|
223
|
+
//# sourceMappingURL=scenes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scenes.js","sourceRoot":"","sources":["../../../src/tools/engine/scenes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Smart Screenshot Engine
|
|
3
|
+
*
|
|
4
|
+
* Element-aware screenshot system that can target specific page features.
|
|
5
|
+
* Instead of full-page screenshots, this finds and captures specific UI elements
|
|
6
|
+
* like chat widgets, booking forms, pricing sections, wizards, etc.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* smartScreenshot({ url: '...', targets: ['chat', 'pricing', 'booking'] })
|
|
10
|
+
* smartScreenshot({ url: '...', targets: [{ selector: '.hero-section' }] })
|
|
11
|
+
* smartScreenshot({ url: '...', targets: ['all'] }) // auto-detect all features
|
|
12
|
+
*/
|
|
13
|
+
export interface SmartTarget {
|
|
14
|
+
/** Feature keyword (e.g. "chat", "pricing") or CSS selector (prefixed with .) or "all" for auto-detect */
|
|
15
|
+
feature: string;
|
|
16
|
+
/** Optional: custom CSS selector override */
|
|
17
|
+
selector?: string;
|
|
18
|
+
/** Optional: custom padding around element */
|
|
19
|
+
padding?: number;
|
|
20
|
+
/** Optional: click to reveal before screenshot */
|
|
21
|
+
revealFirst?: boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface SmartScreenshotConfig {
|
|
24
|
+
/** URL to screenshot */
|
|
25
|
+
url: string;
|
|
26
|
+
/** What to capture - keywords, selectors, or "all" */
|
|
27
|
+
targets: (string | SmartTarget)[];
|
|
28
|
+
/** Output directory */
|
|
29
|
+
outputDir?: string;
|
|
30
|
+
/** Viewport size */
|
|
31
|
+
viewport?: {
|
|
32
|
+
width: number;
|
|
33
|
+
height: number;
|
|
34
|
+
};
|
|
35
|
+
/** Device scale factor for retina */
|
|
36
|
+
deviceScaleFactor?: number;
|
|
37
|
+
/** Dark mode */
|
|
38
|
+
darkMode?: boolean;
|
|
39
|
+
/** Wait time after page load (ms) */
|
|
40
|
+
waitAfterLoad?: number;
|
|
41
|
+
/** Also take a full-page screenshot */
|
|
42
|
+
includeFullPage?: boolean;
|
|
43
|
+
/** Maximum width for element screenshots (prevents ultra-wide captures) */
|
|
44
|
+
maxWidth?: number;
|
|
45
|
+
/** Maximum height for element screenshots */
|
|
46
|
+
maxHeight?: number;
|
|
47
|
+
}
|
|
48
|
+
export interface DetectedFeature {
|
|
49
|
+
name: string;
|
|
50
|
+
pattern: string;
|
|
51
|
+
selector: string;
|
|
52
|
+
bounds: {
|
|
53
|
+
x: number;
|
|
54
|
+
y: number;
|
|
55
|
+
width: number;
|
|
56
|
+
height: number;
|
|
57
|
+
};
|
|
58
|
+
matchMethod: 'selector' | 'text' | 'aria' | 'custom';
|
|
59
|
+
confidence: 'high' | 'medium' | 'low';
|
|
60
|
+
}
|
|
61
|
+
export interface SmartScreenshotResult {
|
|
62
|
+
success: boolean;
|
|
63
|
+
url: string;
|
|
64
|
+
screenshots: {
|
|
65
|
+
feature: string;
|
|
66
|
+
path: string;
|
|
67
|
+
bounds: {
|
|
68
|
+
x: number;
|
|
69
|
+
y: number;
|
|
70
|
+
width: number;
|
|
71
|
+
height: number;
|
|
72
|
+
};
|
|
73
|
+
matchMethod: string;
|
|
74
|
+
confidence: string;
|
|
75
|
+
}[];
|
|
76
|
+
detected: DetectedFeature[];
|
|
77
|
+
fullPage?: string;
|
|
78
|
+
totalTime: string;
|
|
79
|
+
}
|
|
80
|
+
export declare function smartScreenshot(config: SmartScreenshotConfig): Promise<SmartScreenshotResult>;
|