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.
@@ -1,698 +0,0 @@
1
- const { EventEmitter } = require("events");
2
- const path = require("path");
3
-
4
- // Native modülü yükle
5
- let nativeBinding;
6
- try {
7
- if (process.platform === "darwin" && process.arch === "arm64") {
8
- nativeBinding = require("./prebuilds/darwin-arm64/node.napi.node");
9
- } else {
10
- nativeBinding = require("./build/Release/mac_recorder.node");
11
- }
12
- } catch (error) {
13
- try {
14
- nativeBinding = require("./build/Release/mac_recorder.node");
15
- } catch (_) {
16
- try {
17
- nativeBinding = require("./build/Debug/mac_recorder.node");
18
- } catch (debugError) {
19
- throw new Error(
20
- 'Native module not found. Please run "npm run build" to compile the native module.\n' +
21
- "Original error: " +
22
- error.message
23
- );
24
- }
25
- }
26
- }
27
-
28
- class ElectronWindowSelector extends EventEmitter {
29
- constructor() {
30
- super();
31
- this.isSelecting = false;
32
- this.isScreenSelecting = false;
33
- this.selectedWindow = null;
34
- this.selectedScreen = null;
35
- this.selectionTimer = null;
36
- this.lastStatus = null;
37
-
38
- // Electron detection
39
- this.isElectron = !!(process.versions && process.versions.electron) ||
40
- !!(process.env.ELECTRON_VERSION) ||
41
- !!(process.env.ELECTRON_RUN_AS_NODE);
42
-
43
- console.log(`🔍 ElectronWindowSelector: ${this.isElectron ? 'Electron' : 'Node.js'} environment detected`);
44
- }
45
-
46
- /**
47
- * Pencere seçim modunu başlatır - Electron'da overlay ile
48
- * @returns {Promise<Object>} Seçilen pencere bilgisi
49
- */
50
- async selectWindow() {
51
- if (this.isSelecting) {
52
- throw new Error("Window selection is already in progress");
53
- }
54
-
55
- return new Promise((resolve, reject) => {
56
- try {
57
- // Event listener'ları ayarla
58
- const onWindowSelected = (windowInfo) => {
59
- this.removeAllListeners("windowSelected");
60
- this.removeAllListeners("error");
61
- this.removeAllListeners("selectionCancelled");
62
- resolve(windowInfo);
63
- };
64
-
65
- const onError = (error) => {
66
- this.removeAllListeners("windowSelected");
67
- this.removeAllListeners("error");
68
- this.removeAllListeners("selectionCancelled");
69
- reject(error);
70
- };
71
-
72
- const onCancelled = () => {
73
- this.removeAllListeners("windowSelected");
74
- this.removeAllListeners("error");
75
- this.removeAllListeners("selectionCancelled");
76
- reject(new Error("Window selection was cancelled"));
77
- };
78
-
79
- this.once("windowSelected", onWindowSelected);
80
- this.once("error", onError);
81
- this.once("selectionCancelled", onCancelled);
82
-
83
- // Native window selection başlat (overlay ile)
84
- this.startWindowSelectionWithOverlay();
85
-
86
- } catch (error) {
87
- this.removeAllListeners("windowSelected");
88
- this.removeAllListeners("error");
89
- this.removeAllListeners("selectionCancelled");
90
- reject(error);
91
- }
92
- });
93
- }
94
-
95
- /**
96
- * Ekran seçim modunu başlatır - Electron'da overlay ile
97
- * @returns {Promise<Object>} Seçilen ekran bilgisi
98
- */
99
- async selectScreen() {
100
- if (this.isScreenSelecting) {
101
- throw new Error("Screen selection is already in progress");
102
- }
103
-
104
- return new Promise((resolve, reject) => {
105
- try {
106
- // Event listener'ları ayarla
107
- const onScreenSelected = (screenInfo) => {
108
- this.removeAllListeners("screenSelected");
109
- this.removeAllListeners("error");
110
- this.removeAllListeners("selectionCancelled");
111
- resolve(screenInfo);
112
- };
113
-
114
- const onError = (error) => {
115
- this.removeAllListeners("screenSelected");
116
- this.removeAllListeners("error");
117
- this.removeAllListeners("selectionCancelled");
118
- reject(error);
119
- };
120
-
121
- const onCancelled = () => {
122
- this.removeAllListeners("screenSelected");
123
- this.removeAllListeners("error");
124
- this.removeAllListeners("selectionCancelled");
125
- reject(new Error("Screen selection was cancelled"));
126
- };
127
-
128
- this.once("screenSelected", onScreenSelected);
129
- this.once("error", onError);
130
- this.once("selectionCancelled", onCancelled);
131
-
132
- // Native screen selection başlat (overlay ile)
133
- this.startScreenSelectionWithOverlay();
134
-
135
- } catch (error) {
136
- this.removeAllListeners("screenSelected");
137
- this.removeAllListeners("error");
138
- this.removeAllListeners("selectionCancelled");
139
- reject(error);
140
- }
141
- });
142
- }
143
-
144
- /**
145
- * Native window selection'ı overlay ile başlatır
146
- */
147
- async startWindowSelectionWithOverlay() {
148
- try {
149
- // Native binding'den window selection başlat
150
- const success = await this.callNativeWindowSelection();
151
-
152
- if (success) {
153
- this.isSelecting = true;
154
- this.selectedWindow = null;
155
-
156
- // Polling timer başlat (overlay update'leri için)
157
- this.selectionTimer = setInterval(() => {
158
- this.checkWindowSelectionStatus();
159
- }, 50); // 20 FPS
160
-
161
- this.emit("selectionStarted");
162
- console.log("✅ Window selection overlay started");
163
- } else {
164
- throw new Error("Failed to start window selection overlay");
165
- }
166
- } catch (error) {
167
- console.error("❌ Window selection failed:", error.message);
168
- this.emit("error", error);
169
- }
170
- }
171
-
172
- /**
173
- * Native screen selection'ı overlay ile başlatır
174
- */
175
- async startScreenSelectionWithOverlay() {
176
- try {
177
- // Native binding'den screen selection başlat
178
- const success = await this.callNativeScreenSelection();
179
-
180
- if (success) {
181
- this.isScreenSelecting = true;
182
- this.selectedScreen = null;
183
-
184
- // Polling timer başlat (overlay update'leri için)
185
- this.selectionTimer = setInterval(() => {
186
- this.checkScreenSelectionStatus();
187
- }, 50); // 20 FPS
188
-
189
- this.emit("screenSelectionStarted");
190
- console.log("✅ Screen selection overlay started");
191
- } else {
192
- throw new Error("Failed to start screen selection overlay");
193
- }
194
- } catch (error) {
195
- console.error("❌ Screen selection failed:", error.message);
196
- this.emit("error", error);
197
- }
198
- }
199
-
200
- /**
201
- * Native window selection API'yi çağırır - Electron-compatible
202
- */
203
- async callNativeWindowSelection() {
204
- try {
205
- // Electron'da bile overlay'lerin çalışması için environment variable'ı geçici olarak kaldır
206
- const originalElectronVersion = process.env.ELECTRON_VERSION;
207
- const originalElectronRunAs = process.env.ELECTRON_RUN_AS_NODE;
208
-
209
- // Geçici olarak Electron environment variable'larını kaldır
210
- delete process.env.ELECTRON_VERSION;
211
- delete process.env.ELECTRON_RUN_AS_NODE;
212
-
213
- try {
214
- // Native function çağır
215
- const result = nativeBinding.startWindowSelection();
216
- return result;
217
- } finally {
218
- // Environment variable'ları geri yükle
219
- if (originalElectronVersion) {
220
- process.env.ELECTRON_VERSION = originalElectronVersion;
221
- }
222
- if (originalElectronRunAs) {
223
- process.env.ELECTRON_RUN_AS_NODE = originalElectronRunAs;
224
- }
225
- }
226
- } catch (error) {
227
- console.error("Native window selection failed:", error.message);
228
- return false;
229
- }
230
- }
231
-
232
- /**
233
- * Native screen selection API'yi çağırır - Electron-compatible
234
- */
235
- async callNativeScreenSelection() {
236
- try {
237
- // Electron'da bile overlay'lerin çalışması için environment variable'ı geçici olarak kaldır
238
- const originalElectronVersion = process.env.ELECTRON_VERSION;
239
- const originalElectronRunAs = process.env.ELECTRON_RUN_AS_NODE;
240
-
241
- // Geçici olarak Electron environment variable'larını kaldır
242
- delete process.env.ELECTRON_VERSION;
243
- delete process.env.ELECTRON_RUN_AS_NODE;
244
-
245
- try {
246
- // Native function çağır
247
- const result = nativeBinding.startScreenSelection();
248
- return result;
249
- } finally {
250
- // Environment variable'ları geri yükle
251
- if (originalElectronVersion) {
252
- process.env.ELECTRON_VERSION = originalElectronVersion;
253
- }
254
- if (originalElectronRunAs) {
255
- process.env.ELECTRON_RUN_AS_NODE = originalElectronRunAs;
256
- }
257
- }
258
- } catch (error) {
259
- console.error("Native screen selection failed:", error.message);
260
- return false;
261
- }
262
- }
263
-
264
- /**
265
- * Window selection durumunu kontrol eder
266
- */
267
- checkWindowSelectionStatus() {
268
- if (!this.isSelecting) return;
269
-
270
- try {
271
- const status = nativeBinding.getWindowSelectionStatus();
272
-
273
- // Seçim tamamlandı mı kontrol et
274
- if (status.hasSelectedWindow && !this.selectedWindow) {
275
- const windowInfo = nativeBinding.getSelectedWindowInfo();
276
- if (windowInfo) {
277
- this.selectedWindow = windowInfo;
278
- this.isSelecting = false;
279
-
280
- // Timer'ı durdur
281
- if (this.selectionTimer) {
282
- clearInterval(this.selectionTimer);
283
- this.selectionTimer = null;
284
- }
285
-
286
- console.log("🎯 Window selected:", windowInfo.title || windowInfo.appName);
287
- this.emit("windowSelected", windowInfo);
288
- return;
289
- }
290
- }
291
-
292
- // Mouse movement events için mevcut pencere değişikliklerini kontrol et
293
- if (this.lastStatus) {
294
- const lastWindow = this.lastStatus.currentWindow;
295
- const currentWindow = status.currentWindow;
296
-
297
- if (!lastWindow && currentWindow) {
298
- // Yeni pencere üstüne gelindi
299
- this.emit("windowEntered", currentWindow);
300
- } else if (lastWindow && !currentWindow) {
301
- // Pencere üstünden ayrıldı
302
- this.emit("windowLeft", lastWindow);
303
- } else if (
304
- lastWindow &&
305
- currentWindow &&
306
- (lastWindow.id !== currentWindow.id ||
307
- lastWindow.title !== currentWindow.title ||
308
- lastWindow.appName !== currentWindow.appName)
309
- ) {
310
- // Farklı bir pencereye geçildi
311
- this.emit("windowLeft", lastWindow);
312
- this.emit("windowEntered", currentWindow);
313
- }
314
- } else if (!this.lastStatus && status.currentWindow) {
315
- // İlk pencere detection
316
- this.emit("windowEntered", status.currentWindow);
317
- }
318
-
319
- this.lastStatus = status;
320
- } catch (error) {
321
- console.error("Window selection status check error:", error.message);
322
- this.emit("error", error);
323
- }
324
- }
325
-
326
- /**
327
- * Screen selection durumunu kontrol eder
328
- */
329
- checkScreenSelectionStatus() {
330
- if (!this.isScreenSelecting) return;
331
-
332
- try {
333
- const selectedScreen = nativeBinding.getSelectedScreenInfo();
334
-
335
- if (selectedScreen && !this.selectedScreen) {
336
- this.selectedScreen = selectedScreen;
337
- this.isScreenSelecting = false;
338
-
339
- // Timer'ı durdur
340
- if (this.selectionTimer) {
341
- clearInterval(this.selectionTimer);
342
- this.selectionTimer = null;
343
- }
344
-
345
- console.log("🖥️ Screen selected:", selectedScreen);
346
- this.emit("screenSelected", selectedScreen);
347
- }
348
- } catch (error) {
349
- console.error("Screen selection status check error:", error.message);
350
- this.emit("error", error);
351
- }
352
- }
353
-
354
- /**
355
- * Window selection'ı durdurur
356
- */
357
- async stopWindowSelection() {
358
- if (!this.isSelecting) {
359
- return false;
360
- }
361
-
362
- try {
363
- // Environment variable'ları geçici kaldır
364
- const originalElectronVersion = process.env.ELECTRON_VERSION;
365
- const originalElectronRunAs = process.env.ELECTRON_RUN_AS_NODE;
366
-
367
- delete process.env.ELECTRON_VERSION;
368
- delete process.env.ELECTRON_RUN_AS_NODE;
369
-
370
- try {
371
- const success = nativeBinding.stopWindowSelection();
372
-
373
- // Timer'ı durdur
374
- if (this.selectionTimer) {
375
- clearInterval(this.selectionTimer);
376
- this.selectionTimer = null;
377
- }
378
-
379
- this.isSelecting = false;
380
- this.lastStatus = null;
381
-
382
- this.emit("selectionStopped");
383
- console.log("🛑 Window selection stopped");
384
- return success;
385
- } finally {
386
- // Environment variable'ları geri yükle
387
- if (originalElectronVersion) {
388
- process.env.ELECTRON_VERSION = originalElectronVersion;
389
- }
390
- if (originalElectronRunAs) {
391
- process.env.ELECTRON_RUN_AS_NODE = originalElectronRunAs;
392
- }
393
- }
394
- } catch (error) {
395
- console.error("Stop window selection error:", error.message);
396
- return false;
397
- }
398
- }
399
-
400
- /**
401
- * Screen selection'ı durdurur
402
- */
403
- async stopScreenSelection() {
404
- if (!this.isScreenSelecting) {
405
- return false;
406
- }
407
-
408
- try {
409
- // Environment variable'ları geçici kaldır
410
- const originalElectronVersion = process.env.ELECTRON_VERSION;
411
- const originalElectronRunAs = process.env.ELECTRON_RUN_AS_NODE;
412
-
413
- delete process.env.ELECTRON_VERSION;
414
- delete process.env.ELECTRON_RUN_AS_NODE;
415
-
416
- try {
417
- const success = nativeBinding.stopScreenSelection();
418
-
419
- // Timer'ı durdur
420
- if (this.selectionTimer) {
421
- clearInterval(this.selectionTimer);
422
- this.selectionTimer = null;
423
- }
424
-
425
- this.isScreenSelecting = false;
426
-
427
- this.emit("screenSelectionStopped");
428
- console.log("🛑 Screen selection stopped");
429
- return success;
430
- } finally {
431
- // Environment variable'ları geri yükle
432
- if (originalElectronVersion) {
433
- process.env.ELECTRON_VERSION = originalElectronVersion;
434
- }
435
- if (originalElectronRunAs) {
436
- process.env.ELECTRON_RUN_AS_NODE = originalElectronRunAs;
437
- }
438
- }
439
- } catch (error) {
440
- console.error("Stop screen selection error:", error.message);
441
- return false;
442
- }
443
- }
444
-
445
- /**
446
- * Recording preview gösterir
447
- * @param {Object} windowInfo - Pencere bilgisi
448
- */
449
- async showRecordingPreview(windowInfo) {
450
- if (!windowInfo) {
451
- throw new Error("Window info is required");
452
- }
453
-
454
- try {
455
- // Environment variable'ları geçici kaldır
456
- const originalElectronVersion = process.env.ELECTRON_VERSION;
457
- const originalElectronRunAs = process.env.ELECTRON_RUN_AS_NODE;
458
-
459
- delete process.env.ELECTRON_VERSION;
460
- delete process.env.ELECTRON_RUN_AS_NODE;
461
-
462
- try {
463
- const success = nativeBinding.showRecordingPreview(windowInfo);
464
- console.log("🎬 Recording preview shown");
465
- return success;
466
- } finally {
467
- // Environment variable'ları geri yükle
468
- if (originalElectronVersion) {
469
- process.env.ELECTRON_VERSION = originalElectronVersion;
470
- }
471
- if (originalElectronRunAs) {
472
- process.env.ELECTRON_RUN_AS_NODE = originalElectronRunAs;
473
- }
474
- }
475
- } catch (error) {
476
- console.error("Show recording preview error:", error.message);
477
- throw error;
478
- }
479
- }
480
-
481
- /**
482
- * Recording preview'ı gizler
483
- */
484
- async hideRecordingPreview() {
485
- try {
486
- // Environment variable'ları geçici kaldır
487
- const originalElectronVersion = process.env.ELECTRON_VERSION;
488
- const originalElectronRunAs = process.env.ELECTRON_RUN_AS_NODE;
489
-
490
- delete process.env.ELECTRON_VERSION;
491
- delete process.env.ELECTRON_RUN_AS_NODE;
492
-
493
- try {
494
- const success = nativeBinding.hideRecordingPreview();
495
- console.log("🎬 Recording preview hidden");
496
- return success;
497
- } finally {
498
- // Environment variable'ları geri yükle
499
- if (originalElectronVersion) {
500
- process.env.ELECTRON_VERSION = originalElectronVersion;
501
- }
502
- if (originalElectronRunAs) {
503
- process.env.ELECTRON_RUN_AS_NODE = originalElectronRunAs;
504
- }
505
- }
506
- } catch (error) {
507
- console.error("Hide recording preview error:", error.message);
508
- throw error;
509
- }
510
- }
511
-
512
- /**
513
- * Screen recording preview gösterir
514
- * @param {Object} screenInfo - Ekran bilgisi
515
- */
516
- async showScreenRecordingPreview(screenInfo) {
517
- if (!screenInfo) {
518
- throw new Error("Screen info is required");
519
- }
520
-
521
- try {
522
- // Environment variable'ları geçici kaldır
523
- const originalElectronVersion = process.env.ELECTRON_VERSION;
524
- const originalElectronRunAs = process.env.ELECTRON_RUN_AS_NODE;
525
-
526
- delete process.env.ELECTRON_VERSION;
527
- delete process.env.ELECTRON_RUN_AS_NODE;
528
-
529
- try {
530
- const success = nativeBinding.showScreenRecordingPreview(screenInfo);
531
- console.log("🖥️ Screen recording preview shown");
532
- return success;
533
- } finally {
534
- // Environment variable'ları geri yükle
535
- if (originalElectronVersion) {
536
- process.env.ELECTRON_VERSION = originalElectronVersion;
537
- }
538
- if (originalElectronRunAs) {
539
- process.env.ELECTRON_RUN_AS_NODE = originalElectronRunAs;
540
- }
541
- }
542
- } catch (error) {
543
- console.error("Show screen recording preview error:", error.message);
544
- throw error;
545
- }
546
- }
547
-
548
- /**
549
- * Screen recording preview'ı gizler
550
- */
551
- async hideScreenRecordingPreview() {
552
- try {
553
- // Environment variable'ları geçici kaldır
554
- const originalElectronVersion = process.env.ELECTRON_VERSION;
555
- const originalElectronRunAs = process.env.ELECTRON_RUN_AS_NODE;
556
-
557
- delete process.env.ELECTRON_VERSION;
558
- delete process.env.ELECTRON_RUN_AS_NODE;
559
-
560
- try {
561
- const success = nativeBinding.hideScreenRecordingPreview();
562
- console.log("🖥️ Screen recording preview hidden");
563
- return success;
564
- } finally {
565
- // Environment variable'ları geri yükle
566
- if (originalElectronVersion) {
567
- process.env.ELECTRON_VERSION = originalElectronVersion;
568
- }
569
- if (originalElectronRunAs) {
570
- process.env.ELECTRON_RUN_AS_NODE = originalElectronRunAs;
571
- }
572
- }
573
- } catch (error) {
574
- console.error("Hide screen recording preview error:", error.message);
575
- throw error;
576
- }
577
- }
578
-
579
- /**
580
- * Mevcut durumu döndürür
581
- */
582
- getStatus() {
583
- return {
584
- isSelecting: this.isSelecting,
585
- isScreenSelecting: this.isScreenSelecting,
586
- hasSelectedWindow: !!this.selectedWindow,
587
- hasSelectedScreen: !!this.selectedScreen,
588
- selectedWindow: this.selectedWindow,
589
- selectedScreen: this.selectedScreen,
590
- isElectron: this.isElectron
591
- };
592
- }
593
-
594
- /**
595
- * Seçilen pencere bilgisini döndürür
596
- */
597
- getSelectedWindow() {
598
- return this.selectedWindow;
599
- }
600
-
601
- /**
602
- * Seçilen ekran bilgisini döndürür
603
- */
604
- getSelectedScreen() {
605
- return this.selectedScreen;
606
- }
607
-
608
- /**
609
- * Tüm kaynakları temizler
610
- */
611
- async cleanup() {
612
- try {
613
- // Selection'ları durdur
614
- if (this.isSelecting) {
615
- await this.stopWindowSelection();
616
- }
617
-
618
- if (this.isScreenSelecting) {
619
- await this.stopScreenSelection();
620
- }
621
-
622
- // Timer'ları temizle
623
- if (this.selectionTimer) {
624
- clearInterval(this.selectionTimer);
625
- this.selectionTimer = null;
626
- }
627
-
628
- // Preview'ları gizle
629
- try {
630
- await this.hideRecordingPreview();
631
- await this.hideScreenRecordingPreview();
632
- } catch (error) {
633
- // Preview errors are not critical
634
- console.warn("Preview cleanup warning:", error.message);
635
- }
636
-
637
- // Event listener'ları temizle
638
- this.removeAllListeners();
639
-
640
- // State'i sıfırla
641
- this.selectedWindow = null;
642
- this.selectedScreen = null;
643
- this.lastStatus = null;
644
- this.isSelecting = false;
645
- this.isScreenSelecting = false;
646
-
647
- console.log("🧹 ElectronWindowSelector cleaned up");
648
- } catch (error) {
649
- console.error("Cleanup error:", error.message);
650
- }
651
- }
652
-
653
- /**
654
- * İzinleri kontrol eder
655
- */
656
- async checkPermissions() {
657
- try {
658
- const MacRecorder = require("./index.js");
659
- const recorder = new MacRecorder();
660
- return await recorder.checkPermissions();
661
- } catch (error) {
662
- return {
663
- screenRecording: false,
664
- accessibility: false,
665
- error: error.message,
666
- };
667
- }
668
- }
669
-
670
- /**
671
- * Electron tarafından kullanılacak window listesi döndürür
672
- */
673
- async getAvailableWindows() {
674
- try {
675
- const windows = nativeBinding.getWindows();
676
- return windows || [];
677
- } catch (error) {
678
- console.error('Get available windows failed:', error.message);
679
- return [];
680
- }
681
- }
682
-
683
- /**
684
- * Electron tarafından kullanılacak display listesi döndürür
685
- */
686
- async getAvailableDisplays() {
687
- try {
688
- const MacRecorder = require('./index.js');
689
- const recorder = new MacRecorder();
690
- return await recorder.getDisplays();
691
- } catch (error) {
692
- console.error('Get available displays failed:', error.message);
693
- return [];
694
- }
695
- }
696
- }
697
-
698
- module.exports = ElectronWindowSelector;
Binary file