support progress bar while splash window is up

pull/702/head
Luke Pulverenti 11 years ago
parent 065a8ea21e
commit d00178d8f0

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

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

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

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

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

@ -2,13 +2,18 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 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"> 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"> <Border BorderBrush="DarkGray" BorderThickness="1">
<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"/> <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"> <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"/> <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 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>
</Grid> </Grid>

@ -1,16 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows; 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 namespace MediaBrowser.ServerApplication.Splash
{ {
@ -19,10 +9,33 @@ namespace MediaBrowser.ServerApplication.Splash
/// </summary> /// </summary>
public partial class SplashWindow : Window public partial class SplashWindow : Window
{ {
public SplashWindow(Version version) private readonly Progress<double> _progress;
public SplashWindow(Version version, Progress<double> progress)
{ {
InitializeComponent(); InitializeComponent();
lblStatus.Text = string.Format("Loading Media Browser Server\nVersion {0}...", version); 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);
} }
} }
} }

Loading…
Cancel
Save