node-mac-recorder 2.17.21 → 2.18.1
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/cursor-data-1751364226346.json +1 -0
- package/cursor-data-1751364314136.json +1 -0
- package/cursor-data.json +1 -0
- package/index.js +152 -64
- package/package.json +1 -1
- package/publish.sh +31 -18
- package/src/cursor_tracker.mm +218 -456
- package/src/screen_capture_kit.mm +1 -34
- package/auto-front-demo.js +0 -71
- package/simple-api-example.js +0 -182
- package/usage-examples.js +0 -202
- package/working-example.js +0 -94
|
@@ -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;
|
package/auto-front-demo.js
DELETED
|
@@ -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
|
-
}
|
package/simple-api-example.js
DELETED
|
@@ -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 };
|
package/working-example.js
DELETED
|
@@ -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();
|