瀏覽代碼

Merge branch 'master' of https://github.com/MediaBrowser/MediaBrowser

Eric Reed 11 年之前
父節點
當前提交
c6e57c6448
共有 46 個文件被更改,包括 479 次插入376 次删除
  1. 5 2
      MediaBrowser.Api/GamesService.cs
  2. 5 5
      MediaBrowser.Api/MediaBrowser.Api.csproj
  3. 2 2
      MediaBrowser.Api/PackageService.cs
  4. 1 1
      MediaBrowser.Api/SimilarItemsHelper.cs
  5. 1 1
      MediaBrowser.Api/TvShowsService.cs
  6. 1 1
      MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs
  7. 21 20
      MediaBrowser.Api/UserLibrary/ItemsService.cs
  8. 2 2
      MediaBrowser.Api/packages.config
  9. 1 1
      MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
  10. 12 13
      MediaBrowser.Common.Implementations/Updates/InstallationManager.cs
  11. 1 1
      MediaBrowser.Common.Implementations/packages.config
  12. 5 5
      MediaBrowser.Common/MediaBrowser.Common.csproj
  13. 6 3
      MediaBrowser.Common/Updates/IInstallationManager.cs
  14. 2 2
      MediaBrowser.Common/packages.config
  15. 2 1
      MediaBrowser.Controller/Entities/Folder.cs
  16. 6 0
      MediaBrowser.Controller/Entities/Game.cs
  17. 6 0
      MediaBrowser.Controller/Entities/GameSystem.cs
  18. 36 0
      MediaBrowser.Controller/Providers/BaseItemXmlParser.cs
  19. 12 0
      MediaBrowser.Controller/Providers/BaseMetadataProvider.cs
  20. 12 0
      MediaBrowser.Model/Dto/GameSystemSummary.cs
  21. 5 1
      MediaBrowser.Model/Entities/MetadataFields.cs
  22. 0 5
      MediaBrowser.Model/Querying/ItemFields.cs
  23. 6 0
      MediaBrowser.Model/Querying/ItemQuery.cs
  24. 4 1
      MediaBrowser.Providers/MediaInfo/FFProbeVideoInfoProvider.cs
  25. 15 11
      MediaBrowser.Providers/Movies/MovieDbProvider.cs
  26. 1 1
      MediaBrowser.Providers/Savers/XmlSaverHelpers.cs
  27. 13 1
      MediaBrowser.Providers/TV/RemoteSeriesProvider.cs
  28. 11 18
      MediaBrowser.Server.Implementations/Dto/DtoService.cs
  29. 6 4
      MediaBrowser.Server.Implementations/HttpServer/HttpServer.cs
  30. 9 11
      MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
  31. 10 222
      MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs
  32. 1 1
      MediaBrowser.Server.Implementations/Providers/ProviderManager.cs
  33. 7 8
      MediaBrowser.Server.Implementations/ScheduledTasks/PluginUpdateTask.cs
  34. 3 3
      MediaBrowser.Server.Implementations/packages.config
  35. 1 1
      MediaBrowser.Server.Implementations/swagger-ui/index.html
  36. 14 4
      MediaBrowser.ServerApplication/ApplicationHost.cs
  37. 205 0
      MediaBrowser.ServerApplication/Implementations/FFMpegDownloader.cs
  38. 0 0
      MediaBrowser.ServerApplication/Implementations/ffmpeg20130904.zip.REMOVED.git-id
  39. 0 0
      MediaBrowser.ServerApplication/Implementations/readme.txt
  40. 14 9
      MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj
  41. 3 3
      MediaBrowser.ServerApplication/packages.config
  42. 5 5
      MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
  43. 2 2
      MediaBrowser.WebDashboard/packages.config
  44. 2 2
      Nuget/MediaBrowser.Common.Internal.nuspec
  45. 1 1
      Nuget/MediaBrowser.Common.nuspec
  46. 2 2
      Nuget/MediaBrowser.Server.Core.nuspec

+ 5 - 2
MediaBrowser.Api/GamesService.cs

@@ -110,16 +110,19 @@ namespace MediaBrowser.Api
         {
             var summary = new GameSystemSummary
             {
-                Name = system.Name
+                Name = system.GameSystemName,
+                DisplayName = system.Name
             };
 
             var items = user == null ? system.RecursiveChildren : system.GetRecursiveChildren(user);
 
             var games = items.OfType<Game>().ToList();
 
+            summary.ClientInstalledGameCount = games.Count(i => !i.IsInstalledOnClient);
+
             summary.GameCount = games.Count;
 
-            summary.GameFileExtensions = games.Select(i => Path.GetExtension(i.Path))
+            summary.GameFileExtensions = games.Where(i => !i.IsInstalledOnClient).Select(i => Path.GetExtension(i.Path))
                 .Distinct(StringComparer.OrdinalIgnoreCase)
                 .ToList();
 

+ 5 - 5
MediaBrowser.Api/MediaBrowser.Api.csproj

@@ -40,17 +40,17 @@
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\packages\morelinq.1.0.16006\lib\net35\MoreLinq.dll</HintPath>
     </Reference>
-    <Reference Include="ServiceStack.Common, Version=3.9.59.0, Culture=neutral, processorArchitecture=MSIL">
+    <Reference Include="ServiceStack.Common, Version=3.9.60.0, Culture=neutral, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\ServiceStack.Common.3.9.59\lib\net35\ServiceStack.Common.dll</HintPath>
+      <HintPath>..\packages\ServiceStack.Common.3.9.62\lib\net35\ServiceStack.Common.dll</HintPath>
     </Reference>
-    <Reference Include="ServiceStack.Interfaces, Version=3.9.59.0, Culture=neutral, processorArchitecture=MSIL">
+    <Reference Include="ServiceStack.Interfaces, Version=3.9.60.0, Culture=neutral, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\ServiceStack.Common.3.9.59\lib\net35\ServiceStack.Interfaces.dll</HintPath>
+      <HintPath>..\packages\ServiceStack.Common.3.9.62\lib\net35\ServiceStack.Interfaces.dll</HintPath>
     </Reference>
     <Reference Include="ServiceStack.Text, Version=3.9.59.0, Culture=neutral, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\ServiceStack.Text.3.9.59\lib\net35\ServiceStack.Text.dll</HintPath>
+      <HintPath>..\packages\ServiceStack.Text.3.9.62\lib\net35\ServiceStack.Text.dll</HintPath>
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />

+ 2 - 2
MediaBrowser.Api/PackageService.cs

@@ -132,7 +132,7 @@ namespace MediaBrowser.Api
 
             if (request.PackageType == PackageType.UserInstalled || request.PackageType == PackageType.All)
             {
-                result.AddRange(_installationManager.GetAvailablePluginUpdates(false, CancellationToken.None).Result.ToList());
+                result.AddRange(_installationManager.GetAvailablePluginUpdates(_appHost.ApplicationVersion, false, CancellationToken.None).Result.ToList());
             }
 
             else if (request.PackageType == PackageType.System || request.PackageType == PackageType.All)
@@ -194,7 +194,7 @@ namespace MediaBrowser.Api
         public void Post(InstallPackage request)
         {
             var package = string.IsNullOrEmpty(request.Version) ?
-                _installationManager.GetLatestCompatibleVersion(request.Name, request.UpdateClass).Result :
+                _installationManager.GetLatestCompatibleVersion(request.Name, _appHost.ApplicationVersion, request.UpdateClass).Result :
                 _installationManager.GetPackage(request.Name, request.UpdateClass, Version.Parse(request.Version)).Result;
 
             if (package == null)

+ 1 - 1
MediaBrowser.Api/SimilarItemsHelper.cs

@@ -45,7 +45,7 @@ namespace MediaBrowser.Api
         /// Fields to return within the items, in addition to basic information
         /// </summary>
         /// <value>The fields.</value>
-        [ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Budget, Chapters, CriticRatingSummary, DateCreated, Genres, HomePageUrl, ItemCounts, IndexOptions, MediaStreams, Overview, OverviewHtml, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines, TrailerUrls", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
+        [ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Budget, Chapters, CriticRatingSummary, DateCreated, Genres, HomePageUrl, IndexOptions, MediaStreams, Overview, OverviewHtml, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines, TrailerUrls", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
         public string Fields { get; set; }
 
         /// <summary>

+ 1 - 1
MediaBrowser.Api/TvShowsService.cs

@@ -43,7 +43,7 @@ namespace MediaBrowser.Api
         /// Fields to return within the items, in addition to basic information
         /// </summary>
         /// <value>The fields.</value>
-        [ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Budget, Chapters, CriticRatingSummary, DateCreated, Genres, HomePageUrl, ItemCounts, IndexOptions, MediaStreams, Overview, OverviewHtml, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines, TrailerUrls", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
+        [ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Budget, Chapters, CriticRatingSummary, DateCreated, Genres, HomePageUrl, IndexOptions, MediaStreams, Overview, OverviewHtml, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines, TrailerUrls", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
         public string Fields { get; set; }
 
         /// <summary>

+ 1 - 1
MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs

@@ -48,7 +48,7 @@ namespace MediaBrowser.Api.UserLibrary
         /// Fields to return within the items, in addition to basic information
         /// </summary>
         /// <value>The fields.</value>
-        [ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Budget, Chapters, CriticRatingSummary, DateCreated, Genres, HomePageUrl, ItemCounts, IndexOptions, MediaStreams, Overview, OverviewHtml, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines, TrailerUrls", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
+        [ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: Budget, Chapters, CriticRatingSummary, DateCreated, Genres, HomePageUrl, IndexOptions, MediaStreams, Overview, OverviewHtml, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Revenue, SortName, Studios, Taglines, TrailerUrls", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
         public string Fields { get; set; }
 
         /// <summary>

+ 21 - 20
MediaBrowser.Api/UserLibrary/ItemsService.cs

@@ -12,7 +12,6 @@ using ServiceStack.ServiceHost;
 using System;
 using System.Collections.Generic;
 using System.Linq;
-using System.Threading.Tasks;
 
 namespace MediaBrowser.Api.UserLibrary
 {
@@ -64,6 +63,9 @@ namespace MediaBrowser.Api.UserLibrary
         [ApiMember(Name = "Genres", Description = "Optional. If specified, results will be filtered based on genre. This allows multiple, comma delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
         public string Genres { get; set; }
 
+        [ApiMember(Name = "AllGenres", Description = "Optional. If specified, results will be filtered based on genre. This allows multiple, comma delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
+        public string AllGenres { get; set; }
+
         /// <summary>
         /// Limit results to items containing specific studios
         /// </summary>
@@ -609,43 +611,42 @@ namespace MediaBrowser.Api.UserLibrary
                 items = items.Where(item => imageTypes.Any(imageType => HasImage(item, imageType)));
             }
 
-            var genres = request.Genres;
-
             // Apply genre filter
-            if (!string.IsNullOrEmpty(genres))
+            if (!string.IsNullOrEmpty(request.Genres))
             {
-                var vals = genres.Split(',');
-                items = items.Where(f => f.Genres != null && vals.Any(v => f.Genres.Contains(v, StringComparer.OrdinalIgnoreCase)));
+                var vals = request.Genres.Split(',');
+                items = items.Where(f => vals.Any(v => f.Genres.Contains(v, StringComparer.OrdinalIgnoreCase)));
             }
 
-            var studios = request.Studios;
-
+            // Apply genre filter
+            if (!string.IsNullOrEmpty(request.AllGenres))
+            {
+                var vals = request.AllGenres.Split(',');
+                items = items.Where(f => vals.All(v => f.Genres.Contains(v, StringComparer.OrdinalIgnoreCase)));
+            }
+            
             // Apply studio filter
-            if (!string.IsNullOrEmpty(studios))
+            if (!string.IsNullOrEmpty(request.Studios))
             {
-                var vals = studios.Split(',');
-                items = items.Where(f => f.Studios != null && vals.Any(v => f.Studios.Contains(v, StringComparer.OrdinalIgnoreCase)));
+                var vals = request.Studios.Split(',');
+                items = items.Where(f => vals.Any(v => f.Studios.Contains(v, StringComparer.OrdinalIgnoreCase)));
             }
 
-            var years = request.Years;
-
             // Apply year filter
-            if (!string.IsNullOrEmpty(years))
+            if (!string.IsNullOrEmpty(request.Years))
             {
-                var vals = years.Split(',').Select(int.Parse);
+                var vals = request.Years.Split(',').Select(int.Parse).ToList();
                 items = items.Where(f => f.ProductionYear.HasValue && vals.Contains(f.ProductionYear.Value));
             }
 
-            var personName = request.Person;
-
             // Apply person filter
-            if (!string.IsNullOrEmpty(personName))
+            if (!string.IsNullOrEmpty(request.Person))
             {
                 var personTypes = request.PersonTypes;
 
                 if (string.IsNullOrEmpty(personTypes))
                 {
-                    items = items.Where(item => item.People != null && item.People.Any(p => string.Equals(p.Name, personName, StringComparison.OrdinalIgnoreCase)));
+                    items = items.Where(item => item.People != null && item.People.Any(p => string.Equals(p.Name, request.Person, StringComparison.OrdinalIgnoreCase)));
                 }
                 else
                 {
@@ -654,7 +655,7 @@ namespace MediaBrowser.Api.UserLibrary
                     items = items.Where(item =>
                             item.People != null &&
                             item.People.Any(p =>
-                                p.Name.Equals(personName, StringComparison.OrdinalIgnoreCase) && (types.Contains(p.Type, StringComparer.OrdinalIgnoreCase) || types.Contains(p.Role, StringComparer.OrdinalIgnoreCase))));
+                                p.Name.Equals(request.Person, StringComparison.OrdinalIgnoreCase) && (types.Contains(p.Type, StringComparer.OrdinalIgnoreCase) || types.Contains(p.Role, StringComparer.OrdinalIgnoreCase))));
                 }
             }
 

+ 2 - 2
MediaBrowser.Api/packages.config

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
   <package id="morelinq" version="1.0.16006" targetFramework="net45" />
-  <package id="ServiceStack.Common" version="3.9.59" targetFramework="net45" />
-  <package id="ServiceStack.Text" version="3.9.59" targetFramework="net45" />
+  <package id="ServiceStack.Common" version="3.9.62" targetFramework="net45" />
+  <package id="ServiceStack.Text" version="3.9.62" targetFramework="net45" />
 </packages>

+ 1 - 1
MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj

@@ -41,7 +41,7 @@
     </Reference>
     <Reference Include="ServiceStack.Text, Version=3.9.59.0, Culture=neutral, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\ServiceStack.Text.3.9.59\lib\net35\ServiceStack.Text.dll</HintPath>
+      <HintPath>..\packages\ServiceStack.Text.3.9.62\lib\net35\ServiceStack.Text.dll</HintPath>
     </Reference>
     <Reference Include="SimpleInjector, Version=2.3.5.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>

+ 12 - 13
MediaBrowser.Common.Implementations/Updates/InstallationManager.cs

@@ -225,9 +225,9 @@ namespace MediaBrowser.Common.Implementations.Updates
         /// Determines whether [is package version up to date] [the specified package version info].
         /// </summary>
         /// <param name="packageVersionInfo">The package version info.</param>
-        /// <param name="applicationVersion">The application version.</param>
+        /// <param name="currentServerVersion">The current server version.</param>
         /// <returns><c>true</c> if [is package version up to date] [the specified package version info]; otherwise, <c>false</c>.</returns>
-        private bool IsPackageVersionUpToDate(PackageVersionInfo packageVersionInfo, Version applicationVersion)
+        private bool IsPackageVersionUpToDate(PackageVersionInfo packageVersionInfo, Version currentServerVersion)
         {
             if (string.IsNullOrEmpty(packageVersionInfo.requiredVersionStr))
             {
@@ -236,7 +236,7 @@ namespace MediaBrowser.Common.Implementations.Updates
 
             Version requiredVersion;
 
-            return Version.TryParse(packageVersionInfo.requiredVersionStr, out requiredVersion) && applicationVersion >= requiredVersion;
+            return Version.TryParse(packageVersionInfo.requiredVersionStr, out requiredVersion) && currentServerVersion >= requiredVersion;
         }
 
         /// <summary>
@@ -264,13 +264,14 @@ namespace MediaBrowser.Common.Implementations.Updates
         /// Gets the latest compatible version.
         /// </summary>
         /// <param name="name">The name.</param>
+        /// <param name="currentServerVersion">The current server version.</param>
         /// <param name="classification">The classification.</param>
         /// <returns>Task{PackageVersionInfo}.</returns>
-        public async Task<PackageVersionInfo> GetLatestCompatibleVersion(string name, PackageVersionClass classification = PackageVersionClass.Release)
+        public async Task<PackageVersionInfo> GetLatestCompatibleVersion(string name, Version currentServerVersion, PackageVersionClass classification = PackageVersionClass.Release)
         {
             var packages = await GetAvailablePackages(CancellationToken.None).ConfigureAwait(false);
 
-            return GetLatestCompatibleVersion(packages, name, classification);
+            return GetLatestCompatibleVersion(packages, name, currentServerVersion, classification);
         }
 
         /// <summary>
@@ -278,9 +279,10 @@ namespace MediaBrowser.Common.Implementations.Updates
         /// </summary>
         /// <param name="availablePackages">The available packages.</param>
         /// <param name="name">The name.</param>
+        /// <param name="currentServerVersion">The current server version.</param>
         /// <param name="classification">The classification.</param>
         /// <returns>PackageVersionInfo.</returns>
-        public PackageVersionInfo GetLatestCompatibleVersion(IEnumerable<PackageInfo> availablePackages, string name, PackageVersionClass classification = PackageVersionClass.Release)
+        public PackageVersionInfo GetLatestCompatibleVersion(IEnumerable<PackageInfo> availablePackages, string name, Version currentServerVersion, PackageVersionClass classification = PackageVersionClass.Release)
         {
             var package = availablePackages.FirstOrDefault(p => p.name.Equals(name, StringComparison.OrdinalIgnoreCase));
 
@@ -291,23 +293,20 @@ namespace MediaBrowser.Common.Implementations.Updates
 
             return package.versions
                 .OrderByDescending(v => v.version)
-                .FirstOrDefault(v => v.classification <= classification && IsPackageVersionUpToDate(v, _applicationHost.ApplicationVersion));
+                .FirstOrDefault(v => v.classification <= classification && IsPackageVersionUpToDate(v, currentServerVersion));
         }
 
         /// <summary>
         /// Gets the available plugin updates.
         /// </summary>
+        /// <param name="currentServerVersion">The current server version.</param>
         /// <param name="withAutoUpdateEnabled">if set to <c>true</c> [with auto update enabled].</param>
         /// <param name="cancellationToken">The cancellation token.</param>
         /// <returns>Task{IEnumerable{PackageVersionInfo}}.</returns>
-        public async Task<IEnumerable<PackageVersionInfo>> GetAvailablePluginUpdates(bool withAutoUpdateEnabled, CancellationToken cancellationToken)
+        public async Task<IEnumerable<PackageVersionInfo>> GetAvailablePluginUpdates(Version currentServerVersion, bool withAutoUpdateEnabled, CancellationToken cancellationToken)
         {
             var catalog = await GetAvailablePackagesWithoutRegistrationInfo(cancellationToken).ConfigureAwait(false);
-            return FilterCatalog(catalog, withAutoUpdateEnabled);
-        }
 
-        protected IEnumerable<PackageVersionInfo> FilterCatalog(IEnumerable<PackageInfo> catalog, bool withAutoUpdateEnabled)
-        {
             var plugins = _applicationHost.Plugins.ToList();
 
             if (withAutoUpdateEnabled)
@@ -320,7 +319,7 @@ namespace MediaBrowser.Common.Implementations.Updates
             // Figure out what needs to be installed
             var packages = plugins.Select(p =>
             {
-                var latestPluginInfo = GetLatestCompatibleVersion(catalog, p.Name, p.Configuration.UpdateClass);
+                var latestPluginInfo = GetLatestCompatibleVersion(catalog, p.Name, currentServerVersion, p.Configuration.UpdateClass);
 
                 return latestPluginInfo != null && latestPluginInfo.version != null && latestPluginInfo.version > p.Version ? latestPluginInfo : null;
 

+ 1 - 1
MediaBrowser.Common.Implementations/packages.config

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
   <package id="NLog" version="2.0.1.2" targetFramework="net45" />
-  <package id="ServiceStack.Text" version="3.9.59" targetFramework="net45" />
+  <package id="ServiceStack.Text" version="3.9.62" targetFramework="net45" />
   <package id="SimpleInjector" version="2.3.5" targetFramework="net45" />
 </packages>

+ 5 - 5
MediaBrowser.Common/MediaBrowser.Common.csproj

@@ -37,17 +37,17 @@
     </ApplicationIcon>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="ServiceStack.Common, Version=3.9.59.0, Culture=neutral, processorArchitecture=MSIL">
+    <Reference Include="ServiceStack.Common, Version=3.9.60.0, Culture=neutral, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\ServiceStack.Common.3.9.59\lib\net35\ServiceStack.Common.dll</HintPath>
+      <HintPath>..\packages\ServiceStack.Common.3.9.62\lib\net35\ServiceStack.Common.dll</HintPath>
     </Reference>
-    <Reference Include="ServiceStack.Interfaces, Version=3.9.59.0, Culture=neutral, processorArchitecture=MSIL">
+    <Reference Include="ServiceStack.Interfaces, Version=3.9.60.0, Culture=neutral, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\ServiceStack.Common.3.9.59\lib\net35\ServiceStack.Interfaces.dll</HintPath>
+      <HintPath>..\packages\ServiceStack.Common.3.9.62\lib\net35\ServiceStack.Interfaces.dll</HintPath>
     </Reference>
     <Reference Include="ServiceStack.Text, Version=3.9.59.0, Culture=neutral, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\ServiceStack.Text.3.9.59\lib\net35\ServiceStack.Text.dll</HintPath>
+      <HintPath>..\packages\ServiceStack.Text.3.9.62\lib\net35\ServiceStack.Text.dll</HintPath>
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />

+ 6 - 3
MediaBrowser.Common/Updates/IInstallationManager.cs

@@ -76,26 +76,29 @@ namespace MediaBrowser.Common.Updates
         /// Gets the latest compatible version.
         /// </summary>
         /// <param name="name">The name.</param>
+        /// <param name="currentServerVersion">The current server version.</param>
         /// <param name="classification">The classification.</param>
         /// <returns>Task{PackageVersionInfo}.</returns>
-        Task<PackageVersionInfo> GetLatestCompatibleVersion(string name, PackageVersionClass classification = PackageVersionClass.Release);
+        Task<PackageVersionInfo> GetLatestCompatibleVersion(string name, Version currentServerVersion, PackageVersionClass classification = PackageVersionClass.Release);
 
         /// <summary>
         /// Gets the latest compatible version.
         /// </summary>
         /// <param name="availablePackages">The available packages.</param>
         /// <param name="name">The name.</param>
+        /// <param name="currentServerVersion">The current server version.</param>
         /// <param name="classification">The classification.</param>
         /// <returns>PackageVersionInfo.</returns>
-        PackageVersionInfo GetLatestCompatibleVersion(IEnumerable<PackageInfo> availablePackages, string name, PackageVersionClass classification = PackageVersionClass.Release);
+        PackageVersionInfo GetLatestCompatibleVersion(IEnumerable<PackageInfo> availablePackages, string name, Version currentServerVersion, PackageVersionClass classification = PackageVersionClass.Release);
 
         /// <summary>
         /// Gets the available plugin updates.
         /// </summary>
+        /// <param name="currentServerVersion">The current server version.</param>
         /// <param name="withAutoUpdateEnabled">if set to <c>true</c> [with auto update enabled].</param>
         /// <param name="cancellationToken">The cancellation token.</param>
         /// <returns>Task{IEnumerable{PackageVersionInfo}}.</returns>
-        Task<IEnumerable<PackageVersionInfo>> GetAvailablePluginUpdates(bool withAutoUpdateEnabled, CancellationToken cancellationToken);
+        Task<IEnumerable<PackageVersionInfo>> GetAvailablePluginUpdates(Version currentServerVersion, bool withAutoUpdateEnabled, CancellationToken cancellationToken);
 
         /// <summary>
         /// Installs the package.

+ 2 - 2
MediaBrowser.Common/packages.config

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="ServiceStack.Common" version="3.9.59" targetFramework="net45" />
-  <package id="ServiceStack.Text" version="3.9.59" targetFramework="net45" />
+  <package id="ServiceStack.Common" version="3.9.62" targetFramework="net45" />
+  <package id="ServiceStack.Text" version="3.9.62" targetFramework="net45" />
 </packages>

+ 2 - 1
MediaBrowser.Controller/Entities/Folder.cs

@@ -1004,7 +1004,8 @@ namespace MediaBrowser.Controller.Entities
                 throw new ArgumentNullException();
             }
 
-            var list = new List<BaseItem>(10000);
+            var initialCount = _children == null ? 100 : _children.Count;
+            var list = new List<BaseItem>(initialCount);
 
             AddRecursiveChildrenInternal(user, includeLinkedChildren, list);
 

+ 6 - 0
MediaBrowser.Controller/Entities/Game.cs

@@ -24,6 +24,12 @@ namespace MediaBrowser.Controller.Entities
         /// <value>The players supported.</value>
         public int? PlayersSupported { get; set; }
 
+        /// <summary>
+        /// Gets or sets a value indicating whether this instance is installed on client.
+        /// </summary>
+        /// <value><c>true</c> if this instance is installed on client; otherwise, <c>false</c>.</value>
+        public bool IsInstalledOnClient { get; set; }
+
         /// <summary>
         /// Gets or sets the game system.
         /// </summary>

+ 6 - 0
MediaBrowser.Controller/Entities/GameSystem.cs

@@ -19,5 +19,11 @@ namespace MediaBrowser.Controller.Entities
                 return Id;
             }
         }
+
+        /// <summary>
+        /// Gets or sets the game system.
+        /// </summary>
+        /// <value>The game system.</value>
+        public string GameSystemName { get; set; }
     }
 }

+ 36 - 0
MediaBrowser.Controller/Providers/BaseItemXmlParser.cs

@@ -139,6 +139,7 @@ namespace MediaBrowser.Controller.Providers
 
                         break;
                     }
+
                 case "CriticRating":
                     {
                         var text = reader.ReadElementContentAsString();
@@ -150,6 +151,7 @@ namespace MediaBrowser.Controller.Providers
 
                         break;
                     }
+
                 case "Budget":
                     {
                         var text = reader.ReadElementContentAsString();
@@ -161,6 +163,7 @@ namespace MediaBrowser.Controller.Providers
 
                         break;
                     }
+
                 case "Revenue":
                     {
                         var text = reader.ReadElementContentAsString();
@@ -172,6 +175,7 @@ namespace MediaBrowser.Controller.Providers
 
                         break;
                     }
+
                 case "SortTitle":
                     {
                         var val = reader.ReadElementContentAsString();
@@ -466,6 +470,7 @@ namespace MediaBrowser.Controller.Providers
                         break;
                     }
 
+                case "ReleaseYear":
                 case "ProductionYear":
                     {
                         var val = reader.ReadElementContentAsString();
@@ -555,6 +560,37 @@ namespace MediaBrowser.Controller.Providers
                     }
                     break;
 
+                case "Players":
+                    {
+                        var val = reader.ReadElementContentAsString();
+                        if (!string.IsNullOrWhiteSpace(val))
+                        {
+                            int num;
+                            // All external meta is saving this as '.' for decimal I believe...but just to be sure
+                            if (int.TryParse(val, NumberStyles.Integer, _usCulture, out num))
+                            {
+                                var game = item as Game;
+                                if (game != null)
+                                {
+                                    game.PlayersSupported = num;
+                                }
+                            }
+                        }
+                        break;
+                    }
+                case "GameSystem":
+                    {
+                        var val = reader.ReadElementContentAsString();
+                        if (!string.IsNullOrWhiteSpace(val))
+                        {
+                            var game = item as Game;
+                            if (game != null)
+                            {
+                                game.GameSystem = val;
+                            }
+                        }
+                        break;
+                    }
                 case "MusicbrainzId":
                     {
                         var mbz = reader.ReadElementContentAsString();

+ 12 - 0
MediaBrowser.Controller/Providers/BaseMetadataProvider.cs

@@ -202,6 +202,18 @@ namespace MediaBrowser.Controller.Providers
             return NeedsRefreshInternal(item, data);
         }
 
+        /// <summary>
+        /// Gets a value indicating whether [enforce dont fetch metadata].
+        /// </summary>
+        /// <value><c>true</c> if [enforce dont fetch metadata]; otherwise, <c>false</c>.</value>
+        public virtual bool EnforceDontFetchMetadata
+        {
+            get
+            {
+                return true;
+            }
+        }
+
         /// <summary>
         /// Needses the refresh internal.
         /// </summary>

+ 12 - 0
MediaBrowser.Model/Dto/GameSystemSummary.cs

@@ -13,6 +13,12 @@ namespace MediaBrowser.Model.Dto
         /// <value>The name.</value>
         public string Name { get; set; }
 
+        /// <summary>
+        /// Gets or sets the name.
+        /// </summary>
+        /// <value>The name.</value>
+        public string DisplayName { get; set; }
+        
         /// <summary>
         /// Gets or sets the game count.
         /// </summary>
@@ -25,6 +31,12 @@ namespace MediaBrowser.Model.Dto
         /// <value>The game extensions.</value>
         public List<string> GameFileExtensions { get; set; }
 
+        /// <summary>
+        /// Gets or sets the client installed game count.
+        /// </summary>
+        /// <value>The client installed game count.</value>
+        public int ClientInstalledGameCount { get; set; }
+
         /// <summary>
         /// Initializes a new instance of the <see cref="GameSystemSummary"/> class.
         /// </summary>

+ 5 - 1
MediaBrowser.Model/Entities/MetadataFields.cs

@@ -37,6 +37,10 @@ namespace MediaBrowser.Model.Entities
         /// <summary>
         /// The runtime
         /// </summary>
-        Runtime
+        Runtime,
+        /// <summary>
+        /// The official rating
+        /// </summary>
+        OfficialRating
     }
 }

+ 0 - 5
MediaBrowser.Model/Querying/ItemFields.cs

@@ -51,11 +51,6 @@ namespace MediaBrowser.Model.Querying
         /// </summary>
         HomePageUrl,
 
-        /// <summary>
-        /// Child count, recursive child count, etc
-        /// </summary>
-        ItemCounts,
-
         /// <summary>
         /// The fields that the server supports indexing on
         /// </summary>

+ 6 - 0
MediaBrowser.Model/Querying/ItemQuery.cs

@@ -92,6 +92,12 @@ namespace MediaBrowser.Model.Querying
         /// <value>The genres.</value>
         public string[] Genres { get; set; }
 
+        /// <summary>
+        /// Limit results to items containing specific genres
+        /// </summary>
+        /// <value>The genres.</value>
+        public string[] AllGenres { get; set; }
+        
         /// <summary>
         /// Limit results to items containing specific studios
         /// </summary>

+ 4 - 1
MediaBrowser.Providers/MediaInfo/FFProbeVideoInfoProvider.cs

@@ -384,7 +384,10 @@ namespace MediaBrowser.Providers.MediaInfo
 
                 if (!string.IsNullOrWhiteSpace(officialRating))
                 {
-                    video.OfficialRating = officialRating;
+                    if (!video.LockedFields.Contains(MetadataFields.OfficialRating))
+                    {
+                        video.OfficialRating = officialRating;
+                    }
                 }
             }
 

+ 15 - 11
MediaBrowser.Providers/Movies/MovieDbProvider.cs

@@ -317,7 +317,7 @@ namespace MediaBrowser.Providers.Movies
             var boxset = item as BoxSet;
             if (boxset != null)
             {
-               // See if any movies have a collection id already
+                // See if any movies have a collection id already
                 var collId = boxset.Children.Concat(boxset.GetLinkedChildren()).OfType<Video>()
                     .Select(i => i.GetProviderId(MetadataProviders.TmdbCollection))
                    .FirstOrDefault(i => i != null);
@@ -462,7 +462,7 @@ namespace MediaBrowser.Providers.Movies
                 Logger.Info("MoviedbProvider: Ignoring " + item.Name + " because ID forced blank.");
                 return;
             }
-            
+
             item.SetProviderId(MetadataProviders.Tmdb, id);
 
             var mainResult = await FetchMainResult(item, id, cancellationToken).ConfigureAwait(false);
@@ -586,14 +586,18 @@ namespace MediaBrowser.Providers.Movies
                     var ourRelease = movieData.releases.countries.FirstOrDefault(c => c.iso_3166_1.Equals(ConfigurationManager.Configuration.MetadataCountryCode, StringComparison.OrdinalIgnoreCase)) ?? new Country();
                     var usRelease = movieData.releases.countries.FirstOrDefault(c => c.iso_3166_1.Equals("US", StringComparison.OrdinalIgnoreCase)) ?? new Country();
                     var minimunRelease = movieData.releases.countries.OrderBy(c => c.release_date).FirstOrDefault() ?? new Country();
-                    var ratingPrefix = ConfigurationManager.Configuration.MetadataCountryCode.Equals("us", StringComparison.OrdinalIgnoreCase) ? "" : ConfigurationManager.Configuration.MetadataCountryCode + "-";
-                    movie.OfficialRating = !string.IsNullOrEmpty(ourRelease.certification)
-                                               ? ratingPrefix + ourRelease.certification
-                                               : !string.IsNullOrEmpty(usRelease.certification)
-                                                     ? usRelease.certification
-                                                     : !string.IsNullOrEmpty(minimunRelease.certification)
-                                                           ? minimunRelease.iso_3166_1 + "-" + minimunRelease.certification
-                                                           : null;
+
+                    if (!movie.LockedFields.Contains(MetadataFields.OfficialRating))
+                    {
+                        var ratingPrefix = ConfigurationManager.Configuration.MetadataCountryCode.Equals("us", StringComparison.OrdinalIgnoreCase) ? "" : ConfigurationManager.Configuration.MetadataCountryCode + "-";
+                        movie.OfficialRating = !string.IsNullOrEmpty(ourRelease.certification)
+                                                   ? ratingPrefix + ourRelease.certification
+                                                   : !string.IsNullOrEmpty(usRelease.certification)
+                                                         ? usRelease.certification
+                                                         : !string.IsNullOrEmpty(minimunRelease.certification)
+                                                               ? minimunRelease.iso_3166_1 + "-" + minimunRelease.certification
+                                                               : null;
+                    }
 
                     if (ourRelease.release_date != default(DateTime))
                     {
@@ -632,7 +636,7 @@ namespace MediaBrowser.Providers.Movies
                 }
 
                 //if that didn't find a rating and we are a boxset, use the one from our first child
-                if (movie.OfficialRating == null && movie is BoxSet)
+                if (movie.OfficialRating == null && movie is BoxSet && !movie.LockedFields.Contains(MetadataFields.OfficialRating))
                 {
                     var boxset = movie as BoxSet;
                     Logger.Info("MovieDbProvider - Using rating of first child of boxset...");

+ 1 - 1
MediaBrowser.Providers/Savers/XmlSaverHelpers.cs

@@ -563,7 +563,7 @@ namespace MediaBrowser.Providers.Savers
 
             if (video != null)
             {
-                AddChapters(video, builder, itemRepository);
+                //AddChapters(video, builder, itemRepository);
             }
         }
     }

+ 13 - 1
MediaBrowser.Providers/TV/RemoteSeriesProvider.cs

@@ -153,6 +153,15 @@ namespace MediaBrowser.Providers.TV
             }
         }
 
+        public override bool EnforceDontFetchMetadata
+        {
+            get
+            {
+                // Other providers depend on the xml downloaded here
+                return false;
+            }
+        }
+
         protected override DateTime CompareDate(BaseItem item)
         {
             var seriesId = item.GetProviderId(MetadataProviders.Tvdb);
@@ -440,7 +449,10 @@ namespace MediaBrowser.Providers.TV
 
                                 if (!string.IsNullOrWhiteSpace(val))
                                 {
-                                    item.OfficialRating = val;
+                                    if (!item.LockedFields.Contains(MetadataFields.OfficialRating))
+                                    {
+                                        item.OfficialRating = val;
+                                    }
                                 }
                                 break;
                             }

+ 11 - 18
MediaBrowser.Server.Implementations/Dto/DtoService.cs

@@ -107,13 +107,10 @@ namespace MediaBrowser.Server.Implementations.Dto
                     .ToArray();
             }
 
-            if (fields.Contains(ItemFields.ItemCounts))
+            var itemByName = item as IItemByName;
+            if (itemByName != null)
             {
-                var itemByName = item as IItemByName;
-                if (itemByName != null)
-                {
-                    AttachItemByNameCounts(dto, itemByName, user);
-                }
+                AttachItemByNameCounts(dto, itemByName, user);
             }
 
             return dto;
@@ -166,18 +163,13 @@ namespace MediaBrowser.Server.Implementations.Dto
         {
             if (item.IsFolder)
             {
-                var hasItemCounts = fields.Contains(ItemFields.ItemCounts);
+                var folder = (Folder)item;
 
-                if (hasItemCounts || fields.Contains(ItemFields.CumulativeRunTimeTicks))
-                {
-                    var folder = (Folder)item;
+                dto.ChildCount = folder.GetChildren(user, true).Count();
 
-                    if (hasItemCounts)
-                    {
-                        dto.ChildCount = folder.GetChildren(user, true).Count();
-                    }
-
-                    SetSpecialCounts(folder, user, dto);
+                if (!(folder is UserRootFolder))
+                {
+                    SetSpecialCounts(folder, user, dto, fields);
                 }
             }
 
@@ -1068,8 +1060,9 @@ namespace MediaBrowser.Server.Implementations.Dto
         /// <param name="folder">The folder.</param>
         /// <param name="user">The user.</param>
         /// <param name="dto">The dto.</param>
+        /// <param name="fields">The fields.</param>
         /// <returns>Task.</returns>
-        private void SetSpecialCounts(Folder folder, User user, BaseItemDto dto)
+        private void SetSpecialCounts(Folder folder, User user, BaseItemDto dto, List<ItemFields> fields)
         {
             var rcentlyAddedItemCount = 0;
             var recursiveItemCount = 0;
@@ -1127,7 +1120,7 @@ namespace MediaBrowser.Server.Implementations.Dto
                 dto.PlayedPercentage = totalPercentPlayed / recursiveItemCount;
             }
 
-            if (runtime > 0)
+            if (runtime > 0 && fields.Contains(ItemFields.CumulativeRunTimeTicks))
             {
                 dto.CumulativeRunTimeTicks = runtime;
             }

+ 6 - 4
MediaBrowser.Server.Implementations/HttpServer/HttpServer.cs

@@ -356,6 +356,12 @@ namespace MediaBrowser.Server.Implementations.HttpServer
                 try
                 {
                     ProcessRequest(context);
+
+                    var url = context.Request.Url.ToString();
+                    var endPoint = context.Request.RemoteEndPoint;
+
+                    LogResponse(context, url, endPoint);
+
                 }
                 catch (Exception ex)
                 {
@@ -433,9 +439,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer
             var httpRes = new HttpListenerResponseWrapper(context.Response);
             var handler = ServiceStackHttpHandlerFactory.GetHandler(httpReq);
 
-            var url = context.Request.Url.ToString();
-            var endPoint = context.Request.RemoteEndPoint;
-
             var serviceStackHandler = handler as IServiceStackHttpHandler;
 
             if (serviceStackHandler != null)
@@ -446,7 +449,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer
                     httpReq.OperationName = operationName = restHandler.RestPath.RequestType.Name;
                 }
                 serviceStackHandler.ProcessRequest(httpReq, httpRes, operationName);
-                LogResponse(context, url, endPoint);
                 return;
             }
 

+ 9 - 11
MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj

@@ -49,21 +49,21 @@
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\packages\morelinq.1.0.16006\lib\net35\MoreLinq.dll</HintPath>
     </Reference>
-    <Reference Include="ServiceStack, Version=3.9.59.0, Culture=neutral, processorArchitecture=MSIL">
+    <Reference Include="ServiceStack, Version=3.9.60.0, Culture=neutral, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\ServiceStack.3.9.59\lib\net35\ServiceStack.dll</HintPath>
+      <HintPath>..\packages\ServiceStack.3.9.62\lib\net35\ServiceStack.dll</HintPath>
     </Reference>
     <Reference Include="ServiceStack.Api.Swagger, Version=3.9.59.0, Culture=neutral, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\packages\ServiceStack.Api.Swagger.3.9.59\lib\net35\ServiceStack.Api.Swagger.dll</HintPath>
     </Reference>
-    <Reference Include="ServiceStack.Common, Version=3.9.59.0, Culture=neutral, processorArchitecture=MSIL">
+    <Reference Include="ServiceStack.Common, Version=3.9.60.0, Culture=neutral, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\ServiceStack.Common.3.9.59\lib\net35\ServiceStack.Common.dll</HintPath>
+      <HintPath>..\packages\ServiceStack.Common.3.9.62\lib\net35\ServiceStack.Common.dll</HintPath>
     </Reference>
-    <Reference Include="ServiceStack.Interfaces, Version=3.9.59.0, Culture=neutral, processorArchitecture=MSIL">
+    <Reference Include="ServiceStack.Interfaces, Version=3.9.60.0, Culture=neutral, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\ServiceStack.Common.3.9.59\lib\net35\ServiceStack.Interfaces.dll</HintPath>
+      <HintPath>..\packages\ServiceStack.Common.3.9.62\lib\net35\ServiceStack.Interfaces.dll</HintPath>
     </Reference>
     <Reference Include="ServiceStack.OrmLite.SqlServer, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
@@ -73,13 +73,13 @@
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\packages\ServiceStack.Redis.3.9.43\lib\net35\ServiceStack.Redis.dll</HintPath>
     </Reference>
-    <Reference Include="ServiceStack.ServiceInterface, Version=3.9.59.0, Culture=neutral, processorArchitecture=MSIL">
+    <Reference Include="ServiceStack.ServiceInterface, Version=3.9.60.0, Culture=neutral, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\ServiceStack.3.9.59\lib\net35\ServiceStack.ServiceInterface.dll</HintPath>
+      <HintPath>..\packages\ServiceStack.3.9.62\lib\net35\ServiceStack.ServiceInterface.dll</HintPath>
     </Reference>
     <Reference Include="ServiceStack.Text, Version=3.9.59.0, Culture=neutral, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\ServiceStack.Text.3.9.59\lib\net35\ServiceStack.Text.dll</HintPath>
+      <HintPath>..\packages\ServiceStack.Text.3.9.62\lib\net35\ServiceStack.Text.dll</HintPath>
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
@@ -254,10 +254,8 @@
     <EmbeddedResource Include="Localization\Ratings\kz.txt" />
     <EmbeddedResource Include="Localization\Ratings\nz.txt" />
     <EmbeddedResource Include="Localization\Ratings\ru.txt" />
-    <EmbeddedResource Include="MediaEncoder\readme.txt" />
   </ItemGroup>
   <ItemGroup>
-    <EmbeddedResource Include="MediaEncoder\ffmpeg20130904.zip" />
     <None Include="packages.config" />
   </ItemGroup>
   <ItemGroup>

+ 10 - 222
MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs

@@ -1,9 +1,7 @@
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Common.IO;
 using MediaBrowser.Common.MediaInfo;
-using MediaBrowser.Common.Net;
 using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.IO;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Serialization;
 using System;
@@ -13,7 +11,6 @@ using System.Diagnostics;
 using System.Globalization;
 using System.IO;
 using System.Linq;
-using System.Reflection;
 using System.Runtime.InteropServices;
 using System.Text;
 using System.Threading;
@@ -26,12 +23,6 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
     /// </summary>
     public class MediaEncoder : IMediaEncoder, IDisposable
     {
-        /// <summary>
-        /// Gets or sets the zip client.
-        /// </summary>
-        /// <value>The zip client.</value>
-        private readonly IZipClient _zipClient;
-
         /// <summary>
         /// The _logger
         /// </summary>
@@ -48,8 +39,6 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
         /// <value>The json serializer.</value>
         private readonly IJsonSerializer _jsonSerializer;
 
-        private readonly IHttpClient _httpClient;
-
         /// <summary>
         /// The video image resource pool
         /// </summary>
@@ -70,50 +59,25 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
         /// </summary>
         private readonly SemaphoreSlim _ffProbeResourcePool = new SemaphoreSlim(2, 2);
 
-        /// <summary>
-        /// Gets or sets the versioned directory path.
-        /// </summary>
-        /// <value>The versioned directory path.</value>
-        private string VersionedDirectoryPath { get; set; }
+        public string FFMpegPath { get; private set; }
 
-        /// <summary>
-        /// Initializes a new instance of the <see cref="MediaEncoder" /> class.
-        /// </summary>
-        /// <param name="logger">The logger.</param>
-        /// <param name="zipClient">The zip client.</param>
-        /// <param name="appPaths">The app paths.</param>
-        /// <param name="jsonSerializer">The json serializer.</param>
-        public MediaEncoder(ILogger logger, IZipClient zipClient, IApplicationPaths appPaths,
-                            IJsonSerializer jsonSerializer, IHttpClient httpClient)
+        public string FFProbePath { get; private set; }
+
+        public string Version { get; private set; }
+
+        public MediaEncoder(ILogger logger, IApplicationPaths appPaths,
+                            IJsonSerializer jsonSerializer, string ffMpegPath, string ffProbePath, string version)
         {
             _logger = logger;
-            _zipClient = zipClient;
             _appPaths = appPaths;
             _jsonSerializer = jsonSerializer;
-            _httpClient = httpClient;
+            Version = version;
+            FFProbePath = ffProbePath;
+            FFMpegPath = ffMpegPath;
 
             // Not crazy about this but it's the only way to suppress ffmpeg crash dialog boxes
             SetErrorMode(ErrorModes.SEM_FAILCRITICALERRORS | ErrorModes.SEM_NOALIGNMENTFAULTEXCEPT |
                          ErrorModes.SEM_NOGPFAULTERRORBOX | ErrorModes.SEM_NOOPENFILEERRORBOX);
-
-            Task.Run(() => VersionedDirectoryPath = GetVersionedDirectoryPath());
-        }
-
-        /// <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;
         }
 
         /// <summary>
@@ -125,182 +89,6 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
             get { return FFMpegPath; }
         }
 
-        /// <summary>
-        /// The _ FF MPEG path
-        /// </summary>
-        private string _FFMpegPath;
-
-        /// <summary>
-        /// Gets the path to ffmpeg.exe
-        /// </summary>
-        /// <value>The FF MPEG path.</value>
-        public string FFMpegPath
-        {
-            get { return _FFMpegPath ?? (_FFMpegPath = Path.Combine(VersionedDirectoryPath, "ffmpeg.exe")); }
-        }
-
-        /// <summary>
-        /// The _ FF probe path
-        /// </summary>
-        private string _FFProbePath;
-
-        /// <summary>
-        /// Gets the path to ffprobe.exe
-        /// </summary>
-        /// <value>The FF probe path.</value>
-        private string FFProbePath
-        {
-            get { return _FFProbePath ?? (_FFProbePath = Path.Combine(VersionedDirectoryPath, "ffprobe.exe")); }
-        }
-
-        /// <summary>
-        /// Gets the version.
-        /// </summary>
-        /// <value>The version.</value>
-        public string Version
-        {
-            get { return Path.GetFileNameWithoutExtension(VersionedDirectoryPath); }
-        }
-
-        /// <summary>
-        /// Gets the versioned directory path.
-        /// </summary>
-        /// <returns>System.String.</returns>
-        private string GetVersionedDirectoryPath()
-        {
-            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);
-            }
-
-            ExtractTools(assembly, resource, versionedDirectoryPath);
-
-            return 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 void 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);
-        }
-
-        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);
-            }
-        }
-
-        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 info.
         /// </summary>

+ 1 - 1
MediaBrowser.Server.Implementations/Providers/ProviderManager.cs

@@ -128,7 +128,7 @@ namespace MediaBrowser.Server.Implementations.Providers
 
                 // Put this check below the await because the needs refresh of the next tier of providers may depend on the previous ones running
                 //  This is the case for the fan art provider which depends on the movie and tv providers having run before them
-                if (provider.RequiresInternet && item.DontFetchMeta)
+                if (provider.RequiresInternet && item.DontFetchMeta && provider.EnforceDontFetchMetadata)
                 {
                     continue;
                 }

+ 7 - 8
MediaBrowser.Server.Implementations/ScheduledTasks/PluginUpdateTask.cs

@@ -1,4 +1,5 @@
-using MediaBrowser.Common.ScheduledTasks;
+using MediaBrowser.Common;
+using MediaBrowser.Common.ScheduledTasks;
 using MediaBrowser.Common.Updates;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Net;
@@ -23,15 +24,13 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks
 
         private readonly IInstallationManager _installationManager;
 
-        /// <summary>
-        /// Initializes a new instance of the <see cref="PluginUpdateTask" /> class.
-        /// </summary>
-        /// <param name="logger">The logger.</param>
-        /// <param name="installationManager">The installation manager.</param>
-        public PluginUpdateTask(ILogger logger, IInstallationManager installationManager)
+        private readonly IApplicationHost _appHost;
+
+        public PluginUpdateTask(ILogger logger, IInstallationManager installationManager, IApplicationHost appHost)
         {
             _logger = logger;
             _installationManager = installationManager;
+            _appHost = appHost;
         }
 
         /// <summary>
@@ -60,7 +59,7 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks
         {
             progress.Report(0);
 
-            var packagesToInstall = (await _installationManager.GetAvailablePluginUpdates(true, cancellationToken).ConfigureAwait(false)).ToList();
+            var packagesToInstall = (await _installationManager.GetAvailablePluginUpdates(_appHost.ApplicationVersion, true, cancellationToken).ConfigureAwait(false)).ToList();
 
             progress.Report(10);
 

+ 3 - 3
MediaBrowser.Server.Implementations/packages.config

@@ -7,12 +7,12 @@
   <package id="Rx-Core" version="2.1.30214.0" targetFramework="net45" />
   <package id="Rx-Interfaces" version="2.1.30214.0" targetFramework="net45" />
   <package id="Rx-Linq" version="2.1.30214.0" targetFramework="net45" />
-  <package id="ServiceStack" version="3.9.59" targetFramework="net45" />
+  <package id="ServiceStack" version="3.9.62" targetFramework="net45" />
   <package id="ServiceStack.Api.Swagger" version="3.9.59" targetFramework="net45" />
-  <package id="ServiceStack.Common" version="3.9.59" targetFramework="net45" />
+  <package id="ServiceStack.Common" version="3.9.62" targetFramework="net45" />
   <package id="ServiceStack.OrmLite.SqlServer" version="3.9.43" targetFramework="net45" />
   <package id="ServiceStack.Redis" version="3.9.43" targetFramework="net45" />
-  <package id="ServiceStack.Text" version="3.9.59" targetFramework="net45" />
+  <package id="ServiceStack.Text" version="3.9.62" targetFramework="net45" />
   <package id="SharpZipLib" version="0.86.0" targetFramework="net45" />
   <package id="System.Data.SQLite.x86" version="1.0.88.0" targetFramework="net45" />
 </packages>

+ 1 - 1
MediaBrowser.Server.Implementations/swagger-ui/index.html

@@ -20,7 +20,7 @@
 	$(function () {
 	    window.swaggerUi = new SwaggerUi({
 	        discoveryUrl: "../resources",
-	        apiKey: "special-key",
+                apiKey:"special-key",
                 dom_id:"swagger-ui-container",
                 supportHeaderParams: false,
                 supportedSubmitMethods: ['get', 'post', 'put'],

+ 14 - 4
MediaBrowser.ServerApplication/ApplicationHost.cs

@@ -60,7 +60,6 @@ using System.Net.Http;
 using System.Reflection;
 using System.Threading;
 using System.Threading.Tasks;
-using System.Windows;
 
 namespace MediaBrowser.ServerApplication
 {
@@ -285,8 +284,7 @@ namespace MediaBrowser.ServerApplication
 
             RegisterSingleInstance<ILibrarySearchEngine>(() => new LuceneSearchEngine(ApplicationPaths, LogManager, LibraryManager));
 
-            MediaEncoder = new MediaEncoder(LogManager.GetLogger("MediaEncoder"), ZipClient, ApplicationPaths, JsonSerializer, HttpClient);
-            RegisterSingleInstance(MediaEncoder);
+            await RegisterMediaEncoder().ConfigureAwait(false);
 
             var clientConnectionManager = new SessionManager(UserDataRepository, ServerConfigurationManager, Logger, UserRepository);
             RegisterSingleInstance<ISessionManager>(clientConnectionManager);
@@ -317,6 +315,18 @@ namespace MediaBrowser.ServerApplication
             SetKernelProperties();
         }
 
+        /// <summary>
+        /// Registers the media encoder.
+        /// </summary>
+        /// <returns>Task.</returns>
+        private async Task RegisterMediaEncoder()
+        {
+            var info = await new FFMpegDownloader(Logger, ApplicationPaths, HttpClient, ZipClient).GetFFMpegInfo().ConfigureAwait(false);
+
+            MediaEncoder = new MediaEncoder(LogManager.GetLogger("MediaEncoder"), ApplicationPaths, JsonSerializer, info.Path, info.ProbePath, info.Version);
+            RegisterSingleInstance(MediaEncoder);
+        }
+
         /// <summary>
         /// Sets the kernel properties.
         /// </summary>
@@ -708,7 +718,7 @@ namespace MediaBrowser.ServerApplication
         {
             var availablePackages = await InstallationManager.GetAvailablePackagesWithoutRegistrationInfo(cancellationToken).ConfigureAwait(false);
 
-            var version = InstallationManager.GetLatestCompatibleVersion(availablePackages, Constants.MbServerPkgName, ConfigurationManager.CommonConfiguration.SystemUpdateLevel);
+            var version = InstallationManager.GetLatestCompatibleVersion(availablePackages, Constants.MbServerPkgName, ApplicationVersion, ConfigurationManager.CommonConfiguration.SystemUpdateLevel);
 
             return version != null ? new CheckForUpdateResult { AvailableVersion = version.version, IsUpdateAvailable = version.version > ApplicationVersion, Package = version } :
                        new CheckForUpdateResult { AvailableVersion = ApplicationVersion, IsUpdateAvailable = false };

+ 205 - 0
MediaBrowser.ServerApplication/Implementations/FFMpegDownloader.cs

@@ -0,0 +1,205 @@
+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; }
+    }
+}

+ 0 - 0
MediaBrowser.Server.Implementations/MediaEncoder/ffmpeg20130904.zip.REMOVED.git-id → MediaBrowser.ServerApplication/Implementations/ffmpeg20130904.zip.REMOVED.git-id


+ 0 - 0
MediaBrowser.Server.Implementations/MediaEncoder/readme.txt → MediaBrowser.ServerApplication/Implementations/readme.txt


+ 14 - 9
MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj

@@ -142,17 +142,17 @@
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\packages\MediaBrowser.IsoMounting.3.0.56\lib\net45\pfmclrapi.dll</HintPath>
     </Reference>
-    <Reference Include="ServiceStack, Version=3.9.59.0, Culture=neutral, processorArchitecture=MSIL">
+    <Reference Include="ServiceStack, Version=3.9.60.0, Culture=neutral, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\ServiceStack.3.9.59\lib\net35\ServiceStack.dll</HintPath>
+      <HintPath>..\packages\ServiceStack.3.9.62\lib\net35\ServiceStack.dll</HintPath>
     </Reference>
-    <Reference Include="ServiceStack.Common, Version=3.9.59.0, Culture=neutral, processorArchitecture=MSIL">
+    <Reference Include="ServiceStack.Common, Version=3.9.60.0, Culture=neutral, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\ServiceStack.Common.3.9.59\lib\net35\ServiceStack.Common.dll</HintPath>
+      <HintPath>..\packages\ServiceStack.Common.3.9.62\lib\net35\ServiceStack.Common.dll</HintPath>
     </Reference>
-    <Reference Include="ServiceStack.Interfaces, Version=3.9.59.0, Culture=neutral, processorArchitecture=MSIL">
+    <Reference Include="ServiceStack.Interfaces, Version=3.9.60.0, Culture=neutral, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\ServiceStack.Common.3.9.59\lib\net35\ServiceStack.Interfaces.dll</HintPath>
+      <HintPath>..\packages\ServiceStack.Common.3.9.62\lib\net35\ServiceStack.Interfaces.dll</HintPath>
     </Reference>
     <Reference Include="ServiceStack.OrmLite.SqlServer">
       <HintPath>..\packages\ServiceStack.OrmLite.SqlServer.3.9.44\lib\ServiceStack.OrmLite.SqlServer.dll</HintPath>
@@ -160,13 +160,13 @@
     <Reference Include="ServiceStack.Redis">
       <HintPath>..\packages\ServiceStack.Redis.3.9.44\lib\net35\ServiceStack.Redis.dll</HintPath>
     </Reference>
-    <Reference Include="ServiceStack.ServiceInterface, Version=3.9.59.0, Culture=neutral, processorArchitecture=MSIL">
+    <Reference Include="ServiceStack.ServiceInterface, Version=3.9.60.0, Culture=neutral, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\ServiceStack.3.9.59\lib\net35\ServiceStack.ServiceInterface.dll</HintPath>
+      <HintPath>..\packages\ServiceStack.3.9.62\lib\net35\ServiceStack.ServiceInterface.dll</HintPath>
     </Reference>
     <Reference Include="ServiceStack.Text, Version=3.9.59.0, Culture=neutral, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\ServiceStack.Text.3.9.59\lib\net35\ServiceStack.Text.dll</HintPath>
+      <HintPath>..\packages\ServiceStack.Text.3.9.62\lib\net35\ServiceStack.Text.dll</HintPath>
     </Reference>
     <Reference Include="SimpleInjector, Version=2.3.5.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
@@ -210,6 +210,7 @@
     </Compile>
     <Compile Include="EntryPoints\StartupWizard.cs" />
     <Compile Include="EntryPoints\UdpServerEntryPoint.cs" />
+    <Compile Include="Implementations\FFMpegDownloader.cs" />
     <Compile Include="MainStartup.cs" />
     <Compile Include="BackgroundServiceInstaller.cs">
       <SubType>Component</SubType>
@@ -277,6 +278,7 @@
       <LastGenOutput>Resources.Designer.cs</LastGenOutput>
     </EmbeddedResource>
     <None Include="app.manifest" />
+    <EmbeddedResource Include="Implementations\ffmpeg20130904.zip" />
     <None Include="packages.config" />
     <None Include="Properties\Settings.settings">
       <Generator>SettingsSingleFileGenerator</Generator>
@@ -388,6 +390,9 @@
   <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 (

+ 3 - 3
MediaBrowser.ServerApplication/packages.config

@@ -6,11 +6,11 @@
   <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.59" targetFramework="net45" />
-  <package id="ServiceStack.Common" version="3.9.59" targetFramework="net45" />
+  <package id="ServiceStack" version="3.9.62" targetFramework="net45" />
+  <package id="ServiceStack.Common" version="3.9.62" targetFramework="net45" />
   <package id="ServiceStack.OrmLite.SqlServer" version="3.9.44" targetFramework="net45" />
   <package id="ServiceStack.Redis" version="3.9.44" targetFramework="net45" />
-  <package id="ServiceStack.Text" version="3.9.59" targetFramework="net45" />
+  <package id="ServiceStack.Text" version="3.9.62" targetFramework="net45" />
   <package id="SimpleInjector" version="2.3.5" targetFramework="net45" />
   <package id="System.Data.SQLite.x86" version="1.0.88.0" targetFramework="net45" />
 </packages>

+ 5 - 5
MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj

@@ -35,17 +35,17 @@
     <RunPostBuildEvent>Always</RunPostBuildEvent>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="ServiceStack.Common, Version=3.9.59.0, Culture=neutral, processorArchitecture=MSIL">
+    <Reference Include="ServiceStack.Common, Version=3.9.60.0, Culture=neutral, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\ServiceStack.Common.3.9.59\lib\net35\ServiceStack.Common.dll</HintPath>
+      <HintPath>..\packages\ServiceStack.Common.3.9.62\lib\net35\ServiceStack.Common.dll</HintPath>
     </Reference>
-    <Reference Include="ServiceStack.Interfaces, Version=3.9.59.0, Culture=neutral, processorArchitecture=MSIL">
+    <Reference Include="ServiceStack.Interfaces, Version=3.9.60.0, Culture=neutral, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\ServiceStack.Common.3.9.59\lib\net35\ServiceStack.Interfaces.dll</HintPath>
+      <HintPath>..\packages\ServiceStack.Common.3.9.62\lib\net35\ServiceStack.Interfaces.dll</HintPath>
     </Reference>
     <Reference Include="ServiceStack.Text, Version=3.9.59.0, Culture=neutral, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\ServiceStack.Text.3.9.59\lib\net35\ServiceStack.Text.dll</HintPath>
+      <HintPath>..\packages\ServiceStack.Text.3.9.62\lib\net35\ServiceStack.Text.dll</HintPath>
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />

+ 2 - 2
MediaBrowser.WebDashboard/packages.config

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
   <package id="MediaBrowser.ApiClient.Javascript" version="3.0.175" targetFramework="net45" />
-  <package id="ServiceStack.Common" version="3.9.59" targetFramework="net45" />
-  <package id="ServiceStack.Text" version="3.9.59" targetFramework="net45" />
+  <package id="ServiceStack.Common" version="3.9.62" targetFramework="net45" />
+  <package id="ServiceStack.Text" version="3.9.62" targetFramework="net45" />
 </packages>

+ 2 - 2
Nuget/MediaBrowser.Common.Internal.nuspec

@@ -2,7 +2,7 @@
 <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
     <metadata>
         <id>MediaBrowser.Common.Internal</id>
-        <version>3.0.205</version>
+        <version>3.0.206</version>
         <title>MediaBrowser.Common.Internal</title>
         <authors>Luke</authors>
         <owners>ebr,Luke,scottisafool</owners>
@@ -12,7 +12,7 @@
         <description>Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption.</description>
         <copyright>Copyright © Media Browser 2013</copyright>
         <dependencies>
-            <dependency id="MediaBrowser.Common" version="3.0.205" />
+            <dependency id="MediaBrowser.Common" version="3.0.206" />
             <dependency id="NLog" version="2.0.1.2" />
             <dependency id="ServiceStack.Text" version="3.9.58" />
             <dependency id="SimpleInjector" version="2.3.2" />

+ 1 - 1
Nuget/MediaBrowser.Common.nuspec

@@ -2,7 +2,7 @@
 <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
     <metadata>
         <id>MediaBrowser.Common</id>
-        <version>3.0.205</version>
+        <version>3.0.206</version>
         <title>MediaBrowser.Common</title>
         <authors>Media Browser Team</authors>
         <owners>ebr,Luke,scottisafool</owners>

+ 2 - 2
Nuget/MediaBrowser.Server.Core.nuspec

@@ -2,7 +2,7 @@
 <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
     <metadata>
         <id>MediaBrowser.Server.Core</id>
-        <version>3.0.205</version>
+        <version>3.0.206</version>
         <title>Media Browser.Server.Core</title>
         <authors>Media Browser Team</authors>
         <owners>ebr,Luke,scottisafool</owners>
@@ -12,7 +12,7 @@
         <description>Contains core components required to build plugins for Media Browser Server.</description>
         <copyright>Copyright © Media Browser 2013</copyright>
         <dependencies>
-            <dependency id="MediaBrowser.Common" version="3.0.205" />
+            <dependency id="MediaBrowser.Common" version="3.0.206" />
         </dependencies>
     </metadata>
     <files>