mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-18 21:45:31 +09:00
refactor(voice): drop the native only surface from voice_engine_v2 and narrow the desktop bridge (#1788)
This commit is contained in:
1 parent
9731bac40f
commit
4f21430880
43 files changed
+196
-3682
No files matched your search
@@ -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;
|
||||
}
|
||||
@@ -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(
|
||||
|
||||
Reference in new issue
Block a user