feat: create virtual devices (+ Add Device dropdown)
Backend:
- POST /api/create-null-sink {name} - loads null-sink module
- POST /api/create-loopback {name} - loads loopback module
- POST /api/unload-module {module_id} - unloads a module
- Fixed double-proxy-destroy crash in GraphEngine
- Graceful failure when module not available (no crash)
Frontend:
- + Add Device button in toolbar with dropdown menu
- Null Sink option (creates virtual audio output)
- Loopback Device option (creates paired input+output)
- Dropdown closes on outside click
Note: null-sink requires libpipewire-module-null-sink to be installed.
Loopback works on all PipeWire installations.
This commit is contained in:
@@ -383,4 +383,47 @@ export async function setNodeMute(nodeId: number, mute: boolean) {
|
||||
}
|
||||
}
|
||||
|
||||
// Virtual devices
|
||||
export async function createNullSink(name: string): Promise<number | null> {
|
||||
try {
|
||||
const res = await fetch('/api/create-null-sink', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ name }),
|
||||
});
|
||||
const data = await res.json();
|
||||
return data.module_id || null;
|
||||
} catch (e) {
|
||||
console.error('[api] create-null-sink failed:', e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export async function createLoopback(name: string): Promise<number | null> {
|
||||
try {
|
||||
const res = await fetch('/api/create-loopback', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ name }),
|
||||
});
|
||||
const data = await res.json();
|
||||
return data.module_id || null;
|
||||
} catch (e) {
|
||||
console.error('[api] create-loopback failed:', e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export async function unloadModule(moduleId: number) {
|
||||
try {
|
||||
await fetch('/api/unload-module', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ module_id: moduleId }),
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('[api] unload-module failed:', e);
|
||||
}
|
||||
}
|
||||
|
||||
export { connectPorts, disconnectPorts };
|
||||
|
||||
Reference in New Issue
Block a user