private void StartLivestreamer(string livestreamerArgs, string streamQuality, MessageBoxViewModel messageBoxViewModel, Action onClose = null)
        {
            if (!CheckLivestreamerExists())
            {
                return;
            }

            // the process needs to be launched from its own thread so it doesn't lockup the UI
            Task.Run(() =>
            {
                var proc = new Process
                {
                    StartInfo =
                    {
                        FileName  = settingsHandler.Settings.LivestreamerFullPath,
                        Arguments = livestreamerArgs,
                        RedirectStandardOutput = true,
                        RedirectStandardError  = true,
                        CreateNoWindow         = true,
                        UseShellExecute        = false
                    },
                    EnableRaisingEvents = true
                };

                bool preventClose = false;

                // see below for output handler
                proc.ErrorDataReceived +=
                    (sender, args) =>
                {
                    if (args.Data == null)
                    {
                        return;
                    }

                    preventClose = true;
                    messageBoxViewModel.MessageText += Environment.NewLine + args.Data;
                };
                proc.OutputDataReceived +=
                    (sender, args) =>
                {
                    if (args.Data == null)
                    {
                        return;
                    }
                    if (args.Data.StartsWith("[cli][info] Starting player") && settingsHandler.Settings.HideStreamOutputMessageBoxOnLoad)
                    {
                        messageBoxViewModel.TryClose();
                        // can continue adding messages, the view model still exists so it doesn't really matter
                    }

                    messageBoxViewModel.MessageText += Environment.NewLine + args.Data;
                };

                try
                {
                    proc.Start();

                    proc.BeginErrorReadLine();
                    proc.BeginOutputReadLine();

                    proc.WaitForExit();
                    if (proc.ExitCode != 0)
                    {
                        preventClose = true;
                    }

                    onClose?.Invoke();
                }
                catch (Exception ex)
                {
                    preventClose = true;
                    messageBoxViewModel.MessageText += Environment.NewLine + ex;
                }

                if (preventClose)
                {
                    messageBoxViewModel.MessageText += Environment.NewLine + Environment.NewLine +
                                                       $"ERROR occured in {settingsHandler.Settings.LivestreamExeDisplayName}: " +
                                                       $"Manually close this window when you've finished reading the {settingsHandler.Settings.LivestreamExeDisplayName} output.";

                    // open the message box if it was somehow closed prior to the error being displayed
                    if (!messageBoxViewModel.IsActive)
                    {
                        windowManager.ShowWindow(messageBoxViewModel, null, new WindowSettingsBuilder().SizeToContent().NoResizeBorderless().Create());
                    }
                }
                else if (string.IsNullOrEmpty(streamQuality))
                {
                    messageBoxViewModel.MessageText += Environment.NewLine + Environment.NewLine +
                                                       $"No stream quality provided: Manually close this window when you've finished reading the {settingsHandler.Settings.LivestreamExeDisplayName} output.";

                    if (!messageBoxViewModel.IsActive)
                    {
                        windowManager.ShowWindow(messageBoxViewModel, null, new WindowSettingsBuilder().SizeToContent().NoResizeBorderless().Create());
                    }
                }
                else
                {
                    messageBoxViewModel.TryClose();
                }
            });
        }