Fixed linux client start crash when opening too many devices

This commit is contained in:
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 {LogCategory, logError, logTrace} from "./log";
import * as loader from "tc-loader"; import * as loader from "tc-loader";
import {Stage} from "tc-loader"; import {Stage} from "tc-loader";
@ -773,6 +772,12 @@ export class Settings {
valueType: "boolean", 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 => { static readonly FN_LOG_ENABLED: (category: string) => RegistryKey<boolean> = category => {
return { return {
key: "log." + category.toLowerCase() + ".enabled", 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 {defaultRecorder} from "tc-shared/voice/RecorderProfile";
import {DeviceListState, getRecorderBackend, IDevice} from "tc-shared/audio/recorder"; import {DeviceListState, getRecorderBackend, IDevice} from "tc-shared/audio/recorder";
import {Settings, settings} from "tc-shared/settings"; import {Settings, settings} from "tc-shared/settings";
import {getBackend} from "tc-shared/backend";
import * as _ from "lodash";
export type MicrophoneSetting = export type MicrophoneSetting =
"volume" "volume"
@ -48,8 +50,6 @@ export interface MicrophoneSettingsEvents {
"action_request_permissions": {}, "action_request_permissions": {},
"action_set_selected_device": { target: SelectedMicrophone }, "action_set_selected_device": { target: SelectedMicrophone },
"action_set_selected_device_result": { "action_set_selected_device_result": {
status: "success",
} | {
status: "error", status: "error",
reason: string reason: string
}, },
@ -96,6 +96,7 @@ export function initialize_audio_microphone_controller(events: Registry<Micropho
const levelMeterInitializePromises: { [key: string]: Promise<LevelMeter> } = {}; const levelMeterInitializePromises: { [key: string]: Promise<LevelMeter> } = {};
const deviceLevelInfo: { [key: string]: any } = {}; const deviceLevelInfo: { [key: string]: any } = {};
let deviceLevelUpdateTask; let deviceLevelUpdateTask;
let selectedDevice: SelectedMicrophone = { type: "none" };
const destroyLevelIndicators = () => { const destroyLevelIndicators = () => {
Object.keys(levelMeterInitializePromises).forEach(e => { Object.keys(levelMeterInitializePromises).forEach(e => {
@ -110,9 +111,39 @@ export function initialize_audio_microphone_controller(events: Registry<Micropho
const updateLevelMeter = () => { const updateLevelMeter = () => {
destroyLevelIndicators(); 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}; deviceLevelInfo["none"] = {deviceId: "none", status: "success", level: 0};
const defaultDeviceId = recorderBackend.getDeviceList().getDefaultDeviceId();
for (const device of recorderBackend.getDeviceList().getDevices()) { 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 => { let promise = recorderBackend.createLevelMeter(device).then(meter => {
meter.setObserver(level => { meter.setObserver(level => {
if (levelMeterInitializePromises[device.deviceId] !== promise) { if (levelMeterInitializePromises[device.deviceId] !== promise) {
@ -143,6 +174,14 @@ export function initialize_audio_microphone_controller(events: Registry<Micropho
return Promise.reject(error); return Promise.reject(error);
}); });
levelMeterInitializePromises[device.deviceId] = promise; 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; return;
} }
selectedDevice = event.selectedDevice;
updateLevelMeter(); updateLevelMeter();
}); });
@ -167,6 +207,15 @@ export function initialize_audio_microphone_controller(events: Registry<Micropho
destroyLevelIndicators(); destroyLevelIndicators();
clearInterval(deviceLevelUpdateTask); clearInterval(deviceLevelUpdateTask);
}); });
events.on("notify_device_selected", event => {
if(_.isEqual(selectedDevice, event.device)) {
return;
}
selectedDevice = event.device;
updateLevelMeter();
});
} }
/* device list */ /* device list */

View file

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