160 lines
5.1 KiB
JavaScript
160 lines
5.1 KiB
JavaScript
const VoiceEngine = require('./discord_voice.node');
|
|
const ChildProcess = require('child_process');
|
|
const path = require('path');
|
|
const yargs = require('yargs');
|
|
|
|
const isElectronRenderer =
|
|
typeof window !== 'undefined' && window != null && window.DiscordNative && window.DiscordNative.isRenderer;
|
|
|
|
const appSettings = isElectronRenderer ? require('electron').remote.getGlobal('appSettings') : global.appSettings;
|
|
const features = isElectronRenderer ? require('electron').remote.getGlobal('features') : global.features;
|
|
const mainArgv = isElectronRenderer ? require('electron').remote.process.argv : [];
|
|
const releaseChannel = isElectronRenderer ? require('electron').remote.getGlobal('releaseChannel') : '';
|
|
const dialog = isElectronRenderer ? require('electron').remote.dialog : null;
|
|
const useLegacyAudioDevice = appSettings ? appSettings.get('useLegacyAudioDevice') : false;
|
|
const audioSubsystemSelected = appSettings
|
|
? appSettings.get('audioSubsystem') === 'legacy'
|
|
? 'legacy'
|
|
: 'standard'
|
|
: 'standard';
|
|
const audioSubsystem = useLegacyAudioDevice || audioSubsystemSelected;
|
|
const debugLogging = appSettings ? appSettings.get('debugLogging') : false;
|
|
|
|
const argv = yargs(mainArgv.slice(1))
|
|
.describe('log-level', 'Logging level.')
|
|
.default('log-level', -1)
|
|
.help('h')
|
|
.alias('h', 'help')
|
|
.exitProcess(false).argv;
|
|
const logLevel = argv['log-level'] == -1 ? (debugLogging ? 2 : -1) : argv['log-level'];
|
|
|
|
if (debugLogging && console.discordVoiceHooked == null) {
|
|
console.discordVoiceHooked = true;
|
|
|
|
for (const logFn of ['trace', 'debug', 'info', 'warn', 'error', 'log']) {
|
|
const originalLogFn = console[logFn];
|
|
|
|
if (originalLogFn != null) {
|
|
console[logFn] = function () {
|
|
originalLogFn.apply(this, arguments);
|
|
|
|
try {
|
|
VoiceEngine.consoleLog(
|
|
logFn,
|
|
JSON.stringify(Array.from(arguments).map((v) => (v != null ? v.toString() : v)))
|
|
);
|
|
} catch (e) {
|
|
// Drop errors from toString()/stringify.
|
|
}
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
features.declareSupported('voice_panning');
|
|
features.declareSupported('voice_multiple_connections');
|
|
features.declareSupported('media_devices');
|
|
features.declareSupported('media_video');
|
|
features.declareSupported('debug_logging');
|
|
features.declareSupported('set_audio_device_by_id');
|
|
features.declareSupported('set_video_device_by_id');
|
|
features.declareSupported('loopback');
|
|
features.declareSupported('experiment_config');
|
|
features.declareSupported('remote_locus_network_control');
|
|
features.declareSupported('connection_replay');
|
|
|
|
if (process.platform === 'win32') {
|
|
features.declareSupported('voice_legacy_subsystem');
|
|
features.declareSupported('soundshare');
|
|
features.declareSupported('wumpus_video');
|
|
features.declareSupported('hybrid_video');
|
|
features.declareSupported('elevated_hook');
|
|
features.declareSupported('soundshare_loopback');
|
|
features.declareSupported('screen_previews');
|
|
features.declareSupported('window_previews');
|
|
features.declareSupported('audio_debug_state');
|
|
// NOTE(jvass): currently there's no experimental encoders! Add this back if you
|
|
// add one and want to re-enable the UI for them.
|
|
// features.declareSupported('experimental_encoders');
|
|
}
|
|
|
|
const VoiceReplayConnection = VoiceEngine.VoiceReplayConnection;
|
|
|
|
delete VoiceEngine.VoiceReplayConnection;
|
|
|
|
VoiceEngine.createTransport = VoiceEngine._createTransport;
|
|
|
|
if (isElectronRenderer) {
|
|
VoiceEngine.setImageDataAllocator((width, height) => new window.ImageData(width, height));
|
|
}
|
|
|
|
if (dialog != null) {
|
|
VoiceEngine.createReplayConnection = function (audioEngineId, callback) {
|
|
const paths = dialog.showOpenDialogSync(null, {
|
|
filters: [{name: 'All Files', extensions: ['*']}],
|
|
});
|
|
|
|
if (paths == null || paths.length === 0) {
|
|
return null;
|
|
}
|
|
|
|
return new VoiceReplayConnection(paths[0], audioEngineId, callback);
|
|
};
|
|
}
|
|
|
|
VoiceEngine.setAudioSubsystem = function (subsystem) {
|
|
if (appSettings == null) {
|
|
console.warn('Unable to access app settings.');
|
|
return;
|
|
}
|
|
|
|
// TODO: With experiment controlling ADM selection, this may be incorrect since
|
|
// audioSubsystem is read from settings (or default if does not exists)
|
|
// and not the actual ADM used.
|
|
if (subsystem === audioSubsystem) {
|
|
return;
|
|
}
|
|
|
|
appSettings.set('audioSubsystem', subsystem);
|
|
appSettings.set('useLegacyAudioDevice', false);
|
|
appSettings.save();
|
|
|
|
reloadElectronApp();
|
|
};
|
|
|
|
VoiceEngine.setDebugLogging = function (enable) {
|
|
if (appSettings == null) {
|
|
console.warn('Unable to access app settings.');
|
|
return;
|
|
}
|
|
|
|
if (debugLogging === enable) {
|
|
return;
|
|
}
|
|
|
|
appSettings.set('debugLogging', enable);
|
|
|
|
appSettings.save();
|
|
reloadElectronApp();
|
|
};
|
|
|
|
VoiceEngine.getDebugLogging = function () {
|
|
return debugLogging;
|
|
};
|
|
|
|
reloadElectronApp = function () {
|
|
if (isElectronRenderer) {
|
|
const app = require('electron').remote.app;
|
|
app.relaunch();
|
|
app.exit(0);
|
|
} else {
|
|
ChildProcess.spawn(process.argv[0], process.argv.splice(1), {detached: true});
|
|
process.exit(0);
|
|
}
|
|
};
|
|
|
|
console.log(`Initializing voice engine with audio subsystem: ${audioSubsystem}`);
|
|
VoiceEngine.initialize({audioSubsystem, logLevel});
|
|
|
|
module.exports = VoiceEngine;
|