node-mac-recorder 2.4.11 → 2.4.13
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/binding.gyp +5 -12
- package/index.js +25 -104
- package/install.js +2 -19
- package/package.json +2 -6
- package/src/audio_capture.mm +40 -96
- package/src/cursor_tracker.mm +4 -3
- package/src/mac_recorder.mm +673 -753
- package/src/screen_capture.h +0 -5
- package/src/screen_capture.mm +60 -139
- package/src/window_selector.mm +113 -399
- package/window-selector.js +34 -112
- package/ELECTRON-INTEGRATION.md +0 -710
- package/WINDOW_SELECTOR_USAGE.md +0 -447
- package/backup/binding.gyp +0 -44
- package/backup/src/audio_capture.mm +0 -116
- package/backup/src/cursor_tracker.mm +0 -518
- package/backup/src/mac_recorder.mm +0 -829
- package/backup/src/screen_capture.h +0 -19
- package/backup/src/screen_capture.mm +0 -162
- package/backup/src/screen_capture_kit.h +0 -15
- package/backup/src/window_selector.mm +0 -1457
- package/electron-window-selector.js +0 -698
- package/node-mac-recorder-2.4.2.tgz +0 -0
- package/prebuilds/darwin-arm64/node.napi.node +0 -0
- package/test-api-compatibility.js +0 -92
- package/test-audio.js +0 -94
- package/test-comprehensive.js +0 -164
- package/test-electron-window-selector.js +0 -119
- package/test-overlay-fix.js +0 -72
- package/test-recording.js +0 -142
- package/test-sck-availability.js +0 -26
- package/test-sck-simple.js +0 -37
- package/test-sck.js +0 -56
- package/test-screencapture-overlay.js +0 -54
- package/test-simple-windows.js +0 -29
- package/test-sync.js +0 -52
- package/test-window-details.js +0 -34
- package/test-windows.js +0 -57
package/window-selector.js
CHANGED
|
@@ -1,27 +1,19 @@
|
|
|
1
1
|
const { EventEmitter } = require("events");
|
|
2
2
|
const path = require("path");
|
|
3
3
|
|
|
4
|
-
// Native modülü yükle
|
|
4
|
+
// Native modülü yükle
|
|
5
5
|
let nativeBinding;
|
|
6
6
|
try {
|
|
7
|
-
|
|
8
|
-
nativeBinding = require("./prebuilds/darwin-arm64/node.napi.node");
|
|
9
|
-
} else {
|
|
10
|
-
nativeBinding = require("./build/Release/mac_recorder.node");
|
|
11
|
-
}
|
|
7
|
+
nativeBinding = require("./build/Release/mac_recorder.node");
|
|
12
8
|
} catch (error) {
|
|
13
9
|
try {
|
|
14
|
-
nativeBinding = require("./build/
|
|
15
|
-
} catch (
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"Original error: " +
|
|
22
|
-
error.message
|
|
23
|
-
);
|
|
24
|
-
}
|
|
10
|
+
nativeBinding = require("./build/Debug/mac_recorder.node");
|
|
11
|
+
} catch (debugError) {
|
|
12
|
+
throw new Error(
|
|
13
|
+
'Native module not found. Please run "npm run build" to compile the native module.\n' +
|
|
14
|
+
"Original error: " +
|
|
15
|
+
error.message
|
|
16
|
+
);
|
|
25
17
|
}
|
|
26
18
|
}
|
|
27
19
|
|
|
@@ -32,15 +24,6 @@ class WindowSelector extends EventEmitter {
|
|
|
32
24
|
this.selectionTimer = null;
|
|
33
25
|
this.selectedWindow = null;
|
|
34
26
|
this.lastStatus = null;
|
|
35
|
-
|
|
36
|
-
// Electron environment detection
|
|
37
|
-
this.isElectron = !!(process.versions && process.versions.electron) ||
|
|
38
|
-
!!(process.env.ELECTRON_VERSION) ||
|
|
39
|
-
!!(process.env.ELECTRON_RUN_AS_NODE);
|
|
40
|
-
|
|
41
|
-
if (this.isElectron) {
|
|
42
|
-
console.log("🔍 WindowSelector: Detected Electron environment - using safe mode");
|
|
43
|
-
}
|
|
44
27
|
}
|
|
45
28
|
|
|
46
29
|
/**
|
|
@@ -57,11 +40,11 @@ class WindowSelector extends EventEmitter {
|
|
|
57
40
|
try {
|
|
58
41
|
// Native window selection başlat
|
|
59
42
|
const success = nativeBinding.startWindowSelection();
|
|
60
|
-
|
|
43
|
+
|
|
61
44
|
if (success) {
|
|
62
45
|
this.isSelecting = true;
|
|
63
46
|
this.selectedWindow = null;
|
|
64
|
-
|
|
47
|
+
|
|
65
48
|
// Status polling timer başlat (higher frequency for overlay updates)
|
|
66
49
|
this.selectionTimer = setInterval(() => {
|
|
67
50
|
this.checkSelectionStatus();
|
|
@@ -89,7 +72,7 @@ class WindowSelector extends EventEmitter {
|
|
|
89
72
|
return new Promise((resolve, reject) => {
|
|
90
73
|
try {
|
|
91
74
|
const success = nativeBinding.stopWindowSelection();
|
|
92
|
-
|
|
75
|
+
|
|
93
76
|
// Timer'ı durdur
|
|
94
77
|
if (this.selectionTimer) {
|
|
95
78
|
clearInterval(this.selectionTimer);
|
|
@@ -115,14 +98,14 @@ class WindowSelector extends EventEmitter {
|
|
|
115
98
|
|
|
116
99
|
try {
|
|
117
100
|
const status = nativeBinding.getWindowSelectionStatus();
|
|
118
|
-
|
|
101
|
+
|
|
119
102
|
// Seçim tamamlandı mı kontrol et
|
|
120
103
|
if (status.hasSelectedWindow && !this.selectedWindow) {
|
|
121
104
|
const windowInfo = nativeBinding.getSelectedWindowInfo();
|
|
122
105
|
if (windowInfo) {
|
|
123
106
|
this.selectedWindow = windowInfo;
|
|
124
107
|
this.isSelecting = false;
|
|
125
|
-
|
|
108
|
+
|
|
126
109
|
// Timer'ı durdur
|
|
127
110
|
if (this.selectionTimer) {
|
|
128
111
|
clearInterval(this.selectionTimer);
|
|
@@ -138,20 +121,17 @@ class WindowSelector extends EventEmitter {
|
|
|
138
121
|
if (this.lastStatus) {
|
|
139
122
|
const lastWindow = this.lastStatus.currentWindow;
|
|
140
123
|
const currentWindow = status.currentWindow;
|
|
141
|
-
|
|
124
|
+
|
|
142
125
|
if (!lastWindow && currentWindow) {
|
|
143
126
|
// Yeni pencere üstüne gelindi
|
|
144
127
|
this.emit("windowEntered", currentWindow);
|
|
145
128
|
} else if (lastWindow && !currentWindow) {
|
|
146
129
|
// Pencere üstünden ayrıldı
|
|
147
130
|
this.emit("windowLeft", lastWindow);
|
|
148
|
-
} else if (
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
lastWindow.title !== currentWindow.title ||
|
|
153
|
-
lastWindow.appName !== currentWindow.appName)
|
|
154
|
-
) {
|
|
131
|
+
} else if (lastWindow && currentWindow &&
|
|
132
|
+
(lastWindow.id !== currentWindow.id ||
|
|
133
|
+
lastWindow.title !== currentWindow.title ||
|
|
134
|
+
lastWindow.appName !== currentWindow.appName)) {
|
|
155
135
|
// Farklı bir pencereye geçildi
|
|
156
136
|
this.emit("windowLeft", lastWindow);
|
|
157
137
|
this.emit("windowEntered", currentWindow);
|
|
@@ -174,59 +154,6 @@ class WindowSelector extends EventEmitter {
|
|
|
174
154
|
return this.selectedWindow;
|
|
175
155
|
}
|
|
176
156
|
|
|
177
|
-
/**
|
|
178
|
-
* Electron'da kullanmak için mevcut pencereleri döndürür
|
|
179
|
-
* @returns {Array} Available windows for selection
|
|
180
|
-
*/
|
|
181
|
-
async getAvailableWindows() {
|
|
182
|
-
if (this.isElectron) {
|
|
183
|
-
try {
|
|
184
|
-
// Start selection to populate window list (safe mode)
|
|
185
|
-
const success = nativeBinding.startWindowSelection();
|
|
186
|
-
if (success) {
|
|
187
|
-
// Get the populated window list
|
|
188
|
-
const status = nativeBinding.getWindowSelectionStatus();
|
|
189
|
-
|
|
190
|
-
// Stop selection immediately
|
|
191
|
-
nativeBinding.stopWindowSelection();
|
|
192
|
-
|
|
193
|
-
// Return windows from native status
|
|
194
|
-
// In Electron safe mode, these will be available without overlay
|
|
195
|
-
const MacRecorder = require("./index.js");
|
|
196
|
-
const recorder = new MacRecorder();
|
|
197
|
-
return await recorder.getWindows();
|
|
198
|
-
}
|
|
199
|
-
} catch (error) {
|
|
200
|
-
console.error("Error getting available windows in Electron:", error.message);
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
// Fallback to regular MacRecorder method
|
|
205
|
-
try {
|
|
206
|
-
const MacRecorder = require("./index.js");
|
|
207
|
-
const recorder = new MacRecorder();
|
|
208
|
-
return await recorder.getWindows();
|
|
209
|
-
} catch (error) {
|
|
210
|
-
console.error("Error getting windows:", error.message);
|
|
211
|
-
return [];
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* Electron'da pencere seçmek için - overlay olmadan
|
|
217
|
-
* @param {Object} windowInfo - Selected window from getAvailableWindows()
|
|
218
|
-
*/
|
|
219
|
-
selectWindowById(windowInfo) {
|
|
220
|
-
if (!windowInfo || !windowInfo.id) {
|
|
221
|
-
throw new Error("Valid window info required");
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
this.selectedWindow = windowInfo;
|
|
225
|
-
this.emit('windowSelected', windowInfo);
|
|
226
|
-
|
|
227
|
-
return windowInfo;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
157
|
/**
|
|
231
158
|
* Seçim durumunu döndürür
|
|
232
159
|
*/
|
|
@@ -237,14 +164,14 @@ class WindowSelector extends EventEmitter {
|
|
|
237
164
|
isSelecting: this.isSelecting && nativeStatus.isSelecting,
|
|
238
165
|
hasSelectedWindow: !!this.selectedWindow,
|
|
239
166
|
selectedWindow: this.selectedWindow,
|
|
240
|
-
nativeStatus: nativeStatus
|
|
167
|
+
nativeStatus: nativeStatus
|
|
241
168
|
};
|
|
242
169
|
} catch (error) {
|
|
243
170
|
return {
|
|
244
171
|
isSelecting: this.isSelecting,
|
|
245
172
|
hasSelectedWindow: !!this.selectedWindow,
|
|
246
173
|
selectedWindow: this.selectedWindow,
|
|
247
|
-
error: error.message
|
|
174
|
+
error: error.message
|
|
248
175
|
};
|
|
249
176
|
}
|
|
250
177
|
}
|
|
@@ -278,6 +205,7 @@ class WindowSelector extends EventEmitter {
|
|
|
278
205
|
|
|
279
206
|
// Seçimi başlat
|
|
280
207
|
await this.startSelection();
|
|
208
|
+
|
|
281
209
|
} catch (error) {
|
|
282
210
|
this.removeAllListeners("windowSelected");
|
|
283
211
|
this.removeAllListeners("error");
|
|
@@ -314,9 +242,7 @@ class WindowSelector extends EventEmitter {
|
|
|
314
242
|
nativeBinding.setBringToFrontEnabled(enabled);
|
|
315
243
|
// Only log if explicitly setting, not on startup
|
|
316
244
|
if (arguments.length > 0) {
|
|
317
|
-
console.log(
|
|
318
|
-
`🔄 Auto bring-to-front: ${enabled ? "ENABLED" : "DISABLED"}`
|
|
319
|
-
);
|
|
245
|
+
console.log(`🔄 Auto bring-to-front: ${enabled ? 'ENABLED' : 'DISABLED'}`);
|
|
320
246
|
}
|
|
321
247
|
} catch (error) {
|
|
322
248
|
throw new Error(`Failed to set bring to front: ${error.message}`);
|
|
@@ -450,14 +376,14 @@ class WindowSelector extends EventEmitter {
|
|
|
450
376
|
try {
|
|
451
377
|
// Start screen selection
|
|
452
378
|
await this.startScreenSelection();
|
|
453
|
-
|
|
379
|
+
|
|
454
380
|
// Poll for selection completion
|
|
455
381
|
return new Promise((resolve, reject) => {
|
|
456
382
|
let isResolved = false;
|
|
457
|
-
|
|
383
|
+
|
|
458
384
|
const checkSelection = () => {
|
|
459
385
|
if (isResolved) return; // Prevent multiple resolutions
|
|
460
|
-
|
|
386
|
+
|
|
461
387
|
const selectedScreen = this.getSelectedScreen();
|
|
462
388
|
if (selectedScreen) {
|
|
463
389
|
isResolved = true;
|
|
@@ -468,19 +394,19 @@ class WindowSelector extends EventEmitter {
|
|
|
468
394
|
} else {
|
|
469
395
|
// Selection was cancelled (probably ESC key)
|
|
470
396
|
isResolved = true;
|
|
471
|
-
reject(new Error(
|
|
397
|
+
reject(new Error('Screen selection was cancelled'));
|
|
472
398
|
}
|
|
473
399
|
};
|
|
474
|
-
|
|
400
|
+
|
|
475
401
|
// Start polling
|
|
476
402
|
checkSelection();
|
|
477
|
-
|
|
403
|
+
|
|
478
404
|
// Timeout after 60 seconds
|
|
479
405
|
setTimeout(() => {
|
|
480
406
|
if (!isResolved) {
|
|
481
407
|
isResolved = true;
|
|
482
408
|
this.stopScreenSelection();
|
|
483
|
-
reject(new Error(
|
|
409
|
+
reject(new Error('Screen selection timed out'));
|
|
484
410
|
}
|
|
485
411
|
}, 60000);
|
|
486
412
|
});
|
|
@@ -504,9 +430,7 @@ class WindowSelector extends EventEmitter {
|
|
|
504
430
|
const success = nativeBinding.showScreenRecordingPreview(screenInfo);
|
|
505
431
|
return success;
|
|
506
432
|
} catch (error) {
|
|
507
|
-
throw new Error(
|
|
508
|
-
`Failed to show screen recording preview: ${error.message}`
|
|
509
|
-
);
|
|
433
|
+
throw new Error(`Failed to show screen recording preview: ${error.message}`);
|
|
510
434
|
}
|
|
511
435
|
}
|
|
512
436
|
|
|
@@ -519,9 +443,7 @@ class WindowSelector extends EventEmitter {
|
|
|
519
443
|
const success = nativeBinding.hideScreenRecordingPreview();
|
|
520
444
|
return success;
|
|
521
445
|
} catch (error) {
|
|
522
|
-
throw new Error(
|
|
523
|
-
`Failed to hide screen recording preview: ${error.message}`
|
|
524
|
-
);
|
|
446
|
+
throw new Error(`Failed to hide screen recording preview: ${error.message}`);
|
|
525
447
|
}
|
|
526
448
|
}
|
|
527
449
|
|
|
@@ -538,10 +460,10 @@ class WindowSelector extends EventEmitter {
|
|
|
538
460
|
return {
|
|
539
461
|
screenRecording: false,
|
|
540
462
|
accessibility: false,
|
|
541
|
-
error: error.message
|
|
463
|
+
error: error.message
|
|
542
464
|
};
|
|
543
465
|
}
|
|
544
466
|
}
|
|
545
467
|
}
|
|
546
468
|
|
|
547
|
-
module.exports = WindowSelector;
|
|
469
|
+
module.exports = WindowSelector;
|