fix: API /admin/devices/list compatible macOS avec CoreAudio

Avant : Utilisait sox (IDs numériques, incomplet)
Après : Utilise CoreAudioBackend.getDevices() (noms devices réels)

- Retourne device.name comme ID (compatible inputDeviceName)
- Affiche channels, sampleRate, isDefault
- Fallback sur built-in devices si erreur
- Cohérent avec résolution AudioBridge (ligne 206-216)

Interface /admin maintenant 100% compatible macOS et Linux.
This commit is contained in:
2026-05-28 16:07:01 +02:00
parent 522a6255fe
commit d908cf4ee6
+29 -22
View File
@@ -679,39 +679,46 @@ router.get('/devices/list', async (req, res) => {
// Détection selon la plateforme // Détection selon la plateforme
if (process.platform === 'darwin') { if (process.platform === 'darwin') {
// macOS : utiliser CoreAudio via sox // macOS : utiliser CoreAudioBackend.getDevices()
const { exec } = await import('child_process');
const { promisify } = await import('util');
const execPromise = promisify(exec);
try { try {
// Utiliser sox pour lister les devices audio const coreAudioDevices = CoreAudioBackend.getDevices();
const { stdout } = await execPromise('sox -V6 2>&1');
// Parser la sortie sox pour extraire les devices // Séparer inputs et outputs
// Format typique : "Input Device [0]: MacBook Pro Microphone" coreAudioDevices.forEach(device => {
const inputMatches = stdout.matchAll(/Input Device \[(\d+)\]: (.+)/g); if (device.maxInputChannels > 0) {
const outputMatches = stdout.matchAll(/Output Device \[(\d+)\]: (.+)/g);
for (const match of inputMatches) {
devices.inputs.push({ devices.inputs.push({
id: parseInt(match[1], 10), id: device.name, // Utiliser le nom comme ID (compatible avec inputDeviceName)
name: match[2].trim() name: device.name,
channels: device.maxInputChannels,
sampleRate: device.defaultSampleRate,
isDefault: device.isDefault?.input || false
}); });
} }
for (const match of outputMatches) { if (device.maxOutputChannels > 0) {
devices.outputs.push({ devices.outputs.push({
id: parseInt(match[1], 10), id: device.name, // Utiliser le nom comme ID (compatible avec outputDeviceName)
name: match[2].trim() name: device.name,
channels: device.maxOutputChannels,
sampleRate: device.defaultSampleRate,
isDefault: device.isDefault?.output || false
}); });
} }
} catch (soxError) { });
console.warn('⚠️ sox non disponible, devices limités:', soxError.message);
// Fallback si aucun device trouvé
if (devices.inputs.length === 0) {
devices.inputs.push({ id: 'builtin-mic', name: 'Built-in Microphone', isDefault: true });
}
if (devices.outputs.length === 0) {
devices.outputs.push({ id: 'builtin-output', name: 'Built-in Output', isDefault: true });
}
} catch (error) {
console.warn('⚠️ Détection CoreAudio échouée:', error.message);
// Fallback : devices par défaut macOS // Fallback : devices par défaut macOS
devices.inputs.push({ id: 0, name: 'Default Input (Built-in Microphone)', isDefault: true }); devices.inputs.push({ id: 'builtin-mic', name: 'Built-in Microphone', isDefault: true });
devices.outputs.push({ id: 0, name: 'Default Output (Built-in Speakers)', isDefault: true }); devices.outputs.push({ id: 'builtin-output', name: 'Built-in Output', isDefault: true });
} }
} else if (process.platform === 'linux') { } else if (process.platform === 'linux') {