refactor(voice): drop the native only surface from voice_engine_v2 and narrow the desktop bridge (#1788)

This commit is contained in:
Hampus authored and GitHub committed 2026-08-20 17:44:37 +02:00
1 parent 9731bac40f
commit 4f21430880
43 files changed
+196 -3682

No files matched your search

+2 -2
View File
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import type {VoiceEngineV2BridgeApi} from '@fluxer/voice_engine_v2/bridge';
import type {VoiceEngineV2BridgeHardwareEncoderApi} from '@fluxer/voice_engine_v2/bridge';
import type {
AuthenticationResponseJSON,
PublicKeyCredentialCreationOptionsJSON,
@@ -777,7 +777,7 @@ export interface ElectronAPI {
virtmic: VirtmicApi;
nativeAudio: NativeAudioApi;
nativeScreenCapture: NativeScreenCaptureApi;
voiceEngine: VoiceEngineV2BridgeApi;
voiceEngine: VoiceEngineV2BridgeHardwareEncoderApi;
getDesktopSources: (
types: Array<'screen' | 'window'>,
requestId?: string,
@@ -5,7 +5,7 @@ import {createChildLogger} from '@electron/common/Logger';
import {
normalizeVoiceEngineV2BridgeHardwareEncoderCapabilities,
unavailableVoiceEngineV2BridgeHardwareEncoderCapabilities,
VOICE_ENGINE_V2_IPC_CHANNELS,
VOICE_ENGINE_V2_HARDWARE_ENCODER_IPC_CHANNEL,
type VoiceEngineV2BridgeHardwareEncoderCapabilities,
} from '@fluxer/voice_engine_v2/bridge';
import {ipcMain} from 'electron';
@@ -56,13 +56,13 @@ export function registerNativeHardwareEncoderHandlers(): void {
if (handlersRegistered) return;
handlersRegistered = true;
ipcMain.handle(
VOICE_ENGINE_V2_IPC_CHANNELS.getHardwareEncoderCapabilities,
VOICE_ENGINE_V2_HARDWARE_ENCODER_IPC_CHANNEL,
(): VoiceEngineV2BridgeHardwareEncoderCapabilities => getHardwareEncoderCapabilities(),
);
}
export function cleanupNativeHardwareEncoderHandlers(): void {
if (!handlersRegistered) return;
ipcMain.removeHandler(VOICE_ENGINE_V2_IPC_CHANNELS.getHardwareEncoderCapabilities);
ipcMain.removeHandler(VOICE_ENGINE_V2_HARDWARE_ENCODER_IPC_CHANNEL);
handlersRegistered = false;
}
+4 -85
View File
@@ -60,15 +60,9 @@ import type {
VirtmicRoutingGraphResult,
VirtmicSystemLinkOptions,
} from '@electron/common/Types';
import type {
VoiceEngineV2BridgeApi,
VoiceEngineV2BridgeEvent,
VoiceEngineV2BridgeVideoFrame,
} from '@fluxer/voice_engine_v2/bridge';
import {
VOICE_ENGINE_V2_BRIDGE_VERSION,
VOICE_ENGINE_V2_EVENT_CHANNELS,
VOICE_ENGINE_V2_IPC_CHANNELS,
VOICE_ENGINE_V2_HARDWARE_ENCODER_IPC_CHANNEL,
type VoiceEngineV2BridgeHardwareEncoderApi,
} from '@fluxer/voice_engine_v2/bridge';
import type {
AuthenticationResponseJSON,
@@ -138,18 +132,6 @@ function validateNativeScreenCaptureLifecycleMessage(value: unknown): NativeScre
: {captureId, kind: kind as NativeScreenCaptureLifecycleEventKind, message, source};
}
interface VoiceEngineV2BridgeVideoFrameWire {
meta: VoiceEngineV2BridgeVideoFrame['meta'];
data: Uint8Array<ArrayBuffer>;
}
function videoFrameWireDataToArrayBuffer(data: Uint8Array<ArrayBuffer>): ArrayBuffer {
if (data.byteOffset === 0 && data.byteLength === data.buffer.byteLength) {
return data.buffer;
}
return data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
}
function clampZoomLevel(level: number): number {
if (!Number.isFinite(level)) return 1;
const pct = Math.round(level * 100);
@@ -758,71 +740,8 @@ const api: ElectronAPI = {
},
},
voiceEngine: {
bridgeVersion: VOICE_ENGINE_V2_BRIDGE_VERSION,
isSupported: () => ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.isSupported),
getCapabilities: () => ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.getCapabilities),
prewarm: () => ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.prewarm),
getHardwareEncoderCapabilities: () =>
ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.getHardwareEncoderCapabilities),
connect: (options) => ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.connect, options),
disconnect: () => ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.disconnect),
isConnected: () => ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.isConnected),
publishMicrophone: (options) => ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.publishMicrophone, options),
pushPcm: (frame) => ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.pushPcm, frame),
publishScreen: (options) => ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.publishScreen, options),
updateScreenShareEncoding: (options) =>
ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.updateScreenShareEncoding, options),
unpublishScreen: () => ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.unpublishScreen),
publishScreenAudio: (options) => ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.publishScreenAudio, options),
pushScreenAudioPcm: (frame) => ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.pushScreenAudioPcm, frame),
pushScreenAudioFloat: (frame) => ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.pushScreenAudioFloat, frame),
unpublishScreenAudio: () => ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.unpublishScreenAudio),
setMicEnabled: (enabled) => ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.setMicEnabled, enabled),
setSpeakingDetection: (options) => ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.setSpeakingDetection, options),
listAudioInputDevices: () => ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.listAudioInputDevices),
listAudioOutputDevices: () => ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.listAudioOutputDevices),
setAudioOutputDevice: (deviceId) => ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.setAudioOutputDevice, deviceId),
setParticipantVolume: (participantSid, volume) =>
ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.setParticipantVolume, {participantSid, volume}),
setRemoteTrackSubscription: (options) =>
ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.setRemoteTrackSubscription, options),
publishData: (options) => ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.publishData, options),
listCameraDevices: () => ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.listCameraDevices),
publishCamera: (options) => ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.publishCamera, options),
publishNativeCameraSink: (options) =>
ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.publishNativeCameraSink, options),
publishProcessedCamera: (options) =>
ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.publishProcessedCamera, options),
pushProcessedCameraFrame: (frame) =>
ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.pushProcessedCameraFrame, frame),
pushCameraBackgroundFrame: (frame) =>
ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.pushCameraBackgroundFrame, frame),
clearCameraBackgroundFrame: () => ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.clearCameraBackgroundFrame),
updateCameraCapture: (options) => ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.updateCameraCapture, options),
publishDeviceScreenShare: (options) =>
ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.publishDeviceScreenShare, options),
unpublishCamera: () => ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.unpublishCamera),
isPublishingCamera: () => ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.isPublishingCamera),
startCameraPreview: (options) => ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.startCameraPreview, options),
stopCameraPreview: () => ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.stopCameraPreview),
getConnectionStats: () => ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.getConnectionStats),
getVoiceEngineReadiness: () => ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.getVoiceEngineReadiness),
getAudioDeviceModuleState: () => ipcRenderer.invoke(VOICE_ENGINE_V2_IPC_CHANNELS.getAudioDeviceModuleState),
onEvent: (callback) => {
const handler = (_event: Electron.IpcRendererEvent, payload: VoiceEngineV2BridgeEvent): void => {
callback(payload);
};
ipcRenderer.on(VOICE_ENGINE_V2_EVENT_CHANNELS.event, handler);
return () => ipcRenderer.removeListener(VOICE_ENGINE_V2_EVENT_CHANNELS.event, handler);
},
onVideoFrame: (callback) => {
const handler = (_event: Electron.IpcRendererEvent, payload: VoiceEngineV2BridgeVideoFrameWire): void => {
callback({meta: payload.meta, data: videoFrameWireDataToArrayBuffer(payload.data)});
};
ipcRenderer.on(VOICE_ENGINE_V2_EVENT_CHANNELS.videoFrame, handler);
return () => ipcRenderer.removeListener(VOICE_ENGINE_V2_EVENT_CHANNELS.videoFrame, handler);
},
} satisfies VoiceEngineV2BridgeApi,
getHardwareEncoderCapabilities: () => ipcRenderer.invoke(VOICE_ENGINE_V2_HARDWARE_ENCODER_IPC_CHANNEL),
} satisfies VoiceEngineV2BridgeHardwareEncoderApi,
};
window.addEventListener(