瀏覽代碼

support progress bar while splash window is up

Luke Pulverenti 11 年之前
父節點
當前提交
d00178d8f0

+ 14 - 12
MediaBrowser.Common.Implementations/BaseApplicationHost.cs

@@ -9,6 +9,7 @@ using MediaBrowser.Common.Implementations.Updates;
 using MediaBrowser.Common.IO;
 using MediaBrowser.Common.Net;
 using MediaBrowser.Common.Plugins;
+using MediaBrowser.Common.Progress;
 using MediaBrowser.Common.ScheduledTasks;
 using MediaBrowser.Common.Security;
 using MediaBrowser.Common.Updates;
@@ -180,7 +181,7 @@ namespace MediaBrowser.Common.Implementations
         /// Inits this instance.
         /// </summary>
         /// <returns>Task.</returns>
-        public virtual async Task Init()
+        public virtual async Task Init(IProgress<double> progress)
         {
             try
             {
@@ -191,38 +192,39 @@ namespace MediaBrowser.Common.Implementations
             {
                 // Failing under mono
             }
+            progress.Report(1);
 
             JsonSerializer = CreateJsonSerializer();
 
             IsFirstRun = !ConfigurationManager.CommonConfiguration.IsStartupWizardCompleted;
+            progress.Report(2);
 
             Logger = LogManager.GetLogger("App");
 
             LogManager.LogSeverity = ConfigurationManager.CommonConfiguration.EnableDebugLevelLogging
                                          ? LogSeverity.Debug
                                          : LogSeverity.Info;
-
-            OnLoggerLoaded();
+            progress.Report(3);
 
             DiscoverTypes();
+            progress.Report(14);
 
             Logger.Info("Version {0} initializing", ApplicationVersion);
 
             SetHttpLimit();
+            progress.Report(15);
+
+            var innerProgress = new ActionableProgress<double>();
+            innerProgress.RegisterAction(p => progress.Report((.8 * p) + 15));
 
-            await RegisterResources().ConfigureAwait(false);
+            await RegisterResources(innerProgress).ConfigureAwait(false);
 
             FindParts();
+            progress.Report(95);
 
             await InstallIsoMounters(CancellationToken.None).ConfigureAwait(false);
-        }
-
-        /// <summary>
-        /// Called when [logger loaded].
-        /// </summary>
-        protected virtual void OnLoggerLoaded()
-        {
 
+            progress.Report(100);
         }
 
         protected virtual IJsonSerializer CreateJsonSerializer()
@@ -348,7 +350,7 @@ namespace MediaBrowser.Common.Implementations
         /// Registers resources that classes will depend on
         /// </summary>
         /// <returns>Task.</returns>
-        protected virtual Task RegisterResources()
+        protected virtual Task RegisterResources(IProgress<double> progress)
         {
             return Task.Run(() =>
             {

+ 2 - 1
MediaBrowser.Common/IApplicationHost.cs

@@ -129,8 +129,9 @@ namespace MediaBrowser.Common
         /// <summary>
         /// Inits this instance.
         /// </summary>
+        /// <param name="progress">The progress.</param>
         /// <returns>Task.</returns>
-        Task Init();
+        Task Init(IProgress<double> progress);
 
         /// <summary>
         /// Creates the instance.

+ 6 - 4
MediaBrowser.ServerApplication/App.xaml.cs

@@ -72,12 +72,14 @@ namespace MediaBrowser.ServerApplication
         {
             try
             {
+                var initProgress = new Progress<double>();
+
                 if (!IsRunningAsService)
                 {
-                    ShowSplashWindow();
+                    ShowSplashWindow(initProgress);
                 }
 
-                await _appHost.Init();
+                await _appHost.Init(initProgress);
 
                 var task = _appHost.RunStartupTasks();
 
@@ -131,9 +133,9 @@ namespace MediaBrowser.ServerApplication
         }
 
         private SplashWindow _splashWindow;
-        private void ShowSplashWindow()
+        private void ShowSplashWindow(Progress<double> progress)
         {
-            var win = new SplashWindow(_appHost.ApplicationVersion);
+            var win = new SplashWindow(_appHost.ApplicationVersion, progress);
             win.Show();
 
             _splashWindow = win;

+ 17 - 20
MediaBrowser.ServerApplication/ApplicationHost.cs

@@ -8,6 +8,7 @@ using MediaBrowser.Common.Implementations.ScheduledTasks;
 using MediaBrowser.Common.IO;
 using MediaBrowser.Common.MediaInfo;
 using MediaBrowser.Common.Net;
+using MediaBrowser.Common.Progress;
 using MediaBrowser.Controller;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Drawing;
@@ -170,8 +171,6 @@ namespace MediaBrowser.ServerApplication
         private IItemRepository ItemRepository { get; set; }
         private INotificationsRepository NotificationsRepository { get; set; }
 
-        private Task<IHttpServer> _httpServerCreationTask;
-
         /// <summary>
         /// Initializes a new instance of the <see cref="ApplicationHost"/> class.
         /// </summary>
@@ -215,25 +214,15 @@ namespace MediaBrowser.ServerApplication
             });
         }
 
-        /// <summary>
-        /// Called when [logger loaded].
-        /// </summary>
-        protected override void OnLoggerLoaded()
-        {
-            base.OnLoggerLoaded();
-
-            _httpServerCreationTask = Task.Run(() => ServerFactory.CreateServer(this, LogManager, "Media Browser", "mediabrowser", "dashboard/index.html"));
-        }
-
         /// <summary>
         /// Registers resources that classes will depend on
         /// </summary>
         /// <returns>Task.</returns>
-        protected override async Task RegisterResources()
+        protected override async Task RegisterResources(IProgress<double> progress)
         {
             ServerKernel = new Kernel();
 
-            await base.RegisterResources().ConfigureAwait(false);
+            await base.RegisterResources(progress).ConfigureAwait(false);
 
             RegisterSingleInstance<IHttpResultFactory>(new HttpResultFactory(LogManager, FileSystemManager));
 
@@ -247,8 +236,6 @@ namespace MediaBrowser.ServerApplication
 
             RegisterSingleInstance<IBlurayExaminer>(() => new BdInfoExaminer());
 
-            var mediaEncoderTask = RegisterMediaEncoder();
-
             UserDataManager = new UserDataManager(LogManager);
             RegisterSingleInstance(UserDataManager);
 
@@ -278,8 +265,9 @@ namespace MediaBrowser.ServerApplication
             SessionManager = new SessionManager(UserDataManager, ServerConfigurationManager, Logger, UserRepository, LibraryManager);
             RegisterSingleInstance(SessionManager);
 
-            HttpServer = await _httpServerCreationTask.ConfigureAwait(false);
+            HttpServer = ServerFactory.CreateServer(this, LogManager, "Media Browser", "mediabrowser", "dashboard/index.html");
             RegisterSingleInstance(HttpServer, false);
+            progress.Report(10);
 
             ServerManager = new ServerManager(this, JsonSerializer, Logger, ServerConfigurationManager);
             RegisterSingleInstance(ServerManager);
@@ -295,14 +283,23 @@ namespace MediaBrowser.ServerApplication
 
             LiveTvManager = new LiveTvManager(ApplicationPaths, FileSystemManager, Logger, ItemRepository, ImageProcessor, UserManager, LocalizationManager, UserDataManager, DtoService);
             RegisterSingleInstance(LiveTvManager);
+            progress.Report(15);
+
+            var innerProgress = new ActionableProgress<double>();
+            innerProgress.RegisterAction(p => progress.Report((.75 * p) + 15));
+
+            await RegisterMediaEncoder(innerProgress).ConfigureAwait(false);
+            progress.Report(90);
 
             var displayPreferencesTask = Task.Run(async () => await ConfigureDisplayPreferencesRepositories().ConfigureAwait(false));
             var itemsTask = Task.Run(async () => await ConfigureItemRepositories().ConfigureAwait(false));
             var userdataTask = Task.Run(async () => await ConfigureUserDataRepositories().ConfigureAwait(false));
 
             await ConfigureNotificationsRepository().ConfigureAwait(false);
+            progress.Report(92);
 
-            await Task.WhenAll(itemsTask, displayPreferencesTask, userdataTask, mediaEncoderTask).ConfigureAwait(false);
+            await Task.WhenAll(itemsTask, displayPreferencesTask, userdataTask).ConfigureAwait(false);
+            progress.Report(100);
 
             SetKernelProperties();
         }
@@ -321,9 +318,9 @@ namespace MediaBrowser.ServerApplication
         /// Registers the media encoder.
         /// </summary>
         /// <returns>Task.</returns>
-        private async Task RegisterMediaEncoder()
+        private async Task RegisterMediaEncoder(IProgress<double> progress)
         {
-            var info = await new FFMpegDownloader(Logger, ApplicationPaths, HttpClient, ZipClient, FileSystemManager).GetFFMpegInfo().ConfigureAwait(false);
+            var info = await new FFMpegDownloader(Logger, ApplicationPaths, HttpClient, ZipClient, FileSystemManager).GetFFMpegInfo(progress).ConfigureAwait(false);
 
             MediaEncoder = new MediaEncoder(LogManager.GetLogger("MediaEncoder"), ApplicationPaths, JsonSerializer, info.Path, info.ProbePath, info.Version, FileSystemManager);
             RegisterSingleInstance(MediaEncoder);

+ 53 - 19
MediaBrowser.ServerApplication/FFMpeg/FFMpegDownloader.cs

@@ -1,6 +1,7 @@
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Common.IO;
 using MediaBrowser.Common.Net;
+using MediaBrowser.Common.Progress;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Net;
@@ -36,7 +37,7 @@ namespace MediaBrowser.ServerApplication.FFMpeg
             _fileSystem = fileSystem;
         }
 
-        public async Task<FFMpegInfo> GetFFMpegInfo()
+        public async Task<FFMpegInfo> GetFFMpegInfo(IProgress<double> progress)
         {
             var versionedDirectoryPath = Path.Combine(GetMediaToolsPath(true), FFMpegDownloadInfo.Version);
 
@@ -51,25 +52,64 @@ namespace MediaBrowser.ServerApplication.FFMpeg
 
             var tasks = new List<Task>();
 
+            double ffmpegPercent = 0;
+            double fontPercent = 0;
+            var syncLock = new object();
+
             if (!File.Exists(info.ProbePath) || !File.Exists(info.Path))
             {
-                tasks.Add(DownloadFFMpeg(info));
+                var ffmpegProgress = new ActionableProgress<double>();
+                ffmpegProgress.RegisterAction(p =>
+                {
+                    ffmpegPercent = p;
+
+                    lock (syncLock)
+                    {
+                        progress.Report((ffmpegPercent / 2) + (fontPercent / 2));
+                    }
+                });
+
+                tasks.Add(DownloadFFMpeg(info, ffmpegProgress));
+            }
+            else
+            {
+                ffmpegPercent = 100;
+                progress.Report(50);
             }
 
-            tasks.Add(DownloadFonts(versionedDirectoryPath));
+            var fontProgress = new ActionableProgress<double>();
+            fontProgress.RegisterAction(p =>
+            {
+                fontPercent = p;
+
+                lock (syncLock)
+                {
+                    progress.Report((ffmpegPercent / 2) + (fontPercent / 2));
+                }
+            });
+
+            tasks.Add(DownloadFonts(versionedDirectoryPath, fontProgress));
 
             await Task.WhenAll(tasks).ConfigureAwait(false);
 
             return info;
         }
 
-        private async Task DownloadFFMpeg(FFMpegInfo info)
+        private async Task DownloadFFMpeg(FFMpegInfo info, IProgress<double> progress)
         {
             foreach (var url in FFMpegDownloadInfo.FfMpegUrls)
             {
+                progress.Report(0);
+
                 try
                 {
-                    var tempFile = await DownloadFFMpeg(info, url).ConfigureAwait(false);
+                    var tempFile = await _httpClient.GetTempFile(new HttpRequestOptions
+                    {
+                        Url = url,
+                        CancellationToken = CancellationToken.None,
+                        Progress = progress
+
+                    }).ConfigureAwait(false);
 
                     ExtractFFMpeg(tempFile, Path.GetDirectoryName(info.Path));
                     return;
@@ -83,16 +123,6 @@ namespace MediaBrowser.ServerApplication.FFMpeg
             throw new ApplicationException("Unable to download required components. Please try again later.");
         }
 
-        private Task<string> DownloadFFMpeg(FFMpegInfo info, string url)
-        {
-            return _httpClient.GetTempFile(new HttpRequestOptions
-            {
-                Url = url,
-                CancellationToken = CancellationToken.None,
-                Progress = new Progress<double>()
-            });
-        }
-
         private void ExtractFFMpeg(string tempFile, string targetFolder)
         {
             _logger.Debug("Extracting ffmpeg from {0}", tempFile);
@@ -157,7 +187,7 @@ namespace MediaBrowser.ServerApplication.FFMpeg
         /// Extracts the fonts.
         /// </summary>
         /// <param name="targetPath">The target path.</param>
-        private async Task DownloadFonts(string targetPath)
+        private async Task DownloadFonts(string targetPath, IProgress<double> progress)
         {
             try
             {
@@ -171,7 +201,7 @@ namespace MediaBrowser.ServerApplication.FFMpeg
 
                 if (!File.Exists(fontFile))
                 {
-                    await DownloadFontFile(fontsDirectory, fontFilename).ConfigureAwait(false);
+                    await DownloadFontFile(fontsDirectory, fontFilename, progress).ConfigureAwait(false);
                 }
 
                 await WriteFontConfigFile(fontsDirectory).ConfigureAwait(false);
@@ -186,6 +216,8 @@ namespace MediaBrowser.ServerApplication.FFMpeg
                 // Don't let the server crash because of this
                 _logger.ErrorException("Error writing ffmpeg font files", ex);
             }
+
+            progress.Report(100);
         }
 
         /// <summary>
@@ -194,7 +226,7 @@ namespace MediaBrowser.ServerApplication.FFMpeg
         /// <param name="fontsDirectory">The fonts directory.</param>
         /// <param name="fontFilename">The font filename.</param>
         /// <returns>Task.</returns>
-        private async Task DownloadFontFile(string fontsDirectory, string fontFilename)
+        private async Task DownloadFontFile(string fontsDirectory, string fontFilename, IProgress<double> progress)
         {
             var existingFile = Directory
                 .EnumerateFiles(_appPaths.ProgramDataPath, fontFilename, SearchOption.AllDirectories)
@@ -218,12 +250,14 @@ namespace MediaBrowser.ServerApplication.FFMpeg
 
             foreach (var url in _fontUrls)
             {
+                progress.Report(0);
+
                 try
                 {
                     tempFile = await _httpClient.GetTempFile(new HttpRequestOptions
                     {
                         Url = url,
-                        Progress = new Progress<double>()
+                        Progress = progress
 
                     }).ConfigureAwait(false);
 

+ 9 - 4
MediaBrowser.ServerApplication/Splash/SplashWindow.xaml

@@ -2,13 +2,18 @@
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         Height="386.939" Width="664.49" WindowStartupLocation="CenterScreen" Title="Media Browser Server" ShowInTaskbar="True" WindowStyle="None" BorderThickness="1" BorderBrush="#cccccc" AllowsTransparency="True">
-    <Border BorderBrush="DarkGray" BorderThickness="2" Margin="0,0,0,0">
-        <Grid Margin="-2,0,0,0">
-            <Image x:Name="imgLogo" HorizontalAlignment="Center" Height="146" Margin="0,10,44,0" VerticalAlignment="Top" Width="616" Source="/Resources/Images/mb3logo800.png" Opacity="0.5"/>
+    
+    <Border BorderBrush="DarkGray" BorderThickness="1">
+        <Grid>
+            
+            <Image HorizontalAlignment="Center" Height="146" Margin="0,10,44,0" VerticalAlignment="Top" Width="616" Source="/Resources/Images/mb3logo800.png" Opacity="0.5"/>
+            
             <Grid HorizontalAlignment="Left" Height="153" Margin="0,173,0,0" VerticalAlignment="Top" Width="662" Background="Gray">
+                
                 <TextBlock x:Name="lblStatus" HorizontalAlignment="Left" Margin="12,14,0,18" Width="637" FontSize="36" Foreground="#FFE6D7D7" Text="Loading Media Browser Server..." TextWrapping="WrapWithOverflow"/>
+                
                 <Rectangle Fill="#FF49494B" HorizontalAlignment="Left" Height="13" Stroke="Black" VerticalAlignment="Bottom" Width="662"/>
-                <Rectangle x:Name="rectProgress" Fill="#FF0A0ABF" HorizontalAlignment="Left" Height="13" Stroke="Black" VerticalAlignment="Bottom" Width="0"/>
+                <Rectangle x:Name="RectProgress" Fill="#52B54B" HorizontalAlignment="Left" Height="13" Stroke="Black" VerticalAlignment="Bottom" Width="0"/>
             </Grid>
         </Grid>
 

+ 25 - 12
MediaBrowser.ServerApplication/Splash/SplashWindow.xaml.cs

@@ -1,16 +1,6 @@
 using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using System.ComponentModel;
 using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Data;
-using System.Windows.Documents;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Imaging;
-using System.Windows.Shapes;
 
 namespace MediaBrowser.ServerApplication.Splash
 {
@@ -19,10 +9,33 @@ namespace MediaBrowser.ServerApplication.Splash
     /// </summary>
     public partial class SplashWindow : Window
     {
-        public SplashWindow(Version version)
+        private readonly Progress<double> _progress;
+
+        public SplashWindow(Version version, Progress<double> progress)
         {
             InitializeComponent();
             lblStatus.Text = string.Format("Loading Media Browser Server\nVersion {0}...", version);
+
+            _progress = progress;
+
+            progress.ProgressChanged += progress_ProgressChanged;
+        }
+
+        void progress_ProgressChanged(object sender, double e)
+        {
+            Dispatcher.InvokeAsync(() =>
+            {
+                var width = e * 6.62;
+
+                RectProgress.Width = width;
+            });
+        }
+
+        protected override void OnClosing(CancelEventArgs e)
+        {
+            _progress.ProgressChanged += progress_ProgressChanged;
+
+            base.OnClosing(e);
         }
     }
 }