public async Task<FFMpegInfo> GetFFMpegInfo(StartupOptions options, IProgress<double> progress)
        {
            var customffMpegPath = options.GetOption("-ffmpeg");
            var customffProbePath = options.GetOption("-ffprobe");

            if (!string.IsNullOrWhiteSpace(customffMpegPath) && !string.IsNullOrWhiteSpace(customffProbePath))
            {
                return new FFMpegInfo
                {
                    ProbePath = customffProbePath,
                    EncoderPath = customffMpegPath,
                    Version = "custom"
                };
            }

            var rootEncoderPath = Path.Combine(_appPaths.ProgramDataPath, "ffmpeg");
            var versionedDirectoryPath = Path.Combine(rootEncoderPath, FFMpegDownloadInfo.Version);

            var info = new FFMpegInfo
            {
                ProbePath = Path.Combine(versionedDirectoryPath, FFMpegDownloadInfo.FFProbeFilename),
                EncoderPath = Path.Combine(versionedDirectoryPath, FFMpegDownloadInfo.FFMpegFilename),
                Version = FFMpegDownloadInfo.Version
            };

            Directory.CreateDirectory(versionedDirectoryPath);

            var excludeFromDeletions = new List<string> { versionedDirectoryPath };

            if (!File.Exists(info.ProbePath) || !File.Exists(info.EncoderPath))
            {
                // ffmpeg not present. See if there's an older version we can start with
                var existingVersion = GetExistingVersion(info, rootEncoderPath);

                // No older version. Need to download and block until complete
                if (existingVersion == null)
                {
                    await DownloadFFMpeg(versionedDirectoryPath, progress).ConfigureAwait(false);
                }
                else
                {
                    // Older version found. 
                    // Start with that. Download new version in the background.
                    var newPath = versionedDirectoryPath;
                    Task.Run(() => DownloadFFMpegInBackground(newPath));

                    info = existingVersion;
                    versionedDirectoryPath = Path.GetDirectoryName(info.EncoderPath);

                    excludeFromDeletions.Add(versionedDirectoryPath);
                }
            }

            await DownloadFonts(versionedDirectoryPath).ConfigureAwait(false);

            DeleteOlderFolders(Path.GetDirectoryName(versionedDirectoryPath), excludeFromDeletions);

            return info;
        }
Example #2
0
        /// <summary>
        /// Runs the application.
        /// </summary>
        /// <param name="appPaths">The app paths.</param>
        /// <param name="logManager">The log manager.</param>
        /// <param name="runService">if set to <c>true</c> [run service].</param>
        /// <param name="options">The options.</param>
        private static void RunApplication(ServerApplicationPaths appPaths, ILogManager logManager, bool runService, StartupOptions options)
        {
            _appHost = new ApplicationHost(appPaths, logManager, true, runService, options);

            var initProgress = new Progress<double>();

            if (!runService)
            {
                ShowSplashScreen(_appHost.ApplicationVersion, initProgress, logManager.GetLogger("Splash"));

                // Not crazy about this but it's the only way to suppress ffmpeg crash dialog boxes
                SetErrorMode(ErrorModes.SEM_FAILCRITICALERRORS | ErrorModes.SEM_NOALIGNMENTFAULTEXCEPT |
                             ErrorModes.SEM_NOGPFAULTERRORBOX | ErrorModes.SEM_NOOPENFILEERRORBOX);
            }

            var task = _appHost.Init(initProgress);
            task = task.ContinueWith(new Action<Task>(a => _appHost.RunStartupTasks()));

            if (runService)
            {
                StartService(logManager);
            }
            else
            {
                Task.WaitAll(task);

                SystemEvents.SessionEnding += SystemEvents_SessionEnding;
                SystemEvents.SessionSwitch += SystemEvents_SessionSwitch;

                HideSplashScreen();

                ShowTrayIcon();

                task = ApplicationTaskCompletionSource.Task;
                Task.WaitAll(task);
            }
        }
Example #3
0
        /// <summary>
        /// Defines the entry point of the application.
        /// </summary>
        public static void Main()
        {
            var options = new StartupOptions();
            _isRunningAsService = options.ContainsOption("-service");

            var applicationPath = Process.GetCurrentProcess().MainModule.FileName;

            var appPaths = CreateApplicationPaths(applicationPath, _isRunningAsService);

            var logManager = new NlogManager(appPaths.LogDirectoryPath, "server");
            logManager.ReloadLogger(LogSeverity.Debug);
            logManager.AddConsoleOutput();

            var logger = _logger = logManager.GetLogger("Main");

            BeginLog(logger, appPaths);

            // Install directly
            if (options.ContainsOption("-installservice"))
            {
                logger.Info("Performing service installation");
                InstallService(applicationPath, logger);
                return;
            }

            // Restart with admin rights, then install
            if (options.ContainsOption("-installserviceasadmin"))
            {
                logger.Info("Performing service installation");
                RunServiceInstallation(applicationPath);
                return;
            }

            // Uninstall directly
            if (options.ContainsOption("-uninstallservice"))
            {
                logger.Info("Performing service uninstallation");
                UninstallService(applicationPath, logger);
                return;
            }

            // Restart with admin rights, then uninstall
            if (options.ContainsOption("-uninstallserviceasadmin"))
            {
                logger.Info("Performing service uninstallation");
                RunServiceUninstallation(applicationPath);
                return;
            }

            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

            RunServiceInstallationIfNeeded(applicationPath);

            var currentProcess = Process.GetCurrentProcess();

            if (IsAlreadyRunning(applicationPath, currentProcess))
            {
                logger.Info("Shutting down because another instance of Media Browser Server is already running.");
                return;
            }

            if (PerformUpdateIfNeeded(appPaths, logger))
            {
                logger.Info("Exiting to perform application update.");
                return;
            }

            try
            {
                RunApplication(appPaths, logManager, _isRunningAsService, options);
            }
            finally
            {
                OnServiceShutdown();
            }
        }