Fixed linux client start crash when opening too many devices

master
WolverinDEV 2021-02-28 14:29:06 +01:00
parent d8ecb013c2
commit 6e93b76089
3 changed files with 75 additions and 20 deletions

View File

@ -1,4 +1,3 @@
import * as log from "./log";
import {LogCategory, logError, logTrace} from "./log";
import * as loader from "tc-loader";
import {Stage} from "tc-loader";
@ -773,6 +772,12 @@ export class Settings {
valueType: "boolean",
};
static readonly KEY_MICROPHONE_LEVEL_INDICATOR: RegistryKey<boolean> = {
key: "microphone_level_indicator",
description: "Enable/disable the microphone level indicator when opening the microphone settings. The default is true, except for the linux native client.",
valueType: "boolean",
};
static readonly FN_LOG_ENABLED: (category: string) => RegistryKey<boolean> = category => {
return {
key: "log." + category.toLowerCase() + ".enabled",

View File

@ -6,6 +6,8 @@ import {LogCategory, logTrace, logWarn} from "tc-shared/log";
import {defaultRecorder} from "tc-shared/voice/RecorderProfile";
import {DeviceListState, getRecorderBackend, IDevice} from "tc-shared/audio/recorder";
import {Settings, settings} from "tc-shared/settings";
import {getBackend} from "tc-shared/backend";
import * as _ from "lodash";
export type MicrophoneSetting =
"volume"
@ -48,8 +50,6 @@ export interface MicrophoneSettingsEvents {
"action_request_permissions": {},
"action_set_selected_device": { target: SelectedMicrophone },
"action_set_selected_device_result": {
status: "success",
} | {
status: "error",
reason: string
},
@ -96,6 +96,7 @@ export function initialize_audio_microphone_controller(events: Registry<Micropho
const levelMeterInitializePromises: { [key: string]: Promise<LevelMeter> } = {};
const deviceLevelInfo: { [key: string]: any } = {};
let deviceLevelUpdateTask;
let selectedDevice: SelectedMicrophone = { type: "none" };
const destroyLevelIndicators = () => {
Object.keys(levelMeterInitializePromises).forEach(e => {
@ -110,9 +111,39 @@ export function initialize_audio_microphone_controller(events: Registry<Micropho
const updateLevelMeter = () => {
destroyLevelIndicators();
let levelMeterEnabled;
{
let defaultValue = true;
if(__build.target === "client" && getBackend("native").getVersionInfo().os_platform === "linux") {
defaultValue = false;
}
levelMeterEnabled = settings.getValue(Settings.KEY_MICROPHONE_LEVEL_INDICATOR, defaultValue);
}
deviceLevelInfo["none"] = {deviceId: "none", status: "success", level: 0};
const defaultDeviceId = recorderBackend.getDeviceList().getDefaultDeviceId();
for (const device of recorderBackend.getDeviceList().getDevices()) {
let createLevelMeter;
if(!levelMeterEnabled) {
switch (selectedDevice.type) {
case "default":
createLevelMeter = device.deviceId == defaultDeviceId;
break;
case "device":
createLevelMeter = device.deviceId == selectedDevice.deviceId;
break;
case "none":
createLevelMeter = false;
break;
}
} else {
createLevelMeter = true;
}
if(createLevelMeter) {
let promise = recorderBackend.createLevelMeter(device).then(meter => {
meter.setObserver(level => {
if (levelMeterInitializePromises[device.deviceId] !== promise) {
@ -143,6 +174,14 @@ export function initialize_audio_microphone_controller(events: Registry<Micropho
return Promise.reject(error);
});
levelMeterInitializePromises[device.deviceId] = promise;
} else {
deviceLevelInfo[device.deviceId] = {
deviceId: device.deviceId,
status: "error",
error: tr("level meter disabled")
};
}
}
};
@ -160,6 +199,7 @@ export function initialize_audio_microphone_controller(events: Registry<Micropho
return;
}
selectedDevice = event.selectedDevice;
updateLevelMeter();
});
@ -167,6 +207,15 @@ export function initialize_audio_microphone_controller(events: Registry<Micropho
destroyLevelIndicators();
clearInterval(deviceLevelUpdateTask);
});
events.on("notify_device_selected", event => {
if(_.isEqual(selectedDevice, event.device)) {
return;
}
selectedDevice = event.device;
updateLevelMeter();
});
}
/* device list */

View File

@ -52,6 +52,7 @@ const ActivityBar = (props: { events: Registry<MicrophoneSettingsEvents>, device
}
props.events.reactUse("notify_device_level", event => {
refHider.current.style.width = "100%";
if (event.status === "uninitialized") {
if (status.mode === "uninitialized") {
return;