aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.ServerApplication
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.ServerApplication')
-rw-r--r--MediaBrowser.ServerApplication/App.xaml.cs53
-rw-r--r--MediaBrowser.ServerApplication/ApplicationHost.cs143
-rw-r--r--MediaBrowser.ServerApplication/EntryPoints/StartupWizard.cs14
-rw-r--r--MediaBrowser.ServerApplication/EntryPoints/UdpServerEntryPoint.cs95
-rw-r--r--MediaBrowser.ServerApplication/FFMpeg/FFMpegDownloader.cs302
-rw-r--r--MediaBrowser.ServerApplication/FFMpeg/FFMpegInfo.cs24
-rw-r--r--MediaBrowser.ServerApplication/FFMpeg/ffmpeg-20130904-git-f974289-win32-static.7z.REMOVED.git-id1
-rw-r--r--MediaBrowser.ServerApplication/Implementations/DotNetZipClient.cs43
-rw-r--r--MediaBrowser.ServerApplication/Implementations/FFMpegDownloader.cs205
-rw-r--r--MediaBrowser.ServerApplication/Implementations/ffmpeg20130904.zip.REMOVED.git-id1
-rw-r--r--MediaBrowser.ServerApplication/Implementations/readme.txt5
-rw-r--r--MediaBrowser.ServerApplication/MainStartup.cs1
-rw-r--r--MediaBrowser.ServerApplication/MainWindow.xaml.cs17
-rw-r--r--MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj25
-rw-r--r--MediaBrowser.ServerApplication/Native/Assemblies.cs25
-rw-r--r--MediaBrowser.ServerApplication/Native/Autorun.cs31
-rw-r--r--MediaBrowser.ServerApplication/Native/BrowserLauncher.cs68
-rw-r--r--MediaBrowser.ServerApplication/Native/HttpMessageHandlerFactory.cs26
-rw-r--r--MediaBrowser.ServerApplication/Native/NativeApp.cs25
-rw-r--r--MediaBrowser.ServerApplication/Native/RegisterServer.bat (renamed from MediaBrowser.ServerApplication/RegisterServer.bat)0
-rw-r--r--MediaBrowser.ServerApplication/Native/ServerAuthorization.cs56
-rw-r--r--MediaBrowser.ServerApplication/Native/Sqlite.cs36
-rw-r--r--MediaBrowser.ServerApplication/Resources/Images/mb3logo800.pngbin35600 -> 28816 bytes
-rw-r--r--MediaBrowser.ServerApplication/packages.config1
24 files changed, 669 insertions, 528 deletions
diff --git a/MediaBrowser.ServerApplication/App.xaml.cs b/MediaBrowser.ServerApplication/App.xaml.cs
index 69de391a4..706206d3a 100644
--- a/MediaBrowser.ServerApplication/App.xaml.cs
+++ b/MediaBrowser.ServerApplication/App.xaml.cs
@@ -154,58 +154,5 @@ namespace MediaBrowser.ServerApplication
{
Dispatcher.Invoke(Shutdown);
}
-
- /// <summary>
- /// Opens the dashboard page.
- /// </summary>
- /// <param name="page">The page.</param>
- /// <param name="loggedInUser">The logged in user.</param>
- /// <param name="configurationManager">The configuration manager.</param>
- /// <param name="appHost">The app host.</param>
- public static void OpenDashboardPage(string page, User loggedInUser, IServerConfigurationManager configurationManager, IServerApplicationHost appHost)
- {
- var url = "http://localhost:" + configurationManager.Configuration.HttpServerPortNumber + "/" +
- appHost.WebApplicationName + "/dashboard/" + page;
-
- OpenUrl(url);
- }
-
- /// <summary>
- /// Opens the URL.
- /// </summary>
- /// <param name="url">The URL.</param>
- public static void OpenUrl(string url)
- {
- var process = new Process
- {
- StartInfo = new ProcessStartInfo
- {
- FileName = url
- },
-
- EnableRaisingEvents = true
- };
-
- process.Exited += ProcessExited;
-
- try
- {
- process.Start();
- }
- catch (Exception ex)
- {
- MessageBox.Show("There was an error launching your web browser. Please check your defualt browser settings.");
- }
- }
-
- /// <summary>
- /// Processes the exited.
- /// </summary>
- /// <param name="sender">The sender.</param>
- /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
- static void ProcessExited(object sender, EventArgs e)
- {
- ((Process)sender).Dispose();
- }
}
}
diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs
index 5cae99785..d0f7da73d 100644
--- a/MediaBrowser.ServerApplication/ApplicationHost.cs
+++ b/MediaBrowser.ServerApplication/ApplicationHost.cs
@@ -24,7 +24,6 @@ using MediaBrowser.Controller.Providers;
using MediaBrowser.Controller.Resolvers;
using MediaBrowser.Controller.Session;
using MediaBrowser.Controller.Sorting;
-using MediaBrowser.IsoMounter;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.MediaInfo;
@@ -36,6 +35,7 @@ using MediaBrowser.Server.Implementations.BdInfo;
using MediaBrowser.Server.Implementations.Configuration;
using MediaBrowser.Server.Implementations.Drawing;
using MediaBrowser.Server.Implementations.Dto;
+using MediaBrowser.Server.Implementations.EntryPoints;
using MediaBrowser.Server.Implementations.HttpServer;
using MediaBrowser.Server.Implementations.IO;
using MediaBrowser.Server.Implementations.Library;
@@ -46,16 +46,14 @@ using MediaBrowser.Server.Implementations.Providers;
using MediaBrowser.Server.Implementations.ServerManager;
using MediaBrowser.Server.Implementations.Session;
using MediaBrowser.Server.Implementations.WebSocket;
-using MediaBrowser.ServerApplication.Implementations;
+using MediaBrowser.ServerApplication.FFMpeg;
+using MediaBrowser.ServerApplication.Native;
using MediaBrowser.WebDashboard.Api;
using System;
using System.Collections.Generic;
-using System.Data.SQLite;
-using System.Diagnostics;
+using System.Data;
using System.IO;
using System.Linq;
-using System.Net;
-using System.Net.Cache;
using System.Net.Http;
using System.Reflection;
using System.Threading;
@@ -68,8 +66,6 @@ namespace MediaBrowser.ServerApplication
/// </summary>
public class ApplicationHost : BaseApplicationHost<ServerApplicationPaths>, IServerApplicationHost
{
- internal const int UdpServerPort = 7359;
-
/// <summary>
/// Gets the server kernel.
/// </summary>
@@ -142,11 +138,6 @@ namespace MediaBrowser.ServerApplication
/// <value>The provider manager.</value>
private IProviderManager ProviderManager { get; set; }
/// <summary>
- /// Gets or sets the zip client.
- /// </summary>
- /// <value>The zip client.</value>
- private IZipClient ZipClient { get; set; }
- /// <summary>
/// Gets or sets the HTTP server.
/// </summary>
/// <value>The HTTP server.</value>
@@ -161,6 +152,7 @@ namespace MediaBrowser.ServerApplication
private IMediaEncoder MediaEncoder { get; set; }
private IIsoManager IsoManager { get; set; }
+ private ISessionManager SessionManager { get; set; }
private ILocalizationManager LocalizationManager { get; set; }
@@ -174,14 +166,6 @@ namespace MediaBrowser.ServerApplication
private IItemRepository ItemRepository { get; set; }
private INotificationsRepository NotificationsRepository { get; set; }
- /// <summary>
- /// The full path to our startmenu shortcut
- /// </summary>
- protected override string ProductShortcutPath
- {
- get { return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.StartMenu), "Media Browser 3", "Media Browser Server.lnk"); }
- }
-
private Task<IHttpServer> _httpServerCreationTask;
/// <summary>
@@ -255,8 +239,7 @@ namespace MediaBrowser.ServerApplication
RegisterSingleInstance<IBlurayExaminer>(() => new BdInfoExaminer());
- ZipClient = new DotNetZipClient();
- RegisterSingleInstance(ZipClient);
+ var mediaEncoderTask = RegisterMediaEncoder();
UserDataRepository = new SqliteUserDataRepository(ApplicationPaths, JsonSerializer, LogManager);
RegisterSingleInstance(UserDataRepository);
@@ -284,10 +267,8 @@ namespace MediaBrowser.ServerApplication
RegisterSingleInstance<ILibrarySearchEngine>(() => new LuceneSearchEngine(ApplicationPaths, LogManager, LibraryManager));
- await RegisterMediaEncoder().ConfigureAwait(false);
-
- var clientConnectionManager = new SessionManager(UserDataRepository, ServerConfigurationManager, Logger, UserRepository);
- RegisterSingleInstance<ISessionManager>(clientConnectionManager);
+ SessionManager = new SessionManager(UserDataRepository, ServerConfigurationManager, Logger, UserRepository);
+ RegisterSingleInstance<ISessionManager>(SessionManager);
HttpServer = await _httpServerCreationTask.ConfigureAwait(false);
RegisterSingleInstance(HttpServer, false);
@@ -310,7 +291,7 @@ namespace MediaBrowser.ServerApplication
await ConfigureNotificationsRepository().ConfigureAwait(false);
- await Task.WhenAll(itemsTask, displayPreferencesTask, userdataTask).ConfigureAwait(false);
+ await Task.WhenAll(itemsTask, displayPreferencesTask, userdataTask, mediaEncoderTask).ConfigureAwait(false);
SetKernelProperties();
}
@@ -406,27 +387,14 @@ namespace MediaBrowser.ServerApplication
/// <param name="dbPath">The db path.</param>
/// <returns>Task{IDbConnection}.</returns>
/// <exception cref="System.ArgumentNullException">dbPath</exception>
- private static async Task<SQLiteConnection> ConnectToDb(string dbPath)
+ private static Task<IDbConnection> ConnectToDb(string dbPath)
{
if (string.IsNullOrEmpty(dbPath))
{
throw new ArgumentNullException("dbPath");
}
- var connectionstr = new SQLiteConnectionStringBuilder
- {
- PageSize = 4096,
- CacheSize = 4096,
- SyncMode = SynchronizationModes.Normal,
- DataSource = dbPath,
- JournalMode = SQLiteJournalModeEnum.Wal
- };
-
- var connection = new SQLiteConnection(connectionstr.ConnectionString);
-
- await connection.OpenAsync().ConfigureAwait(false);
-
- return connection;
+ return Sqlite.OpenDatabase(dbPath);
}
/// <summary>
@@ -477,6 +445,8 @@ namespace MediaBrowser.ServerApplication
IsoManager.AddParts(GetExports<IIsoMounter>());
+ SessionManager.AddParts(GetExports<ISessionRemoteController>());
+
ImageProcessor.AddParts(GetExports<IImageEnhancer>());
}
@@ -527,7 +497,6 @@ namespace MediaBrowser.ServerApplication
{
NotifyPendingRestart();
}
-
}
/// <summary>
@@ -544,7 +513,7 @@ namespace MediaBrowser.ServerApplication
Logger.ErrorException("Error sending server restart web socket message", ex);
}
- MainStartup.Restart();
+ NativeApp.Restart();
}
/// <summary>
@@ -568,44 +537,44 @@ namespace MediaBrowser.ServerApplication
/// <returns>IEnumerable{Assembly}.</returns>
protected override IEnumerable<Assembly> GetComposablePartAssemblies()
{
+ var list = Directory.EnumerateFiles(ApplicationPaths.PluginsPath, "*.dll", SearchOption.TopDirectoryOnly)
+ .Select(LoadAssembly)
+ .Where(a => a != null)
+ .ToList();
+
// Gets all plugin assemblies by first reading all bytes of the .dll and calling Assembly.Load against that
// This will prevent the .dll file from getting locked, and allow us to replace it when needed
- foreach (var pluginAssembly in Directory
- .EnumerateFiles(ApplicationPaths.PluginsPath, "*.dll", SearchOption.TopDirectoryOnly)
- .Select(LoadAssembly).Where(a => a != null))
- {
- yield return pluginAssembly;
- }
// Include composable parts in the Api assembly
- yield return typeof(ApiEntryPoint).Assembly;
+ list.Add(typeof(ApiEntryPoint).Assembly);
// Include composable parts in the Dashboard assembly
- yield return typeof(DashboardInfo).Assembly;
+ list.Add(typeof(DashboardInfo).Assembly);
// Include composable parts in the Model assembly
- yield return typeof(SystemInfo).Assembly;
+ list.Add(typeof(SystemInfo).Assembly);
// Include composable parts in the Common assembly
- yield return typeof(IApplicationHost).Assembly;
+ list.Add(typeof(IApplicationHost).Assembly);
// Include composable parts in the Controller assembly
- yield return typeof(Kernel).Assembly;
+ list.Add(typeof(Kernel).Assembly);
// Include composable parts in the Providers assembly
- yield return typeof(ImagesByNameProvider).Assembly;
+ list.Add(typeof(ImagesByNameProvider).Assembly);
// Common implementations
- yield return typeof(TaskManager).Assembly;
+ list.Add(typeof(TaskManager).Assembly);
// Server implementations
- yield return typeof(ServerApplicationPaths).Assembly;
+ list.Add(typeof(ServerApplicationPaths).Assembly);
- // Pismo
- yield return typeof(PismoIsoManager).Assembly;
+ list.AddRange(Assemblies.GetAssembliesWithParts());
// Include composable parts in the running assembly
- yield return GetType().Assembly;
+ list.Add(GetType().Assembly);
+
+ return list;
}
private readonly string _systemId = Environment.MachineName.GetMD5().ToString();
@@ -664,7 +633,7 @@ namespace MediaBrowser.ServerApplication
Logger.ErrorException("Error sending server shutdown web socket message", ex);
}
- MainStartup.Shutdown();
+ NativeApp.Shutdown();
}
/// <summary>
@@ -674,36 +643,16 @@ namespace MediaBrowser.ServerApplication
{
Logger.Info("Requesting administrative access to authorize http server");
- // Create a temp file path to extract the bat file to
- var tmpFile = Path.Combine(ConfigurationManager.CommonApplicationPaths.TempDirectory, Guid.NewGuid() + ".bat");
-
- // Extract the bat file
- using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("MediaBrowser.ServerApplication.RegisterServer.bat"))
+ try
{
- using (var fileStream = File.Create(tmpFile))
- {
- stream.CopyTo(fileStream);
- }
+ ServerAuthorization.AuthorizeServer(ServerConfigurationManager.Configuration.HttpServerPortNumber,
+ HttpServerUrlPrefix, ServerConfigurationManager.Configuration.LegacyWebSocketPortNumber,
+ UdpServerEntryPoint.PortNumber,
+ ConfigurationManager.CommonApplicationPaths.TempDirectory);
}
-
- var startInfo = new ProcessStartInfo
- {
- FileName = tmpFile,
-
- Arguments = string.Format("{0} {1} {2} {3}", ServerConfigurationManager.Configuration.HttpServerPortNumber,
- HttpServerUrlPrefix,
- UdpServerPort,
- ServerConfigurationManager.Configuration.LegacyWebSocketPortNumber),
-
- CreateNoWindow = true,
- WindowStyle = ProcessWindowStyle.Hidden,
- Verb = "runas",
- ErrorDialog = false
- };
-
- using (var process = Process.Start(startInfo))
+ catch (Exception ex)
{
- process.WaitForExit();
+ Logger.ErrorException("Error authorizing server", ex);
}
}
@@ -713,8 +662,7 @@ namespace MediaBrowser.ServerApplication
/// <param name="cancellationToken">The cancellation token.</param>
/// <param name="progress">The progress.</param>
/// <returns>Task{CheckForUpdateResult}.</returns>
- public override async Task<CheckForUpdateResult> CheckForApplicationUpdate(CancellationToken cancellationToken,
- IProgress<double> progress)
+ public override async Task<CheckForUpdateResult> CheckForApplicationUpdate(CancellationToken cancellationToken, IProgress<double> progress)
{
var availablePackages = await InstallationManager.GetAvailablePackagesWithoutRegistrationInfo(cancellationToken).ConfigureAwait(false);
@@ -745,11 +693,12 @@ namespace MediaBrowser.ServerApplication
/// <returns>HttpMessageHandler.</returns>
protected override HttpMessageHandler GetHttpMessageHandler(bool enableHttpCompression)
{
- return new WebRequestHandler
- {
- CachePolicy = new RequestCachePolicy(RequestCacheLevel.Revalidate),
- AutomaticDecompression = enableHttpCompression ? DecompressionMethods.Deflate : DecompressionMethods.None
- };
+ return HttpMessageHandlerFactory.GetHttpMessageHandler(enableHttpCompression);
+ }
+
+ protected override void ConfigureAutoRunAtStartup(bool autorun)
+ {
+ Autorun.Configure(autorun);
}
}
}
diff --git a/MediaBrowser.ServerApplication/EntryPoints/StartupWizard.cs b/MediaBrowser.ServerApplication/EntryPoints/StartupWizard.cs
index 87578ef84..1a5f9e2c3 100644
--- a/MediaBrowser.ServerApplication/EntryPoints/StartupWizard.cs
+++ b/MediaBrowser.ServerApplication/EntryPoints/StartupWizard.cs
@@ -3,9 +3,10 @@ using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Plugins;
using MediaBrowser.Model.Logging;
-using System.ComponentModel;
+using System;
using System.Linq;
-using System.Windows;
+using System.Windows.Forms;
+using MediaBrowser.ServerApplication.Native;
namespace MediaBrowser.ServerApplication.EntryPoints
{
@@ -31,9 +32,10 @@ namespace MediaBrowser.ServerApplication.EntryPoints
/// </summary>
/// <param name="appHost">The app host.</param>
/// <param name="userManager">The user manager.</param>
- public StartupWizard(IServerApplicationHost appHost, IUserManager userManager, IServerConfigurationManager configurationManager)
+ public StartupWizard(IServerApplicationHost appHost, IUserManager userManager, IServerConfigurationManager configurationManager, ILogger logger)
{
_appHost = appHost;
+ _logger = logger;
_userManager = userManager;
_configurationManager = configurationManager;
}
@@ -58,9 +60,9 @@ namespace MediaBrowser.ServerApplication.EntryPoints
try
{
- App.OpenDashboardPage("wizardstart.html", user, _configurationManager, _appHost);
+ BrowserLauncher.OpenDashboardPage("wizardstart.html", user, _configurationManager, _appHost, _logger);
}
- catch (Win32Exception ex)
+ catch (Exception ex)
{
_logger.ErrorException("Error launching startup wizard", ex);
@@ -75,4 +77,4 @@ namespace MediaBrowser.ServerApplication.EntryPoints
{
}
}
-}
+} \ No newline at end of file
diff --git a/MediaBrowser.ServerApplication/EntryPoints/UdpServerEntryPoint.cs b/MediaBrowser.ServerApplication/EntryPoints/UdpServerEntryPoint.cs
deleted file mode 100644
index 595d5c89f..000000000
--- a/MediaBrowser.ServerApplication/EntryPoints/UdpServerEntryPoint.cs
+++ /dev/null
@@ -1,95 +0,0 @@
-using MediaBrowser.Common.Net;
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Plugins;
-using MediaBrowser.Model.Logging;
-using MediaBrowser.Server.Implementations.Udp;
-using System.Net.Sockets;
-
-namespace MediaBrowser.ServerApplication.EntryPoints
-{
- /// <summary>
- /// Class UdpServerEntryPoint
- /// </summary>
- public class UdpServerEntryPoint : IServerEntryPoint
- {
- /// <summary>
- /// Gets or sets the UDP server.
- /// </summary>
- /// <value>The UDP server.</value>
- private UdpServer UdpServer { get; set; }
-
- /// <summary>
- /// The _logger
- /// </summary>
- private readonly ILogger _logger;
- /// <summary>
- /// The _network manager
- /// </summary>
- private readonly INetworkManager _networkManager;
- /// <summary>
- /// The _server configuration manager
- /// </summary>
- private readonly IServerConfigurationManager _serverConfigurationManager;
- /// <summary>
- /// The _HTTP server
- /// </summary>
- private readonly IHttpServer _httpServer;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="UdpServerEntryPoint"/> class.
- /// </summary>
- /// <param name="logger">The logger.</param>
- /// <param name="networkManager">The network manager.</param>
- /// <param name="serverConfigurationManager">The server configuration manager.</param>
- /// <param name="httpServer">The HTTP server.</param>
- public UdpServerEntryPoint(ILogger logger, INetworkManager networkManager, IServerConfigurationManager serverConfigurationManager, IHttpServer httpServer)
- {
- _logger = logger;
- _networkManager = networkManager;
- _serverConfigurationManager = serverConfigurationManager;
- _httpServer = httpServer;
- }
-
- /// <summary>
- /// Runs this instance.
- /// </summary>
- public void Run()
- {
- var udpServer = new UdpServer(_logger, _networkManager, _serverConfigurationManager, _httpServer);
-
- try
- {
- udpServer.Start(ApplicationHost.UdpServerPort);
-
- UdpServer = udpServer;
- }
- catch (SocketException ex)
- {
- _logger.ErrorException("Failed to start UDP Server", ex);
- }
- }
-
- /// <summary>
- /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
- /// </summary>
- public void Dispose()
- {
- Dispose(true);
- }
-
- /// <summary>
- /// Releases unmanaged and - optionally - managed resources.
- /// </summary>
- /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
- protected virtual void Dispose(bool dispose)
- {
- if (dispose)
- {
- if (UdpServer != null)
- {
- UdpServer.Dispose();
- }
- }
- }
- }
-}
diff --git a/MediaBrowser.ServerApplication/FFMpeg/FFMpegDownloader.cs b/MediaBrowser.ServerApplication/FFMpeg/FFMpegDownloader.cs
new file mode 100644
index 000000000..926767f5b
--- /dev/null
+++ b/MediaBrowser.ServerApplication/FFMpeg/FFMpegDownloader.cs
@@ -0,0 +1,302 @@
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.IO;
+using MediaBrowser.Common.Net;
+using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Net;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.ServerApplication.FFMpeg
+{
+ public class FFMpegDownloader
+ {
+ private readonly IHttpClient _httpClient;
+ private readonly IApplicationPaths _appPaths;
+ private readonly ILogger _logger;
+ private readonly IZipClient _zipClient;
+
+ private const string Version = "ffmpeg20130904";
+
+ private readonly string[] _fontUrls = new[]
+ {
+ "https://www.dropbox.com/s/pj847twf7riq0j7/ARIALUNI.7z?dl=1"
+ };
+
+ private readonly string[] _ffMpegUrls = new[]
+ {
+ "https://github.com/MediaBrowser/MediaBrowser/raw/master/MediaBrowser.ServerApplication/FFMpeg/ffmpeg-20130904-git-f974289-win32-static.7z",
+
+ "http://ffmpeg.zeranoe.com/builds/win32/static/ffmpeg-20130904-git-f974289-win32-static.7z",
+ "https://www.dropbox.com/s/a81cb2ob23fwcfs/ffmpeg-20130904-git-f974289-win32-static.7z?dl=1"
+ };
+
+ public FFMpegDownloader(ILogger logger, IApplicationPaths appPaths, IHttpClient httpClient, IZipClient zipClient)
+ {
+ _logger = logger;
+ _appPaths = appPaths;
+ _httpClient = httpClient;
+ _zipClient = zipClient;
+ }
+
+ public async Task<FFMpegInfo> GetFFMpegInfo()
+ {
+ var versionedDirectoryPath = Path.Combine(GetMediaToolsPath(true), Version);
+
+ var info = new FFMpegInfo
+ {
+ ProbePath = Path.Combine(versionedDirectoryPath, "ffprobe.exe"),
+ Path = Path.Combine(versionedDirectoryPath, "ffmpeg.exe"),
+ Version = Version
+ };
+
+ if (!Directory.Exists(versionedDirectoryPath))
+ {
+ Directory.CreateDirectory(versionedDirectoryPath);
+ }
+
+ var tasks = new List<Task>();
+
+ if (!File.Exists(info.ProbePath) || !File.Exists(info.Path))
+ {
+ tasks.Add(DownloadFFMpeg(info));
+ }
+
+ tasks.Add(DownloadFonts(versionedDirectoryPath));
+
+ await Task.WhenAll(tasks).ConfigureAwait(false);
+
+ return info;
+ }
+
+ private async Task DownloadFFMpeg(FFMpegInfo info)
+ {
+ foreach (var url in _ffMpegUrls)
+ {
+ try
+ {
+ var tempFile = await DownloadFFMpeg(info, url).ConfigureAwait(false);
+
+ ExtractFFMpeg(tempFile, Path.GetDirectoryName(info.Path));
+ return;
+ }
+ catch (HttpException ex)
+ {
+
+ }
+ }
+
+ 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>(),
+
+ // Make it look like a browser
+ // Try to hide that we're direct linking
+ UserAgent = "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.47 Safari/537.36"
+ });
+ }
+
+ private void ExtractFFMpeg(string tempFile, string targetFolder)
+ {
+ _logger.Debug("Extracting ffmpeg from {0}", tempFile);
+
+ var tempFolder = Path.Combine(_appPaths.TempDirectory, Guid.NewGuid().ToString());
+
+ if (!Directory.Exists(tempFolder))
+ {
+ Directory.CreateDirectory(tempFolder);
+ }
+
+ try
+ {
+ Extract7zArchive(tempFile, tempFolder);
+
+ var files = Directory.EnumerateFiles(tempFolder, "*.exe", SearchOption.AllDirectories).ToList();
+
+ foreach (var file in files)
+ {
+ File.Copy(file, Path.Combine(targetFolder, Path.GetFileName(file)));
+ }
+ }
+ finally
+ {
+ DeleteFile(tempFile);
+ }
+ }
+
+ private void Extract7zArchive(string archivePath, string targetPath)
+ {
+ _zipClient.ExtractAllFrom7z(archivePath, targetPath, true);
+ }
+
+ private void DeleteFile(string path)
+ {
+ try
+ {
+ File.Delete(path);
+ }
+ catch (IOException ex)
+ {
+ _logger.ErrorException("Error deleting temp file {0}", ex, path);
+ }
+ }
+
+ /// <summary>
+ /// Extracts the fonts.
+ /// </summary>
+ /// <param name="targetPath">The target path.</param>
+ private async Task DownloadFonts(string targetPath)
+ {
+ try
+ {
+ var fontsDirectory = Path.Combine(targetPath, "fonts");
+
+ if (!Directory.Exists(fontsDirectory))
+ {
+ Directory.CreateDirectory(fontsDirectory);
+ }
+
+ const string fontFilename = "ARIALUNI.TTF";
+
+ var fontFile = Path.Combine(fontsDirectory, fontFilename);
+
+ if (!File.Exists(fontFile))
+ {
+ await DownloadFontFile(fontsDirectory, fontFilename).ConfigureAwait(false);
+ }
+
+ await WriteFontConfigFile(fontsDirectory).ConfigureAwait(false);
+ }
+ catch (HttpException ex)
+ {
+ // Don't let the server crash because of this
+ _logger.ErrorException("Error downloading ffmpeg font files", ex);
+ }
+ catch (Exception ex)
+ {
+ // Don't let the server crash because of this
+ _logger.ErrorException("Error writing ffmpeg font files", ex);
+ }
+ }
+
+ /// <summary>
+ /// Downloads the font file.
+ /// </summary>
+ /// <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)
+ {
+ var existingFile = Directory
+ .EnumerateFiles(_appPaths.ProgramDataPath, fontFilename, SearchOption.AllDirectories)
+ .FirstOrDefault();
+
+ if (existingFile != null)
+ {
+ try
+ {
+ File.Copy(existingFile, Path.Combine(fontsDirectory, fontFilename), true);
+ return;
+ }
+ catch (IOException ex)
+ {
+ // Log this, but don't let it fail the operation
+ _logger.ErrorException("Error copying file", ex);
+ }
+ }
+
+ string tempFile = null;
+
+ foreach (var url in _fontUrls)
+ {
+ try
+ {
+ tempFile = await _httpClient.GetTempFile(new HttpRequestOptions
+ {
+ Url = url,
+ Progress = new Progress<double>()
+
+ }).ConfigureAwait(false);
+
+ break;
+ }
+ catch (Exception ex)
+ {
+ // The core can function without the font file, so handle this
+ _logger.ErrorException("Failed to download ffmpeg font file from {0}", ex, url);
+ }
+ }
+
+ if (string.IsNullOrEmpty(tempFile))
+ {
+ return;
+ }
+
+ Extract7zArchive(tempFile, fontsDirectory);
+
+ try
+ {
+ File.Delete(tempFile);
+ }
+ catch (IOException ex)
+ {
+ // Log this, but don't let it fail the operation
+ _logger.ErrorException("Error deleting temp file {0}", ex, tempFile);
+ }
+ }
+
+ /// <summary>
+ /// Writes the font config file.
+ /// </summary>
+ /// <param name="fontsDirectory">The fonts directory.</param>
+ /// <returns>Task.</returns>
+ private async Task WriteFontConfigFile(string fontsDirectory)
+ {
+ const string fontConfigFilename = "fonts.conf";
+ var fontConfigFile = Path.Combine(fontsDirectory, fontConfigFilename);
+
+ if (!File.Exists(fontConfigFile))
+ {
+ var contents = string.Format("<?xml version=\"1.0\"?><fontconfig><dir>{0}</dir><alias><family>Arial</family><prefer>Arial Unicode MS</prefer></alias></fontconfig>", fontsDirectory);
+
+ var bytes = Encoding.UTF8.GetBytes(contents);
+
+ using (var fileStream = new FileStream(fontConfigFile, FileMode.Create, FileAccess.Write,
+ FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize,
+ FileOptions.Asynchronous))
+ {
+ await fileStream.WriteAsync(bytes, 0, bytes.Length);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the media tools path.
+ /// </summary>
+ /// <param name="create">if set to <c>true</c> [create].</param>
+ /// <returns>System.String.</returns>
+ private string GetMediaToolsPath(bool create)
+ {
+ var path = Path.Combine(_appPaths.ProgramDataPath, "ffmpeg");
+
+ if (create && !Directory.Exists(path))
+ {
+ Directory.CreateDirectory(path);
+ }
+
+ return path;
+ }
+ }
+}
diff --git a/MediaBrowser.ServerApplication/FFMpeg/FFMpegInfo.cs b/MediaBrowser.ServerApplication/FFMpeg/FFMpegInfo.cs
new file mode 100644
index 000000000..147a9f771
--- /dev/null
+++ b/MediaBrowser.ServerApplication/FFMpeg/FFMpegInfo.cs
@@ -0,0 +1,24 @@
+namespace MediaBrowser.ServerApplication.FFMpeg
+{
+ /// <summary>
+ /// Class FFMpegInfo
+ /// </summary>
+ public class FFMpegInfo
+ {
+ /// <summary>
+ /// Gets or sets the path.
+ /// </summary>
+ /// <value>The path.</value>
+ public string Path { get; set; }
+ /// <summary>
+ /// Gets or sets the probe path.
+ /// </summary>
+ /// <value>The probe path.</value>
+ public string ProbePath { get; set; }
+ /// <summary>
+ /// Gets or sets the version.
+ /// </summary>
+ /// <value>The version.</value>
+ public string Version { get; set; }
+ }
+} \ No newline at end of file
diff --git a/MediaBrowser.ServerApplication/FFMpeg/ffmpeg-20130904-git-f974289-win32-static.7z.REMOVED.git-id b/MediaBrowser.ServerApplication/FFMpeg/ffmpeg-20130904-git-f974289-win32-static.7z.REMOVED.git-id
new file mode 100644
index 000000000..9f83b949b
--- /dev/null
+++ b/MediaBrowser.ServerApplication/FFMpeg/ffmpeg-20130904-git-f974289-win32-static.7z.REMOVED.git-id
@@ -0,0 +1 @@
+8f1dfd62d31e48c31bef4b9ccc0e514f46650a79 \ No newline at end of file
diff --git a/MediaBrowser.ServerApplication/Implementations/DotNetZipClient.cs b/MediaBrowser.ServerApplication/Implementations/DotNetZipClient.cs
deleted file mode 100644
index 3b174a9b2..000000000
--- a/MediaBrowser.ServerApplication/Implementations/DotNetZipClient.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-using Ionic.Zip;
-using MediaBrowser.Model.IO;
-using System.IO;
-
-namespace MediaBrowser.ServerApplication.Implementations
-{
- /// <summary>
- /// Class DotNetZipClient
- /// </summary>
- public class DotNetZipClient : IZipClient
- {
- /// <summary>
- /// Extracts all.
- /// </summary>
- /// <param name="sourceFile">The source file.</param>
- /// <param name="targetPath">The target path.</param>
- /// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param>
- public void ExtractAll(string sourceFile, string targetPath, bool overwriteExistingFiles)
- {
- using (var fileStream = File.OpenRead(sourceFile))
- {
- using (var zipFile = ZipFile.Read(fileStream))
- {
- zipFile.ExtractAll(targetPath, overwriteExistingFiles ? ExtractExistingFileAction.OverwriteSilently : ExtractExistingFileAction.DoNotOverwrite);
- }
- }
- }
-
- /// <summary>
- /// Extracts all.
- /// </summary>
- /// <param name="source">The source.</param>
- /// <param name="targetPath">The target path.</param>
- /// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param>
- public void ExtractAll(Stream source, string targetPath, bool overwriteExistingFiles)
- {
- using (var zipFile = ZipFile.Read(source))
- {
- zipFile.ExtractAll(targetPath, overwriteExistingFiles ? ExtractExistingFileAction.OverwriteSilently : ExtractExistingFileAction.DoNotOverwrite);
- }
- }
- }
-}
diff --git a/MediaBrowser.ServerApplication/Implementations/FFMpegDownloader.cs b/MediaBrowser.ServerApplication/Implementations/FFMpegDownloader.cs
deleted file mode 100644
index 7fd0acddd..000000000
--- a/MediaBrowser.ServerApplication/Implementations/FFMpegDownloader.cs
+++ /dev/null
@@ -1,205 +0,0 @@
-using MediaBrowser.Common.Configuration;
-using MediaBrowser.Common.IO;
-using MediaBrowser.Common.Net;
-using MediaBrowser.Model.IO;
-using MediaBrowser.Model.Logging;
-using System;
-using System.IO;
-using System.Linq;
-using System.Reflection;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.ServerApplication.Implementations
-{
- public class FFMpegDownloader
- {
- private readonly IZipClient _zipClient;
- private readonly IHttpClient _httpClient;
- private readonly IApplicationPaths _appPaths;
- private readonly ILogger _logger;
-
- public FFMpegDownloader(ILogger logger, IApplicationPaths appPaths, IHttpClient httpClient, IZipClient zipClient)
- {
- _logger = logger;
- _appPaths = appPaths;
- _httpClient = httpClient;
- _zipClient = zipClient;
- }
-
- public async Task<FFMpegInfo> GetFFMpegInfo()
- {
- var assembly = GetType().Assembly;
-
- var prefix = GetType().Namespace + ".";
-
- var srch = prefix + "ffmpeg";
-
- var resource = assembly.GetManifestResourceNames().First(r => r.StartsWith(srch));
-
- var filename =
- resource.Substring(resource.IndexOf(prefix, StringComparison.OrdinalIgnoreCase) + prefix.Length);
-
- var versionedDirectoryPath = Path.Combine(GetMediaToolsPath(true),
- Path.GetFileNameWithoutExtension(filename));
-
- if (!Directory.Exists(versionedDirectoryPath))
- {
- Directory.CreateDirectory(versionedDirectoryPath);
- }
-
- await ExtractTools(assembly, resource, versionedDirectoryPath).ConfigureAwait(false);
-
- return new FFMpegInfo
- {
- ProbePath = Path.Combine(versionedDirectoryPath, "ffprobe.exe"),
- Path = Path.Combine(versionedDirectoryPath, "ffmpeg.exe"),
- Version = Path.GetFileNameWithoutExtension(versionedDirectoryPath)
- };
- }
-
- /// <summary>
- /// Extracts the tools.
- /// </summary>
- /// <param name="assembly">The assembly.</param>
- /// <param name="zipFileResourcePath">The zip file resource path.</param>
- /// <param name="targetPath">The target path.</param>
- private async Task ExtractTools(Assembly assembly, string zipFileResourcePath, string targetPath)
- {
- using (var resourceStream = assembly.GetManifestResourceStream(zipFileResourcePath))
- {
- _zipClient.ExtractAll(resourceStream, targetPath, false);
- }
-
- try
- {
- await DownloadFonts(targetPath).ConfigureAwait(false);
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error getting ffmpeg font files", ex);
- }
- }
-
- private const string FontUrl = "https://www.dropbox.com/s/9nb76tybcsw5xrk/ARIALUNI.zip?dl=1";
-
- /// <summary>
- /// Extracts the fonts.
- /// </summary>
- /// <param name="targetPath">The target path.</param>
- private async Task DownloadFonts(string targetPath)
- {
- var fontsDirectory = Path.Combine(targetPath, "fonts");
-
- if (!Directory.Exists(fontsDirectory))
- {
- Directory.CreateDirectory(fontsDirectory);
- }
-
- const string fontFilename = "ARIALUNI.TTF";
-
- var fontFile = Path.Combine(fontsDirectory, fontFilename);
-
- if (!File.Exists(fontFile))
- {
- await DownloadFontFile(fontsDirectory, fontFilename).ConfigureAwait(false);
- }
-
- await WriteFontConfigFile(fontsDirectory).ConfigureAwait(false);
- }
-
- /// <summary>
- /// Downloads the font file.
- /// </summary>
- /// <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)
- {
- var existingFile = Directory
- .EnumerateFiles(_appPaths.ProgramDataPath, fontFilename, SearchOption.AllDirectories)
- .FirstOrDefault();
-
- if (existingFile != null)
- {
- try
- {
- File.Copy(existingFile, Path.Combine(fontsDirectory, fontFilename), true);
- return;
- }
- catch (IOException ex)
- {
- // Log this, but don't let it fail the operation
- _logger.ErrorException("Error copying file", ex);
- }
- }
-
- var tempFile = await _httpClient.GetTempFile(new HttpRequestOptions
- {
- Url = FontUrl,
- Progress = new Progress<double>()
- });
-
- _zipClient.ExtractAll(tempFile, fontsDirectory, true);
-
- try
- {
- File.Delete(tempFile);
- }
- catch (IOException ex)
- {
- // Log this, but don't let it fail the operation
- _logger.ErrorException("Error deleting temp file {0}", ex, tempFile);
- }
- }
-
- /// <summary>
- /// Writes the font config file.
- /// </summary>
- /// <param name="fontsDirectory">The fonts directory.</param>
- /// <returns>Task.</returns>
- private async Task WriteFontConfigFile(string fontsDirectory)
- {
- const string fontConfigFilename = "fonts.conf";
- var fontConfigFile = Path.Combine(fontsDirectory, fontConfigFilename);
-
- if (!File.Exists(fontConfigFile))
- {
- var contents = string.Format("<?xml version=\"1.0\"?><fontconfig><dir>{0}</dir><alias><family>Arial</family><prefer>Arial Unicode MS</prefer></alias></fontconfig>", fontsDirectory);
-
- var bytes = Encoding.UTF8.GetBytes(contents);
-
- using (var fileStream = new FileStream(fontConfigFile, FileMode.Create, FileAccess.Write,
- FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize,
- FileOptions.Asynchronous))
- {
- await fileStream.WriteAsync(bytes, 0, bytes.Length);
- }
- }
- }
-
- /// <summary>
- /// Gets the media tools path.
- /// </summary>
- /// <param name="create">if set to <c>true</c> [create].</param>
- /// <returns>System.String.</returns>
- private string GetMediaToolsPath(bool create)
- {
- var path = Path.Combine(_appPaths.ProgramDataPath, "ffmpeg");
-
- if (create && !Directory.Exists(path))
- {
- Directory.CreateDirectory(path);
- }
-
- return path;
- }
- }
-
- public class FFMpegInfo
- {
- public string Path { get; set; }
- public string ProbePath { get; set; }
- public string Version { get; set; }
- }
-}
diff --git a/MediaBrowser.ServerApplication/Implementations/ffmpeg20130904.zip.REMOVED.git-id b/MediaBrowser.ServerApplication/Implementations/ffmpeg20130904.zip.REMOVED.git-id
deleted file mode 100644
index e99d115a4..000000000
--- a/MediaBrowser.ServerApplication/Implementations/ffmpeg20130904.zip.REMOVED.git-id
+++ /dev/null
@@ -1 +0,0 @@
-3496b2cde22e7c4cb56b480dd2da637167d51e78 \ No newline at end of file
diff --git a/MediaBrowser.ServerApplication/Implementations/readme.txt b/MediaBrowser.ServerApplication/Implementations/readme.txt
deleted file mode 100644
index b32dd9aec..000000000
--- a/MediaBrowser.ServerApplication/Implementations/readme.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is the 32-bit static build of ffmpeg, located at:
-
-http://ffmpeg.zeranoe.com/builds/
-
-The zip file contains both ffmpeg and ffprobe, and is suffixed with the date of the build. \ No newline at end of file
diff --git a/MediaBrowser.ServerApplication/MainStartup.cs b/MediaBrowser.ServerApplication/MainStartup.cs
index e9c1fdc99..55fa60ed2 100644
--- a/MediaBrowser.ServerApplication/MainStartup.cs
+++ b/MediaBrowser.ServerApplication/MainStartup.cs
@@ -11,7 +11,6 @@ using System.IO;
using System.Linq;
using System.ServiceProcess;
using System.Threading;
-using System.Threading.Tasks;
using System.Windows;
namespace MediaBrowser.ServerApplication
diff --git a/MediaBrowser.ServerApplication/MainWindow.xaml.cs b/MediaBrowser.ServerApplication/MainWindow.xaml.cs
index 4c9c065e6..c22c35be8 100644
--- a/MediaBrowser.ServerApplication/MainWindow.xaml.cs
+++ b/MediaBrowser.ServerApplication/MainWindow.xaml.cs
@@ -12,6 +12,7 @@ using System.Diagnostics;
using System.Linq;
using System.Windows;
using System.Windows.Threading;
+using MediaBrowser.ServerApplication.Native;
namespace MediaBrowser.ServerApplication
{
@@ -188,19 +189,19 @@ namespace MediaBrowser.ServerApplication
/// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
void cmdApiDocs_Click(object sender, EventArgs e)
{
- App.OpenUrl("http://localhost:" + _configurationManager.Configuration.HttpServerPortNumber + "/" +
- _appHost.WebApplicationName + "/metadata");
+ BrowserLauncher.OpenUrl("http://localhost:" + _configurationManager.Configuration.HttpServerPortNumber + "/" +
+ _appHost.WebApplicationName + "/metadata", _logger);
}
void cmdSwaggerApiDocs_Click(object sender, EventArgs e)
{
- App.OpenUrl("http://localhost:" + _configurationManager.Configuration.HttpServerPortNumber + "/" +
- _appHost.WebApplicationName + "/swagger-ui/index.html");
+ BrowserLauncher.OpenUrl("http://localhost:" + _configurationManager.Configuration.HttpServerPortNumber + "/" +
+ _appHost.WebApplicationName + "/swagger-ui/index.html", _logger);
}
void cmdGithubWiki_Click(object sender, EventArgs e)
{
- App.OpenUrl("https://github.com/MediaBrowser/MediaBrowser/wiki");
+ BrowserLauncher.OpenUrl("https://github.com/MediaBrowser/MediaBrowser/wiki", _logger);
}
/// <summary>
@@ -254,7 +255,7 @@ namespace MediaBrowser.ServerApplication
/// </summary>
private void OpenDashboard(User loggedInUser)
{
- App.OpenDashboardPage("dashboard.html", loggedInUser, _configurationManager, _appHost);
+ BrowserLauncher.OpenDashboardPage("dashboard.html", loggedInUser, _configurationManager, _appHost, _logger);
}
/// <summary>
@@ -264,7 +265,7 @@ namespace MediaBrowser.ServerApplication
/// <param name="e">The <see cref="RoutedEventArgs" /> instance containing the event data.</param>
private void cmVisitCT_click(object sender, RoutedEventArgs e)
{
- App.OpenUrl("http://community.mediabrowser.tv/");
+ BrowserLauncher.OpenUrl("http://community.mediabrowser.tv/", _logger);
}
/// <summary>
@@ -275,7 +276,7 @@ namespace MediaBrowser.ServerApplication
private void cmdBrowseLibrary_click(object sender, RoutedEventArgs e)
{
var user = _userManager.Users.FirstOrDefault(u => u.Configuration.IsAdministrator);
- App.OpenDashboardPage("index.html", user, _configurationManager, _appHost);
+ BrowserLauncher.OpenDashboardPage("index.html", user, _configurationManager, _appHost, _logger);
}
/// <summary>
diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj
index 043d5c18f..61ec19dd5 100644
--- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj
+++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj
@@ -130,10 +130,6 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\MediaBrowser.IsoMounting.3.0.56\lib\net45\MediaBrowser.IsoMounter.dll</HintPath>
</Reference>
- <Reference Include="MoreLinq, Version=1.0.16006.0, Culture=neutral, PublicKeyToken=384d532d7e88985d, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\morelinq.1.0.16006\lib\net35\MoreLinq.dll</HintPath>
- </Reference>
<Reference Include="NLog, Version=2.0.1.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\NLog.2.0.1.2\lib\net45\NLog.dll</HintPath>
@@ -187,7 +183,6 @@
<Reference Include="System.Net" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Net.Http.WebRequest" />
- <Reference Include="System.Runtime.Remoting" />
<Reference Include="System.ServiceProcess" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Windows.Interactivity, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
@@ -209,12 +204,19 @@
<SubType>Component</SubType>
</Compile>
<Compile Include="EntryPoints\StartupWizard.cs" />
- <Compile Include="EntryPoints\UdpServerEntryPoint.cs" />
- <Compile Include="Implementations\FFMpegDownloader.cs" />
+ <Compile Include="FFMpeg\FFMpegInfo.cs" />
+ <Compile Include="Native\Assemblies.cs" />
+ <Compile Include="Native\HttpMessageHandlerFactory.cs" />
+ <Compile Include="Native\NativeApp.cs" />
+ <Compile Include="Native\ServerAuthorization.cs" />
+ <Compile Include="Native\Autorun.cs" />
+ <Compile Include="Native\BrowserLauncher.cs" />
+ <Compile Include="FFMpeg\FFMpegDownloader.cs" />
<Compile Include="MainStartup.cs" />
<Compile Include="BackgroundServiceInstaller.cs">
<SubType>Component</SubType>
</Compile>
+ <Compile Include="Native\Sqlite.cs" />
<Compile Include="Splash\SplashWindow.xaml.cs">
<DependentUpon>SplashWindow.xaml</DependentUpon>
</Compile>
@@ -242,7 +244,6 @@
<SubType>Code</SubType>
</Compile>
<Compile Include="ApplicationHost.cs" />
- <Compile Include="Implementations\DotNetZipClient.cs" />
<Compile Include="LibraryExplorer.xaml.cs">
<DependentUpon>LibraryExplorer.xaml</DependentUpon>
</Compile>
@@ -278,14 +279,15 @@
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<None Include="app.manifest" />
- <EmbeddedResource Include="Implementations\ffmpeg20130904.zip" />
+ <None Include="FFMpeg\ARIALUNI.7z" />
+ <None Include="FFMpeg\ffmpeg-20130904-git-f974289-win32-static.7z" />
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<AppDesigner Include="Properties\" />
- <EmbeddedResource Include="RegisterServer.bat" />
+ <EmbeddedResource Include="Native\RegisterServer.bat" />
</ItemGroup>
<ItemGroup>
<None Include="App.config">
@@ -390,9 +392,6 @@
<ItemGroup>
<Resource Include="Resources\Images\mb3logo800.png" />
</ItemGroup>
- <ItemGroup>
- <EmbeddedResource Include="Implementations\readme.txt" />
- </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>if $(ConfigurationName) == Release (
diff --git a/MediaBrowser.ServerApplication/Native/Assemblies.cs b/MediaBrowser.ServerApplication/Native/Assemblies.cs
new file mode 100644
index 000000000..b43dc1a10
--- /dev/null
+++ b/MediaBrowser.ServerApplication/Native/Assemblies.cs
@@ -0,0 +1,25 @@
+using MediaBrowser.IsoMounter;
+using System.Collections.Generic;
+using System.Reflection;
+
+namespace MediaBrowser.ServerApplication.Native
+{
+ /// <summary>
+ /// Class Assemblies
+ /// </summary>
+ public static class Assemblies
+ {
+ /// <summary>
+ /// Gets the assemblies with parts.
+ /// </summary>
+ /// <returns>List{Assembly}.</returns>
+ public static List<Assembly> GetAssembliesWithParts()
+ {
+ var list = new List<Assembly>();
+
+ list.Add(typeof(PismoIsoManager).Assembly);
+
+ return list;
+ }
+ }
+}
diff --git a/MediaBrowser.ServerApplication/Native/Autorun.cs b/MediaBrowser.ServerApplication/Native/Autorun.cs
new file mode 100644
index 000000000..d1c02db84
--- /dev/null
+++ b/MediaBrowser.ServerApplication/Native/Autorun.cs
@@ -0,0 +1,31 @@
+using System;
+using System.IO;
+
+namespace MediaBrowser.ServerApplication.Native
+{
+ /// <summary>
+ /// Class Autorun
+ /// </summary>
+ public static class Autorun
+ {
+ /// <summary>
+ /// Configures the specified autorun.
+ /// </summary>
+ /// <param name="autorun">if set to <c>true</c> [autorun].</param>
+ public static void Configure(bool autorun)
+ {
+ var shortcutPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.StartMenu), "Media Browser 3", "Media Browser Server.lnk");
+
+ if (autorun)
+ {
+ //Copy our shortut into the startup folder for this user
+ File.Copy(shortcutPath, Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Startup), Path.GetFileName(shortcutPath) ?? "MBstartup.lnk"), true);
+ }
+ else
+ {
+ //Remove our shortcut from the startup folder for this user
+ File.Delete(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Startup), Path.GetFileName(shortcutPath) ?? "MBstartup.lnk"));
+ }
+ }
+ }
+}
diff --git a/MediaBrowser.ServerApplication/Native/BrowserLauncher.cs b/MediaBrowser.ServerApplication/Native/BrowserLauncher.cs
new file mode 100644
index 000000000..e7d041d15
--- /dev/null
+++ b/MediaBrowser.ServerApplication/Native/BrowserLauncher.cs
@@ -0,0 +1,68 @@
+using MediaBrowser.Controller;
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Model.Logging;
+using System;
+using System.Diagnostics;
+using System.Windows.Forms;
+
+namespace MediaBrowser.ServerApplication.Native
+{
+ public static class BrowserLauncher
+ {
+ /// <summary>
+ /// Opens the dashboard page.
+ /// </summary>
+ /// <param name="page">The page.</param>
+ /// <param name="loggedInUser">The logged in user.</param>
+ /// <param name="configurationManager">The configuration manager.</param>
+ /// <param name="appHost">The app host.</param>
+ public static void OpenDashboardPage(string page, User loggedInUser, IServerConfigurationManager configurationManager, IServerApplicationHost appHost, ILogger logger)
+ {
+ var url = "http://localhost:" + configurationManager.Configuration.HttpServerPortNumber + "/" +
+ appHost.WebApplicationName + "/dashboard/" + page;
+
+ OpenUrl(url, logger);
+ }
+
+ /// <summary>
+ /// Opens the URL.
+ /// </summary>
+ /// <param name="url">The URL.</param>
+ public static void OpenUrl(string url, ILogger logger)
+ {
+ var process = new Process
+ {
+ StartInfo = new ProcessStartInfo
+ {
+ FileName = url
+ },
+
+ EnableRaisingEvents = true
+ };
+
+ process.Exited += ProcessExited;
+
+ try
+ {
+ process.Start();
+ }
+ catch (Exception ex)
+ {
+ logger.ErrorException("Error launching url: {0}", ex, url);
+
+ MessageBox.Show("There was an error launching your web browser. Please check your default browser settings.");
+ }
+ }
+
+ /// <summary>
+ /// Processes the exited.
+ /// </summary>
+ /// <param name="sender">The sender.</param>
+ /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
+ private static void ProcessExited(object sender, EventArgs e)
+ {
+ ((Process)sender).Dispose();
+ }
+ }
+}
diff --git a/MediaBrowser.ServerApplication/Native/HttpMessageHandlerFactory.cs b/MediaBrowser.ServerApplication/Native/HttpMessageHandlerFactory.cs
new file mode 100644
index 000000000..4bbcc9ea0
--- /dev/null
+++ b/MediaBrowser.ServerApplication/Native/HttpMessageHandlerFactory.cs
@@ -0,0 +1,26 @@
+using System.Net;
+using System.Net.Cache;
+using System.Net.Http;
+
+namespace MediaBrowser.ServerApplication.Native
+{
+ /// <summary>
+ /// Class HttpMessageHandlerFactory
+ /// </summary>
+ public static class HttpMessageHandlerFactory
+ {
+ /// <summary>
+ /// Gets the HTTP message handler.
+ /// </summary>
+ /// <param name="enableHttpCompression">if set to <c>true</c> [enable HTTP compression].</param>
+ /// <returns>HttpMessageHandler.</returns>
+ public static HttpMessageHandler GetHttpMessageHandler(bool enableHttpCompression)
+ {
+ return new WebRequestHandler
+ {
+ CachePolicy = new RequestCachePolicy(RequestCacheLevel.Revalidate),
+ AutomaticDecompression = enableHttpCompression ? DecompressionMethods.Deflate : DecompressionMethods.None
+ };
+ }
+ }
+}
diff --git a/MediaBrowser.ServerApplication/Native/NativeApp.cs b/MediaBrowser.ServerApplication/Native/NativeApp.cs
new file mode 100644
index 000000000..ea4218afc
--- /dev/null
+++ b/MediaBrowser.ServerApplication/Native/NativeApp.cs
@@ -0,0 +1,25 @@
+
+namespace MediaBrowser.ServerApplication.Native
+{
+ /// <summary>
+ /// Class NativeApp
+ /// </summary>
+ public static class NativeApp
+ {
+ /// <summary>
+ /// Shutdowns this instance.
+ /// </summary>
+ public static void Shutdown()
+ {
+ MainStartup.Shutdown();
+ }
+
+ /// <summary>
+ /// Restarts this instance.
+ /// </summary>
+ public static void Restart()
+ {
+ MainStartup.Restart();
+ }
+ }
+}
diff --git a/MediaBrowser.ServerApplication/RegisterServer.bat b/MediaBrowser.ServerApplication/Native/RegisterServer.bat
index d762dfaf7..d762dfaf7 100644
--- a/MediaBrowser.ServerApplication/RegisterServer.bat
+++ b/MediaBrowser.ServerApplication/Native/RegisterServer.bat
diff --git a/MediaBrowser.ServerApplication/Native/ServerAuthorization.cs b/MediaBrowser.ServerApplication/Native/ServerAuthorization.cs
new file mode 100644
index 000000000..91f0974eb
--- /dev/null
+++ b/MediaBrowser.ServerApplication/Native/ServerAuthorization.cs
@@ -0,0 +1,56 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Reflection;
+
+namespace MediaBrowser.ServerApplication.Native
+{
+ /// <summary>
+ /// Class Authorization
+ /// </summary>
+ public static class ServerAuthorization
+ {
+ /// <summary>
+ /// Authorizes the server.
+ /// </summary>
+ /// <param name="httpServerPort">The HTTP server port.</param>
+ /// <param name="httpServerUrlPrefix">The HTTP server URL prefix.</param>
+ /// <param name="webSocketPort">The web socket port.</param>
+ /// <param name="udpPort">The UDP port.</param>
+ /// <param name="tempDirectory">The temp directory.</param>
+ public static void AuthorizeServer(int httpServerPort, string httpServerUrlPrefix, int webSocketPort, int udpPort, string tempDirectory)
+ {
+ // Create a temp file path to extract the bat file to
+ var tmpFile = Path.Combine(tempDirectory, Guid.NewGuid() + ".bat");
+
+ // Extract the bat file
+ using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(typeof(ServerAuthorization).Namespace + ".RegisterServer.bat"))
+ {
+ using (var fileStream = File.Create(tmpFile))
+ {
+ stream.CopyTo(fileStream);
+ }
+ }
+
+ var startInfo = new ProcessStartInfo
+ {
+ FileName = tmpFile,
+
+ Arguments = string.Format("{0} {1} {2} {3}", httpServerPort,
+ httpServerUrlPrefix,
+ udpPort,
+ webSocketPort),
+
+ CreateNoWindow = true,
+ WindowStyle = ProcessWindowStyle.Hidden,
+ Verb = "runas",
+ ErrorDialog = false
+ };
+
+ using (var process = Process.Start(startInfo))
+ {
+ process.WaitForExit();
+ }
+ }
+ }
+}
diff --git a/MediaBrowser.ServerApplication/Native/Sqlite.cs b/MediaBrowser.ServerApplication/Native/Sqlite.cs
new file mode 100644
index 000000000..cc20952d7
--- /dev/null
+++ b/MediaBrowser.ServerApplication/Native/Sqlite.cs
@@ -0,0 +1,36 @@
+using System.Data;
+using System.Data.SQLite;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.ServerApplication.Native
+{
+ /// <summary>
+ /// Class Sqlite
+ /// </summary>
+ public static class Sqlite
+ {
+ /// <summary>
+ /// Connects to db.
+ /// </summary>
+ /// <param name="dbPath">The db path.</param>
+ /// <returns>Task{IDbConnection}.</returns>
+ /// <exception cref="System.ArgumentNullException">dbPath</exception>
+ public static async Task<IDbConnection> OpenDatabase(string dbPath)
+ {
+ var connectionstr = new SQLiteConnectionStringBuilder
+ {
+ PageSize = 4096,
+ CacheSize = 4096,
+ SyncMode = SynchronizationModes.Normal,
+ DataSource = dbPath,
+ JournalMode = SQLiteJournalModeEnum.Wal
+ };
+
+ var connection = new SQLiteConnection(connectionstr.ConnectionString);
+
+ await connection.OpenAsync().ConfigureAwait(false);
+
+ return connection;
+ }
+ }
+}
diff --git a/MediaBrowser.ServerApplication/Resources/Images/mb3logo800.png b/MediaBrowser.ServerApplication/Resources/Images/mb3logo800.png
index fbc769a6f..12db84679 100644
--- a/MediaBrowser.ServerApplication/Resources/Images/mb3logo800.png
+++ b/MediaBrowser.ServerApplication/Resources/Images/mb3logo800.png
Binary files differ
diff --git a/MediaBrowser.ServerApplication/packages.config b/MediaBrowser.ServerApplication/packages.config
index 8c1821ca5..e680b556f 100644
--- a/MediaBrowser.ServerApplication/packages.config
+++ b/MediaBrowser.ServerApplication/packages.config
@@ -4,7 +4,6 @@
<package id="Hardcodet.Wpf.TaskbarNotification" version="1.0.4.0" targetFramework="net45" />
<package id="MahApps.Metro" version="0.11.0.17-ALPHA" targetFramework="net45" />
<package id="MediaBrowser.IsoMounting" version="3.0.56" targetFramework="net45" />
- <package id="morelinq" version="1.0.16006" targetFramework="net45" />
<package id="NLog" version="2.0.1.2" targetFramework="net45" />
<package id="ServiceStack" version="3.9.62" targetFramework="net45" />
<package id="ServiceStack.Common" version="3.9.62" targetFramework="net45" />