node-mac-recorder 1.1.0 ā 1.2.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/README.md +153 -0
- package/binding.gyp +6 -2
- package/cursor-test.js +176 -0
- package/index.js +90 -0
- package/manual-cursor-data.json +352 -0
- package/package.json +1 -1
- package/src/cursor_tracker.mm +399 -0
- package/src/mac_recorder.mm +6 -0
- package/preview-test.js +0 -329
package/preview-test.js
DELETED
|
@@ -1,329 +0,0 @@
|
|
|
1
|
-
const MacRecorder = require("./index.js");
|
|
2
|
-
const fs = require("fs");
|
|
3
|
-
|
|
4
|
-
async function testPreviews() {
|
|
5
|
-
const recorder = new MacRecorder();
|
|
6
|
-
|
|
7
|
-
console.log("š¼ļø Thumbnail Preview Test\n");
|
|
8
|
-
|
|
9
|
-
try {
|
|
10
|
-
// 1. Display Previews
|
|
11
|
-
console.log("šŗ Display Thumbnails Test...");
|
|
12
|
-
const displays = await recorder.getDisplays();
|
|
13
|
-
|
|
14
|
-
console.log(`Found ${displays.length} displays:`);
|
|
15
|
-
for (let i = 0; i < displays.length; i++) {
|
|
16
|
-
const display = displays[i];
|
|
17
|
-
console.log(
|
|
18
|
-
` Display ${i}: ${display.resolution} ${
|
|
19
|
-
display.isPrimary ? "(Primary)" : ""
|
|
20
|
-
}`
|
|
21
|
-
);
|
|
22
|
-
|
|
23
|
-
try {
|
|
24
|
-
console.log(` šø Capturing thumbnail...`);
|
|
25
|
-
const thumbnail = await recorder.getDisplayThumbnail(display.id, {
|
|
26
|
-
maxWidth: 300,
|
|
27
|
-
maxHeight: 200,
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
console.log(` ā
Success: ${thumbnail.length} chars`);
|
|
31
|
-
|
|
32
|
-
// Save as HTML file to view
|
|
33
|
-
const htmlContent = `
|
|
34
|
-
<!DOCTYPE html>
|
|
35
|
-
<html>
|
|
36
|
-
<head>
|
|
37
|
-
<title>Display ${i} Preview</title>
|
|
38
|
-
<style>
|
|
39
|
-
body {
|
|
40
|
-
font-family: Arial, sans-serif;
|
|
41
|
-
text-align: center;
|
|
42
|
-
padding: 20px;
|
|
43
|
-
background: #f5f5f5;
|
|
44
|
-
}
|
|
45
|
-
.preview-card {
|
|
46
|
-
background: white;
|
|
47
|
-
padding: 20px;
|
|
48
|
-
border-radius: 12px;
|
|
49
|
-
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
|
|
50
|
-
max-width: 400px;
|
|
51
|
-
margin: 0 auto;
|
|
52
|
-
}
|
|
53
|
-
img {
|
|
54
|
-
border: 2px solid #007AFF;
|
|
55
|
-
border-radius: 8px;
|
|
56
|
-
max-width: 100%;
|
|
57
|
-
}
|
|
58
|
-
.info {
|
|
59
|
-
background: #f0f0f0;
|
|
60
|
-
padding: 15px;
|
|
61
|
-
border-radius: 8px;
|
|
62
|
-
margin: 15px 0;
|
|
63
|
-
text-align: left;
|
|
64
|
-
}
|
|
65
|
-
h1 { color: #007AFF; }
|
|
66
|
-
</style>
|
|
67
|
-
</head>
|
|
68
|
-
<body>
|
|
69
|
-
<div class="preview-card">
|
|
70
|
-
<h1>šŗ Display ${i} Preview</h1>
|
|
71
|
-
<div class="info">
|
|
72
|
-
<strong>Resolution:</strong> ${display.resolution}<br>
|
|
73
|
-
<strong>Position:</strong> (${display.x}, ${display.y})<br>
|
|
74
|
-
<strong>Primary:</strong> ${display.isPrimary ? "Yes" : "No"}<br>
|
|
75
|
-
<strong>Display ID:</strong> ${display.id}
|
|
76
|
-
</div>
|
|
77
|
-
<img src="${thumbnail}" alt="Display ${i} Preview" />
|
|
78
|
-
<p><small>Captured: ${new Date().toLocaleString()}</small></p>
|
|
79
|
-
</div>
|
|
80
|
-
</body>
|
|
81
|
-
</html>`;
|
|
82
|
-
|
|
83
|
-
fs.writeFileSync(`display-${i}-preview.html`, htmlContent);
|
|
84
|
-
console.log(` š¾ Saved: display-${i}-preview.html\n`);
|
|
85
|
-
} catch (error) {
|
|
86
|
-
console.log(` ā Failed: ${error.message}\n`);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// 2. Window Previews
|
|
91
|
-
console.log("šŖ Window Thumbnails Test...");
|
|
92
|
-
const windows = await recorder.getWindows();
|
|
93
|
-
|
|
94
|
-
// Test first 3 windows
|
|
95
|
-
const testWindows = windows.slice(0, 3);
|
|
96
|
-
console.log(`Testing ${testWindows.length} windows:`);
|
|
97
|
-
|
|
98
|
-
for (let i = 0; i < testWindows.length; i++) {
|
|
99
|
-
const window = testWindows[i];
|
|
100
|
-
console.log(` Window ${i}: [${window.appName}] ${window.name}`);
|
|
101
|
-
console.log(` Size: ${window.width}x${window.height}`);
|
|
102
|
-
|
|
103
|
-
try {
|
|
104
|
-
console.log(` šø Capturing thumbnail...`);
|
|
105
|
-
const thumbnail = await recorder.getWindowThumbnail(window.id, {
|
|
106
|
-
maxWidth: 300,
|
|
107
|
-
maxHeight: 200,
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
console.log(` ā
Success: ${thumbnail.length} chars`);
|
|
111
|
-
|
|
112
|
-
// Save as HTML file to view
|
|
113
|
-
const htmlContent = `
|
|
114
|
-
<!DOCTYPE html>
|
|
115
|
-
<html>
|
|
116
|
-
<head>
|
|
117
|
-
<title>${window.appName} Preview</title>
|
|
118
|
-
<style>
|
|
119
|
-
body {
|
|
120
|
-
font-family: Arial, sans-serif;
|
|
121
|
-
text-align: center;
|
|
122
|
-
padding: 20px;
|
|
123
|
-
background: #f5f5f5;
|
|
124
|
-
}
|
|
125
|
-
.preview-card {
|
|
126
|
-
background: white;
|
|
127
|
-
padding: 20px;
|
|
128
|
-
border-radius: 12px;
|
|
129
|
-
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
|
|
130
|
-
max-width: 400px;
|
|
131
|
-
margin: 0 auto;
|
|
132
|
-
}
|
|
133
|
-
img {
|
|
134
|
-
border: 2px solid #FF3B30;
|
|
135
|
-
border-radius: 8px;
|
|
136
|
-
max-width: 100%;
|
|
137
|
-
}
|
|
138
|
-
.info {
|
|
139
|
-
background: #f0f0f0;
|
|
140
|
-
padding: 15px;
|
|
141
|
-
border-radius: 8px;
|
|
142
|
-
margin: 15px 0;
|
|
143
|
-
text-align: left;
|
|
144
|
-
}
|
|
145
|
-
h1 { color: #FF3B30; }
|
|
146
|
-
.app-name { color: #007AFF; font-weight: bold; }
|
|
147
|
-
</style>
|
|
148
|
-
</head>
|
|
149
|
-
<body>
|
|
150
|
-
<div class="preview-card">
|
|
151
|
-
<h1>šŖ <span class="app-name">${window.appName}</span></h1>
|
|
152
|
-
<div class="info">
|
|
153
|
-
<strong>Window:</strong> ${window.name}<br>
|
|
154
|
-
<strong>Size:</strong> ${window.width}x${window.height}<br>
|
|
155
|
-
<strong>Position:</strong> (${window.x}, ${window.y})<br>
|
|
156
|
-
<strong>Window ID:</strong> ${window.id}
|
|
157
|
-
</div>
|
|
158
|
-
<img src="${thumbnail}" alt="${window.appName} Preview" />
|
|
159
|
-
<p><small>Captured: ${new Date().toLocaleString()}</small></p>
|
|
160
|
-
</div>
|
|
161
|
-
</body>
|
|
162
|
-
</html>`;
|
|
163
|
-
|
|
164
|
-
const fileName = `window-${window.appName.replace(
|
|
165
|
-
/[^a-zA-Z0-9]/g,
|
|
166
|
-
""
|
|
167
|
-
)}-${i}-preview.html`;
|
|
168
|
-
fs.writeFileSync(fileName, htmlContent);
|
|
169
|
-
console.log(` š¾ Saved: ${fileName}\n`);
|
|
170
|
-
} catch (error) {
|
|
171
|
-
console.log(` ā Failed: ${error.message}\n`);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
// 3. Create Gallery
|
|
176
|
-
console.log("šØ Creating Preview Gallery...");
|
|
177
|
-
const previewFiles = fs
|
|
178
|
-
.readdirSync(".")
|
|
179
|
-
.filter((file) => file.endsWith("-preview.html"))
|
|
180
|
-
.sort();
|
|
181
|
-
|
|
182
|
-
if (previewFiles.length > 0) {
|
|
183
|
-
const galleryContent = `
|
|
184
|
-
<!DOCTYPE html>
|
|
185
|
-
<html>
|
|
186
|
-
<head>
|
|
187
|
-
<title>šø Thumbnail Preview Gallery</title>
|
|
188
|
-
<style>
|
|
189
|
-
body {
|
|
190
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
191
|
-
padding: 20px;
|
|
192
|
-
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
193
|
-
color: white;
|
|
194
|
-
min-height: 100vh;
|
|
195
|
-
}
|
|
196
|
-
.header {
|
|
197
|
-
text-align: center;
|
|
198
|
-
margin-bottom: 30px;
|
|
199
|
-
}
|
|
200
|
-
.gallery {
|
|
201
|
-
display: grid;
|
|
202
|
-
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
|
|
203
|
-
gap: 20px;
|
|
204
|
-
margin-top: 20px;
|
|
205
|
-
}
|
|
206
|
-
.preview-card {
|
|
207
|
-
background: rgba(255,255,255,0.1);
|
|
208
|
-
border-radius: 16px;
|
|
209
|
-
overflow: hidden;
|
|
210
|
-
backdrop-filter: blur(10px);
|
|
211
|
-
border: 1px solid rgba(255,255,255,0.2);
|
|
212
|
-
transition: transform 0.3s ease;
|
|
213
|
-
}
|
|
214
|
-
.preview-card:hover {
|
|
215
|
-
transform: translateY(-8px);
|
|
216
|
-
}
|
|
217
|
-
.card-header {
|
|
218
|
-
padding: 20px;
|
|
219
|
-
border-bottom: 1px solid rgba(255,255,255,0.1);
|
|
220
|
-
}
|
|
221
|
-
.card-title {
|
|
222
|
-
margin: 0;
|
|
223
|
-
font-size: 18px;
|
|
224
|
-
font-weight: 600;
|
|
225
|
-
}
|
|
226
|
-
.card-subtitle {
|
|
227
|
-
margin: 8px 0 0 0;
|
|
228
|
-
opacity: 0.8;
|
|
229
|
-
font-size: 14px;
|
|
230
|
-
}
|
|
231
|
-
iframe {
|
|
232
|
-
width: 100%;
|
|
233
|
-
height: 400px;
|
|
234
|
-
border: none;
|
|
235
|
-
background: white;
|
|
236
|
-
}
|
|
237
|
-
.stats {
|
|
238
|
-
background: rgba(255,255,255,0.2);
|
|
239
|
-
padding: 20px;
|
|
240
|
-
border-radius: 12px;
|
|
241
|
-
text-align: center;
|
|
242
|
-
margin-bottom: 30px;
|
|
243
|
-
backdrop-filter: blur(10px);
|
|
244
|
-
}
|
|
245
|
-
.btn {
|
|
246
|
-
background: rgba(255,255,255,0.2);
|
|
247
|
-
color: white;
|
|
248
|
-
padding: 10px 20px;
|
|
249
|
-
border: none;
|
|
250
|
-
border-radius: 8px;
|
|
251
|
-
cursor: pointer;
|
|
252
|
-
margin: 5px;
|
|
253
|
-
text-decoration: none;
|
|
254
|
-
display: inline-block;
|
|
255
|
-
transition: all 0.3s ease;
|
|
256
|
-
}
|
|
257
|
-
.btn:hover {
|
|
258
|
-
background: rgba(255,255,255,0.3);
|
|
259
|
-
transform: translateY(-2px);
|
|
260
|
-
}
|
|
261
|
-
</style>
|
|
262
|
-
</head>
|
|
263
|
-
<body>
|
|
264
|
-
<div class="header">
|
|
265
|
-
<h1>šø macOS Thumbnail Preview Gallery</h1>
|
|
266
|
-
<p>Screen and window thumbnails generated with node-mac-recorder</p>
|
|
267
|
-
</div>
|
|
268
|
-
|
|
269
|
-
<div class="stats">
|
|
270
|
-
<strong>${previewFiles.length}</strong> Thumbnails Generated<br>
|
|
271
|
-
<small>Created at ${new Date().toLocaleString()}</small>
|
|
272
|
-
</div>
|
|
273
|
-
|
|
274
|
-
<div style="text-align: center; margin-bottom: 20px;">
|
|
275
|
-
${previewFiles
|
|
276
|
-
.map(
|
|
277
|
-
(file) =>
|
|
278
|
-
`<a href="${file}" class="btn" target="_blank">${file
|
|
279
|
-
.replace("-preview.html", "")
|
|
280
|
-
.replace(/-/g, " ")}</a>`
|
|
281
|
-
)
|
|
282
|
-
.join("")}
|
|
283
|
-
</div>
|
|
284
|
-
|
|
285
|
-
<div class="gallery">
|
|
286
|
-
${previewFiles
|
|
287
|
-
.map(
|
|
288
|
-
(file) => `
|
|
289
|
-
<div class="preview-card">
|
|
290
|
-
<div class="card-header">
|
|
291
|
-
<h3 class="card-title">${file
|
|
292
|
-
.replace("-preview.html", "")
|
|
293
|
-
.replace(/-/g, " ")
|
|
294
|
-
.toUpperCase()}</h3>
|
|
295
|
-
<p class="card-subtitle">${file}</p>
|
|
296
|
-
</div>
|
|
297
|
-
<iframe src="${file}"></iframe>
|
|
298
|
-
</div>
|
|
299
|
-
`
|
|
300
|
-
)
|
|
301
|
-
.join("")}
|
|
302
|
-
</div>
|
|
303
|
-
|
|
304
|
-
<div style="text-align: center; margin-top: 40px; opacity: 0.8;">
|
|
305
|
-
<p>š Generated with <strong>node-mac-recorder v1.1.0</strong></p>
|
|
306
|
-
</div>
|
|
307
|
-
</body>
|
|
308
|
-
</html>`;
|
|
309
|
-
|
|
310
|
-
fs.writeFileSync("preview-gallery.html", galleryContent);
|
|
311
|
-
console.log(`ā
Gallery created: preview-gallery.html`);
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
console.log("\nš Preview Test Completed!");
|
|
315
|
-
console.log("\nš Generated Files:");
|
|
316
|
-
previewFiles.forEach((file) => console.log(` - ${file}`));
|
|
317
|
-
console.log(" - preview-gallery.html (main gallery)");
|
|
318
|
-
|
|
319
|
-
console.log("\nš View Results:");
|
|
320
|
-
console.log(" open preview-gallery.html");
|
|
321
|
-
console.log("\nš” Individual files can be opened directly in browser!");
|
|
322
|
-
} catch (error) {
|
|
323
|
-
console.error("ā Preview test failed:", error.message);
|
|
324
|
-
console.error(error.stack);
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
// Run preview test
|
|
329
|
-
testPreviews();
|