node-mac-recorder 2.17.21 → 2.18.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.
@@ -119,41 +119,8 @@ static NSString *g_outputPath = nil;
119
119
  }
120
120
 
121
121
  if (targetWindow && targetApp) {
122
- NSLog(@"🪟 Recording window: %@ (%ux%u)",
122
+ NSLog(@"🪟 Recording window: %@ (%ux%u)",
123
123
  targetWindow.title, (unsigned)targetWindow.frame.size.width, (unsigned)targetWindow.frame.size.height);
124
-
125
- // Find which display contains this window for proper cursor coordinate transformation
126
- CGRect windowFrame = targetWindow.frame;
127
- NSLog(@"🔍 Window frame: (%.0f,%.0f,%.0fx%.0f)",
128
- windowFrame.origin.x, windowFrame.origin.y,
129
- windowFrame.size.width, windowFrame.size.height);
130
-
131
- // Find the display that contains the window's center point
132
- CGPoint windowCenter = CGPointMake(
133
- windowFrame.origin.x + windowFrame.size.width / 2,
134
- windowFrame.origin.y + windowFrame.size.height / 2
135
- );
136
-
137
- for (SCDisplay *display in content.displays) {
138
- CGRect displayFrame = display.frame;
139
- NSLog(@"🔍 Checking if window center (%.0f,%.0f) is in display ID=%u frame (%.0f,%.0f,%.0fx%.0f)",
140
- windowCenter.x, windowCenter.y, display.displayID,
141
- displayFrame.origin.x, displayFrame.origin.y,
142
- displayFrame.size.width, displayFrame.size.height);
143
-
144
- if (CGRectContainsPoint(displayFrame, windowCenter)) {
145
- targetDisplay = display;
146
- NSLog(@"✅ Window is on display ID=%u", display.displayID);
147
- break;
148
- }
149
- }
150
-
151
- if (!targetDisplay) {
152
- // Fallback: use main display if no display contains the window center
153
- targetDisplay = content.displays.firstObject;
154
- NSLog(@"⚠️ Window not contained in any display, using main display ID=%u as fallback", targetDisplay.displayID);
155
- }
156
-
157
124
  filter = [[SCContentFilter alloc] initWithDesktopIndependentWindow:targetWindow];
158
125
  recordingWidth = (NSInteger)targetWindow.frame.size.width;
159
126
  recordingHeight = (NSInteger)targetWindow.frame.size.height;
@@ -1,71 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const WindowSelector = require('./window-selector');
4
-
5
- async function autoBringToFrontDemo() {
6
- console.log('🤖 Auto Bring-To-Front Demo');
7
- console.log('============================\n');
8
-
9
- const selector = new WindowSelector();
10
-
11
- try {
12
- console.log('🔄 Enabling auto bring-to-front feature...');
13
- selector.setBringToFrontEnabled(true);
14
-
15
- console.log('✅ Auto mode enabled!');
16
- console.log('🖱️ Now move your cursor over different windows');
17
- console.log('🔝 Each window should automatically come to front\n');
18
-
19
- let windowCount = 0;
20
- let lastWindowId = null;
21
-
22
- selector.on('windowEntered', (window) => {
23
- if (window.id !== lastWindowId) {
24
- windowCount++;
25
- console.log(`[${windowCount}] 🎯 AUTO-FRONT: ${window.appName} - "${window.title}"`);
26
- console.log(` 📍 Position: (${window.x}, ${window.y})`);
27
- console.log(` 📏 Size: ${window.width} × ${window.height}`);
28
- console.log(` 🔝 Window should come to front automatically!\n`);
29
- lastWindowId = window.id;
30
- }
31
- });
32
-
33
- selector.on('windowLeft', (window) => {
34
- console.log(`🚪 Left: ${window.appName} - "${window.title}"\n`);
35
- });
36
-
37
- await selector.startSelection();
38
-
39
- console.log('Demo started! Move cursor over different app windows to see them come to front.');
40
- console.log('Press Ctrl+C to stop\n');
41
-
42
- // Auto-stop after 60 seconds
43
- setTimeout(async () => {
44
- console.log('\n⏰ Demo completed!');
45
- console.log(`📊 Total windows auto-focused: ${windowCount}`);
46
- selector.setBringToFrontEnabled(false);
47
- await selector.cleanup();
48
- process.exit(0);
49
- }, 60000);
50
-
51
- // Manual stop
52
- process.on('SIGINT', async () => {
53
- console.log('\n\n🛑 Stopping demo...');
54
- console.log(`📊 Total windows auto-focused: ${windowCount}`);
55
- selector.setBringToFrontEnabled(false);
56
- await selector.cleanup();
57
- process.exit(0);
58
- });
59
-
60
- // Prevent exit
61
- setInterval(() => {}, 1000);
62
-
63
- } catch (error) {
64
- console.error('❌ Error:', error.message);
65
- await selector.cleanup();
66
- }
67
- }
68
-
69
- if (require.main === module) {
70
- autoBringToFrontDemo();
71
- }
@@ -1,182 +0,0 @@
1
- // ===== SENİN UYGULAMANDA NASIL KULLANACAĞIN =====
2
-
3
- const MacRecorder = require('node-mac-recorder'); // npm install node-mac-recorder
4
-
5
- async function myAppRecording() {
6
- const recorder = new MacRecorder();
7
-
8
- // === 1. KULLANICIYA SES CİHAZLARINI GÖSTER ===
9
- const devices = await recorder.getAudioDevices();
10
- console.log('🎤 Ses cihazları:');
11
- devices.forEach((d, i) => console.log(`${i+1}. ${d.name}`));
12
-
13
- // === 2. SİSTEM SESİ CİHAZINI BUL ===
14
- const systemDevice = devices.find(d =>
15
- d.name.includes('Aggregate') ||
16
- d.name.includes('iMobie') ||
17
- d.name.includes('BlackHole')
18
- );
19
-
20
- if (!systemDevice) {
21
- console.log('⚠️ Sistem ses cihazı yok. Sadece mikrofon kullanılacak.');
22
- }
23
-
24
- // === 3. KULLANICI TERCİHLERİ ===
25
- const userPrefs = {
26
- recordSystemAudio: true, // Kullanıcının sistem sesi tercihi
27
- recordMicrophone: false, // Kullanıcının mikrofon tercihi
28
- outputPath: './my-recording.mov'
29
- };
30
-
31
- // === 4. KAYIT BAŞLAT ===
32
- const options = {
33
- // Sistem sesi
34
- includeSystemAudio: userPrefs.recordSystemAudio,
35
- systemAudioDeviceId: systemDevice?.id, // Bulunan cihazı kullan
36
-
37
- // Mikrofon
38
- includeMicrophone: userPrefs.recordMicrophone,
39
-
40
- // Diğer seçenekler
41
- captureCursor: true,
42
- quality: 'high'
43
- };
44
-
45
- console.log('🔴 Kayıt başlıyor...', options);
46
- await recorder.startRecording(userPrefs.outputPath, options);
47
-
48
- // === 5. KAYDI DURDUR ===
49
- setTimeout(async () => {
50
- await recorder.stopRecording();
51
- console.log('✅ Kayıt bitti:', userPrefs.outputPath);
52
- }, 5000);
53
- }
54
-
55
- // === ELECTRONʼDA KULLANIM ===
56
- // main.js
57
- const { ipcMain } = require('electron');
58
- const MacRecorder = require('node-mac-recorder');
59
-
60
- const recorder = new MacRecorder();
61
-
62
- // Renderer'dan gelen istekleri dinle
63
- ipcMain.handle('get-audio-devices', async () => {
64
- return await recorder.getAudioDevices();
65
- });
66
-
67
- ipcMain.handle('start-recording', async (event, options) => {
68
- try {
69
- await recorder.startRecording('./recording.mov', {
70
- includeSystemAudio: options.systemAudio, // true/false
71
- includeMicrophone: options.microphone, // true/false
72
- systemAudioDeviceId: options.systemDeviceId || null
73
- });
74
- return { success: true };
75
- } catch (error) {
76
- return { success: false, error: error.message };
77
- }
78
- });
79
-
80
- ipcMain.handle('stop-recording', async () => {
81
- return await recorder.stopRecording();
82
- });
83
-
84
- // === REACTʼTE KULLANIM ===
85
- // renderer.js veya React component
86
- const { ipcRenderer } = require('electron');
87
-
88
- class RecordingComponent {
89
- async componentDidMount() {
90
- // Ses cihazlarını al
91
- this.audioDevices = await ipcRenderer.invoke('get-audio-devices');
92
- this.setState({ audioDevices: this.audioDevices });
93
- }
94
-
95
- async startRecording() {
96
- const options = {
97
- systemAudio: this.state.enableSystemAudio, // checkbox değeri
98
- microphone: this.state.enableMicrophone, // checkbox değeri
99
- systemDeviceId: this.state.selectedSystemDevice // dropdown değeri
100
- };
101
-
102
- const result = await ipcRenderer.invoke('start-recording', options);
103
- if (result.success) {
104
- this.setState({ recording: true });
105
- }
106
- }
107
-
108
- async stopRecording() {
109
- await ipcRenderer.invoke('stop-recording');
110
- this.setState({ recording: false });
111
- }
112
-
113
- render() {
114
- return (
115
- <div>
116
- <label>
117
- <input
118
- type="checkbox"
119
- checked={this.state.enableSystemAudio}
120
- onChange={e => this.setState({enableSystemAudio: e.target.checked})}
121
- />
122
- Sistem Sesini Kaydet
123
- </label>
124
-
125
- <select onChange={e => this.setState({selectedSystemDevice: e.target.value})}>
126
- {this.state.audioDevices?.map(device => (
127
- <option key={device.id} value={device.id}>
128
- {device.name}
129
- </option>
130
- ))}
131
- </select>
132
-
133
- <button onClick={() => this.startRecording()}>
134
- Kayıt Başlat
135
- </button>
136
- </div>
137
- );
138
- }
139
- }
140
-
141
- // === EXPRESS API ===
142
- const express = require('express');
143
- const MacRecorder = require('node-mac-recorder');
144
-
145
- const app = express();
146
- const recorder = new MacRecorder();
147
-
148
- app.use(express.json());
149
-
150
- // Ses cihazlarını listele
151
- app.get('/api/audio-devices', async (req, res) => {
152
- const devices = await recorder.getAudioDevices();
153
- res.json(devices);
154
- });
155
-
156
- // Kayıt başlat
157
- app.post('/api/start-recording', async (req, res) => {
158
- const { systemAudio, microphone, systemDeviceId } = req.body;
159
-
160
- try {
161
- await recorder.startRecording('./api-recording.mov', {
162
- includeSystemAudio: systemAudio, // true/false
163
- includeMicrophone: microphone, // true/false
164
- systemAudioDeviceId: systemDeviceId || null
165
- });
166
-
167
- res.json({ success: true, message: 'Recording started' });
168
- } catch (error) {
169
- res.status(500).json({ success: false, error: error.message });
170
- }
171
- });
172
-
173
- // Kayıt durdur
174
- app.post('/api/stop-recording', async (req, res) => {
175
- const result = await recorder.stopRecording();
176
- res.json(result);
177
- });
178
-
179
- // Test et
180
- if (require.main === module) {
181
- myAppRecording().catch(console.error);
182
- }
package/usage-examples.js DELETED
@@ -1,202 +0,0 @@
1
- const MacRecorder = require('./index');
2
-
3
- // ===== PARAMETRIK KULLANIM ÖRNEKLERİ =====
4
-
5
- async function examples() {
6
- const recorder = new MacRecorder();
7
-
8
- console.log('🎯 PARAMETRİK SİSTEM SESİ KULLANIMI\n');
9
-
10
- // 1. SİSTEM SESİ AÇIK (default)
11
- console.log('1️⃣ Sistem sesi AÇIK (default):');
12
- await recorder.startRecording('./output1.mov', {
13
- includeSystemAudio: true, // Default zaten true
14
- includeMicrophone: false
15
- });
16
- // ... kayıt yap ve durdur
17
-
18
- // 2. SİSTEM SESİ KAPALI
19
- console.log('2️⃣ Sistem sesi KAPALI:');
20
- await recorder.startRecording('./output2.mov', {
21
- includeSystemAudio: false, // Açıkça kapat
22
- includeMicrophone: true // Sadece mikrofon
23
- });
24
-
25
- // 3. BELİRLİ SES CİHAZI İLE
26
- console.log('3️⃣ Belirli sistem ses cihazı:');
27
-
28
- // Önce cihazları listele
29
- const devices = await recorder.getAudioDevices();
30
- const systemDevice = devices.find(d =>
31
- d.name.includes('iMobie') ||
32
- d.name.includes('BlackHole') ||
33
- d.name.includes('Aggregate')
34
- );
35
-
36
- if (systemDevice) {
37
- await recorder.startRecording('./output3.mov', {
38
- includeSystemAudio: true,
39
- systemAudioDeviceId: systemDevice.id, // Belirli cihaz
40
- includeMicrophone: false
41
- });
42
- }
43
-
44
- // 4. HER İKİSİ BİRDEN
45
- console.log('4️⃣ Sistem sesi + Mikrofon:');
46
- await recorder.startRecording('./output4.mov', {
47
- includeSystemAudio: true, // Sistem sesi
48
- includeMicrophone: true, // Mikrofon
49
- audioDeviceId: 'BuiltInMicrophoneDevice', // Mikrofon cihazı
50
- systemAudioDeviceId: systemDevice?.id // Sistem ses cihazı
51
- });
52
-
53
- console.log('✅ Tüm örnekler hazır!');
54
- }
55
-
56
- // BAŞKA UYGULAMADA KULLANIM
57
- async function usageInYourApp() {
58
- const recorder = new MacRecorder();
59
-
60
- // ===== SENİN UYGULAMANLA ENTEGRASYON =====
61
-
62
- // Kullanıcı ayarları
63
- const userSettings = {
64
- captureSystemAudio: true, // Kullanıcının seçimi
65
- captureMicrophone: false, // Kullanıcının seçimi
66
- preferredSystemAudioDevice: null // Kullanıcının seçtiği cihaz
67
- };
68
-
69
- // Cihazları al ve kullanıcıya göster
70
- const audioDevices = await recorder.getAudioDevices();
71
- const systemAudioDevices = audioDevices.filter(device =>
72
- device.name.toLowerCase().includes('aggregate') ||
73
- device.name.toLowerCase().includes('blackhole') ||
74
- device.name.toLowerCase().includes('soundflower') ||
75
- device.name.toLowerCase().includes('imobie')
76
- );
77
-
78
- console.log('🎤 Sistem ses cihazları:');
79
- systemAudioDevices.forEach((device, i) => {
80
- console.log(`${i + 1}. ${device.name}`);
81
- });
82
-
83
- // Kayıt başlat
84
- const recordingOptions = {
85
- includeSystemAudio: userSettings.captureSystemAudio,
86
- includeMicrophone: userSettings.captureMicrophone,
87
- };
88
-
89
- // Eğer kullanıcı belirli cihaz seçtiyse
90
- if (userSettings.preferredSystemAudioDevice) {
91
- recordingOptions.systemAudioDeviceId = userSettings.preferredSystemAudioDevice;
92
- }
93
-
94
- // Kayıt başlat
95
- await recorder.startRecording('./user-recording.mov', recordingOptions);
96
-
97
- console.log('🔴 Kayıt başladı...');
98
-
99
- // Gerektiğinde durdur
100
- setTimeout(async () => {
101
- await recorder.stopRecording();
102
- console.log('✅ Kayıt bitti!');
103
- }, 5000);
104
- }
105
-
106
- // ===== REACT/ELECTRON ÖRNEĞİ =====
107
- class AudioRecorderService {
108
- constructor() {
109
- this.recorder = new MacRecorder();
110
- this.isRecording = false;
111
- }
112
-
113
- async getAvailableSystemAudioDevices() {
114
- const devices = await this.recorder.getAudioDevices();
115
- return devices.filter(device =>
116
- device.name.toLowerCase().includes('aggregate') ||
117
- device.name.toLowerCase().includes('blackhole') ||
118
- device.name.toLowerCase().includes('imobie')
119
- );
120
- }
121
-
122
- async startRecording(options = {}) {
123
- const {
124
- outputPath,
125
- includeSystemAudio = true, // Default açık
126
- includeMicrophone = false,
127
- systemAudioDeviceId = null,
128
- audioDeviceId = null,
129
- windowId = null,
130
- displayId = null
131
- } = options;
132
-
133
- if (this.isRecording) {
134
- throw new Error('Already recording');
135
- }
136
-
137
- const recordingConfig = {
138
- includeSystemAudio,
139
- includeMicrophone,
140
- systemAudioDeviceId,
141
- audioDeviceId,
142
- windowId,
143
- displayId
144
- };
145
-
146
- await this.recorder.startRecording(outputPath, recordingConfig);
147
- this.isRecording = true;
148
-
149
- return { success: true, config: recordingConfig };
150
- }
151
-
152
- async stopRecording() {
153
- if (!this.isRecording) {
154
- throw new Error('Not recording');
155
- }
156
-
157
- const result = await this.recorder.stopRecording();
158
- this.isRecording = false;
159
-
160
- return result;
161
- }
162
-
163
- getRecordingStatus() {
164
- return {
165
- isRecording: this.isRecording,
166
- ...this.recorder.getStatus()
167
- };
168
- }
169
- }
170
-
171
- // KULLANIM ÖRNEĞİ
172
- async function exampleUsage() {
173
- const service = new AudioRecorderService();
174
-
175
- // Sistem ses cihazlarını listele
176
- const systemDevices = await service.getAvailableSystemAudioDevices();
177
- console.log('Mevcut sistem ses cihazları:', systemDevices);
178
-
179
- // Kayıt başlat - sistem sesi açık
180
- await service.startRecording({
181
- outputPath: './my-app-recording.mov',
182
- includeSystemAudio: true, // ✅ Sistem sesi
183
- includeMicrophone: false, // ❌ Mikrofon
184
- systemAudioDeviceId: systemDevices[0]?.id // İlk cihazı kullan
185
- });
186
-
187
- console.log('Recording started with system audio!');
188
-
189
- // 10 saniye sonra durdur
190
- setTimeout(async () => {
191
- await service.stopRecording();
192
- console.log('Recording finished!');
193
- }, 10000);
194
- }
195
-
196
- // Test et
197
- if (require.main === module) {
198
- console.log('🚀 Parametrik sistem sesi test ediliyor...\n');
199
- exampleUsage().catch(console.error);
200
- }
201
-
202
- module.exports = { AudioRecorderService };
@@ -1,94 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const WindowSelector = require('./window-selector');
4
-
5
- async function workingExample() {
6
- console.log('🎯 Window Selector - Working Example');
7
- console.log('====================================\n');
8
-
9
- const selector = new WindowSelector();
10
-
11
- try {
12
- console.log('Starting window selection...');
13
- console.log('Move cursor over different windows to see detection');
14
- console.log('The system will detect which window is under cursor');
15
- console.log('Press Ctrl+C to stop\n');
16
-
17
- let currentWindow = null;
18
-
19
- selector.on('windowEntered', (window) => {
20
- currentWindow = window;
21
- console.log(`\n🏠 ENTERED WINDOW:`);
22
- console.log(` App: ${window.appName}`);
23
- console.log(` Title: "${window.title}"`);
24
- console.log(` Position: (${window.x}, ${window.y})`);
25
- console.log(` Size: ${window.width} x ${window.height}`);
26
- console.log(` 💡 This window is now highlighted (overlay may not be visible due to macOS security)`);
27
- });
28
-
29
- selector.on('windowLeft', (window) => {
30
- console.log(`\n🚪 LEFT WINDOW: ${window.appName} - "${window.title}"`);
31
- currentWindow = null;
32
- });
33
-
34
- selector.on('windowSelected', (selectedWindow) => {
35
- console.log('\n🎉 WINDOW SELECTED!');
36
- console.log('==================');
37
- console.log(`App: ${selectedWindow.appName}`);
38
- console.log(`Title: "${selectedWindow.title}"`);
39
- console.log(`Position: (${selectedWindow.x}, ${selectedWindow.y})`);
40
- console.log(`Size: ${selectedWindow.width} x ${selectedWindow.height}`);
41
- console.log(`Screen: ${selectedWindow.screenId}`);
42
- process.exit(0);
43
- });
44
-
45
- // Manual selection trigger
46
- let readline = require('readline');
47
- const rl = readline.createInterface({
48
- input: process.stdin,
49
- output: process.stdout
50
- });
51
-
52
- console.log('💡 Pro tip: Press ENTER to select the current window under cursor');
53
- rl.on('line', () => {
54
- if (currentWindow) {
55
- console.log('\n✅ Manually selecting current window...');
56
- selector.emit('windowSelected', currentWindow);
57
- } else {
58
- console.log('\n⚠️ No window under cursor. Move cursor over a window first.');
59
- }
60
- });
61
-
62
- await selector.startSelection();
63
-
64
- // Status monitoring
65
- let statusCount = 0;
66
- const statusInterval = setInterval(() => {
67
- const status = selector.getStatus();
68
- statusCount++;
69
-
70
- if (statusCount % 20 === 0) { // Every 10 seconds
71
- console.log(`\n📊 Status (${statusCount/2}s): Windows detected: ${status.nativeStatus?.windowCount || 0}`);
72
- if (status.nativeStatus?.currentWindow) {
73
- console.log(` Current: ${status.nativeStatus.currentWindow.appName}`);
74
- }
75
- }
76
- }, 500);
77
-
78
- process.on('SIGINT', async () => {
79
- clearInterval(statusInterval);
80
- rl.close();
81
- console.log('\n🛑 Stopping window selector...');
82
- await selector.cleanup();
83
- console.log('✅ Cleanup completed');
84
- process.exit(0);
85
- });
86
-
87
- } catch (error) {
88
- console.error('\n❌ Error:', error.message);
89
- console.error(error.stack);
90
- process.exit(1);
91
- }
92
- }
93
-
94
- workingExample();