mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-17 13:05:32 +09:00
fix(voice): reuse the Linux audio capture across routing changes (#2440)
This commit is contained in:
1 parent
cc3a9c8613
commit
587324fa38
11 files changed
+206
-1
No files matched your search
@@ -430,6 +430,7 @@ export interface NativeAudioApi {
|
||||
listAudibleApplications: () => Promise<Array<NativeAudioApplication>>;
|
||||
resolveAudioRootPidForSource: (sourceId: string) => Promise<number | null>;
|
||||
start: (options: NativeAudioStartOptions) => Promise<NativeAudioStartResult>;
|
||||
setRule: (captureId: string, linuxRule: NonNullable<NativeAudioStartOptions['linuxRule']>) => Promise<boolean>;
|
||||
stop: (captureId: string) => Promise<void>;
|
||||
getRoutingGraph: (captureId?: string) => Promise<NativeAudioRoutingGraphResult>;
|
||||
onFrame: (callback: (message: NativeAudioFrameMessage) => void) => () => void;
|
||||
|
||||
@@ -40,6 +40,7 @@ interface NativeCaptureInstance {
|
||||
removeListener(event: 'closed', listener: () => void): this;
|
||||
start(): Promise<void> | void;
|
||||
stop(): Promise<void> | void;
|
||||
setRoutingRule?: (target: {linuxRule: NonNullable<NativeAudioStartOptions['linuxRule']>}) => boolean;
|
||||
routingGraph?: () => VirtmicRoutingGraph | null;
|
||||
}
|
||||
|
||||
@@ -631,6 +632,23 @@ async function stopCaptureById(
|
||||
await stopActiveSession(session, reason, detail);
|
||||
}
|
||||
|
||||
function reconfigureCaptureById(
|
||||
senderId: number,
|
||||
captureId: string,
|
||||
linuxRule: NonNullable<NativeAudioStartOptions['linuxRule']>,
|
||||
): boolean {
|
||||
const session = activeSessions.get(captureId);
|
||||
if (!session || session.sender.id !== senderId) return false;
|
||||
if (session.finalized || session.stopping) return false;
|
||||
if (typeof session.capture.setRoutingRule !== 'function') return false;
|
||||
try {
|
||||
return session.capture.setRoutingRule({linuxRule});
|
||||
} catch (error) {
|
||||
logger.warn('Failed to reconfigure native audio routing in place', {captureId, error});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async function makeRoomForSenderSession(senderId: number): Promise<void> {
|
||||
const senderSessions = activeSessionIdsBySenderId.get(senderId);
|
||||
if (!senderSessions) return;
|
||||
@@ -885,6 +903,15 @@ export function registerNativeAudioHandlers(): void {
|
||||
(event, options: NativeAudioStartOptions): Promise<NativeAudioStartResult> =>
|
||||
startNativeAudioCapture(event.sender, options),
|
||||
);
|
||||
ipcMain.handle(
|
||||
'native-audio:set-rule',
|
||||
(event, captureId: unknown, linuxRule: NativeAudioStartOptions['linuxRule']): boolean => {
|
||||
if (typeof captureId !== 'string' || !isValidLinuxRule(linuxRule)) {
|
||||
return false;
|
||||
}
|
||||
return reconfigureCaptureById(event.sender.id, captureId, linuxRule);
|
||||
},
|
||||
);
|
||||
ipcMain.handle('native-audio:stop', async (event, captureId: string): Promise<void> => {
|
||||
const session = activeSessions.get(captureId);
|
||||
if (!session || session.sender.id !== event.sender.id) {
|
||||
@@ -904,6 +931,7 @@ export function cleanupNativeAudio(): void {
|
||||
ipcMain.removeHandler('native-audio:list-applications');
|
||||
ipcMain.removeHandler('native-audio:resolve-root-pid');
|
||||
ipcMain.removeHandler('native-audio:start');
|
||||
ipcMain.removeHandler('native-audio:set-rule');
|
||||
ipcMain.removeHandler('native-audio:stop');
|
||||
ipcMain.removeHandler('native-audio:get-routing-graph');
|
||||
handlersRegistered = false;
|
||||
|
||||
@@ -684,6 +684,8 @@ const api: ElectronAPI = {
|
||||
ipcRenderer.invoke('native-audio:resolve-root-pid', sourceId),
|
||||
start: (options: NativeAudioStartOptions): Promise<NativeAudioStartResult> =>
|
||||
ipcRenderer.invoke('native-audio:start', options),
|
||||
setRule: (captureId: string, linuxRule: NonNullable<NativeAudioStartOptions['linuxRule']>): Promise<boolean> =>
|
||||
ipcRenderer.invoke('native-audio:set-rule', captureId, linuxRule),
|
||||
stop: (captureId: string): Promise<void> => ipcRenderer.invoke('native-audio:stop', captureId),
|
||||
getRoutingGraph: (captureId?: string): Promise<NativeAudioRoutingGraphResult> =>
|
||||
ipcRenderer.invoke('native-audio:get-routing-graph', captureId),
|
||||
|
||||
Reference in new issue
Block a user