فهرست منبع

Merge pull request #2998 from MediaBrowser/beta

Beta
Luke 7 سال پیش
والد
کامیت
008cea6984
36فایلهای تغییر یافته به همراه284 افزوده شده و 169 حذف شده
  1. 2 2
      Emby.Drawing.Skia/Emby.Drawing.Skia.csproj
  2. 53 9
      Emby.Drawing.Skia/SkiaEncoder.cs
  3. 2 2
      Emby.Drawing.Skia/StripCollageBuilder.cs
  4. 1 1
      Emby.Drawing.Skia/packages.config
  5. 30 33
      Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs
  6. 2 1
      Emby.Server.Implementations/Data/SqliteItemRepository.cs
  7. 2 2
      Emby.Server.Implementations/Emby.Server.Implementations.csproj
  8. 1 1
      Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
  9. 30 9
      Emby.Server.Implementations/Library/SearchEngine.cs
  10. 1 1
      Emby.Server.Implementations/LiveTv/TunerHosts/LiveStream.cs
  11. 1 6
      Emby.Server.Implementations/Localization/Core/en-US.json
  12. 22 22
      Emby.Server.Implementations/Localization/Core/hu.json
  13. 13 0
      Emby.Server.Implementations/Localization/LocalizationManager.cs
  14. 17 0
      Emby.Server.Implementations/ServerApplicationPaths.cs
  15. 1 1
      Emby.Server.Implementations/packages.config
  16. 0 2
      MediaBrowser.Api/ConfigurationService.cs
  17. 1 11
      MediaBrowser.Api/StartupWizardService.cs
  18. 1 5
      MediaBrowser.Controller/Configuration/IServerConfigurationManager.cs
  19. 17 2
      MediaBrowser.Controller/Entities/BaseItem.cs
  20. 2 0
      MediaBrowser.Controller/IServerApplicationPaths.cs
  21. 0 9
      MediaBrowser.Model/Dlna/PlaybackException.cs
  22. 0 9
      MediaBrowser.Model/Dlna/StreamBuilder.cs
  23. 3 0
      MediaBrowser.Model/Globalization/ILocalizationManager.cs
  24. 0 1
      MediaBrowser.Model/MediaBrowser.Model.csproj
  25. 12 1
      MediaBrowser.Providers/Manager/ItemImageProvider.cs
  26. 21 11
      MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs
  27. 5 1
      MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs
  28. 4 2
      MediaBrowser.Server.Mono/ImageEncoderHelper.cs
  29. 4 4
      MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj
  30. 1 1
      MediaBrowser.Server.Mono/Program.cs
  31. 2 2
      MediaBrowser.Server.Mono/packages.config
  32. 4 2
      MediaBrowser.ServerApplication/ImageEncoderHelper.cs
  33. 15 2
      MediaBrowser.ServerApplication/MainStartup.cs
  34. 6 6
      MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj
  35. 6 6
      MediaBrowser.ServerApplication/ServerNotifyIcon.cs
  36. 2 2
      MediaBrowser.ServerApplication/packages.config

+ 2 - 2
Emby.Drawing.Skia/Emby.Drawing.Skia.csproj

@@ -63,8 +63,8 @@
     <EmbeddedResource Include="fonts\robotoregular.ttf" />
   </ItemGroup>
   <ItemGroup>
-    <Reference Include="SkiaSharp, Version=1.58.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
-      <HintPath>..\packages\SkiaSharp.1.58.1\lib\portable-net45+win8+wpa81+wp8\SkiaSharp.dll</HintPath>
+    <Reference Include="SkiaSharp, Version=1.59.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
+      <HintPath>..\packages\SkiaSharp.1.59.2\lib\portable-net45+win8+wpa81+wp8\SkiaSharp.dll</HintPath>
     </Reference>
   </ItemGroup>
   <ItemGroup>

+ 53 - 9
Emby.Drawing.Skia/SkiaEncoder.cs

@@ -10,22 +10,27 @@ using System.IO;
 using System.Linq;
 using System.Reflection;
 using System.Threading.Tasks;
+using MediaBrowser.Controller.Extensions;
+using System.Globalization;
+using MediaBrowser.Model.Globalization;
 
 namespace Emby.Drawing.Skia
 {
     public class SkiaEncoder : IImageEncoder
     {
         private readonly ILogger _logger;
-        private readonly IApplicationPaths _appPaths;
+        private static IApplicationPaths _appPaths;
         private readonly Func<IHttpClient> _httpClientFactory;
         private readonly IFileSystem _fileSystem;
+        private static ILocalizationManager _localizationManager;
 
-        public SkiaEncoder(ILogger logger, IApplicationPaths appPaths, Func<IHttpClient> httpClientFactory, IFileSystem fileSystem)
+        public SkiaEncoder(ILogger logger, IApplicationPaths appPaths, Func<IHttpClient> httpClientFactory, IFileSystem fileSystem, ILocalizationManager localizationManager)
         {
             _logger = logger;
             _appPaths = appPaths;
             _httpClientFactory = httpClientFactory;
             _fileSystem = fileSystem;
+            _localizationManager = localizationManager;
 
             LogVersion();
         }
@@ -190,14 +195,53 @@ namespace Emby.Drawing.Skia
             }
         }
 
+        private static bool HasDiacritics(string text)
+        {
+            return !String.Equals(text, text.RemoveDiacritics(), StringComparison.Ordinal);
+        }
+
+        private static bool RequiresSpecialCharacterHack(string path)
+        {
+            if (_localizationManager.HasUnicodeCategory(path, UnicodeCategory.OtherLetter))
+            {
+                return true;
+            }
+
+            if (HasDiacritics(path))
+            {
+                return true;
+            }
+
+            return false;
+        }
+
+        private static string NormalizePath(string path, IFileSystem fileSystem)
+        {
+            if (!RequiresSpecialCharacterHack(path))
+            {
+                return path;
+            }
+
+            var tempPath = Path.Combine(_appPaths.TempDirectory, Guid.NewGuid() + Path.GetExtension(path) ?? string.Empty);
+
+            fileSystem.CopyFile(path, tempPath, true);
+
+            return tempPath;
+        }
+
         private static string[] TransparentImageTypes = new string[] { ".png", ".gif", ".webp" };
-        internal static SKBitmap Decode(string path, bool forceCleanBitmap, out SKCodecOrigin origin)
+        internal static SKBitmap Decode(string path, bool forceCleanBitmap, IFileSystem fileSystem, out SKCodecOrigin origin)
         {
+            if (!fileSystem.FileExists(path))
+            {
+                throw new FileNotFoundException("File not found", path);
+            }
+
             var requiresTransparencyHack = TransparentImageTypes.Contains(Path.GetExtension(path) ?? string.Empty);
 
             if (requiresTransparencyHack || forceCleanBitmap)
             {
-                using (var stream = new SKFileStream(path))
+                using (var stream = new SKFileStream(NormalizePath(path, fileSystem)))
                 {
                     using (var codec = SKCodec.Create(stream))
                     {
@@ -227,11 +271,11 @@ namespace Emby.Drawing.Skia
                 }
             }
 
-            var resultBitmap = SKBitmap.Decode(path);
+            var resultBitmap = SKBitmap.Decode(NormalizePath(path, fileSystem));
 
             if (resultBitmap == null)
             {
-                return Decode(path, true, out origin);
+                return Decode(path, true, fileSystem, out origin);
             }
 
             // If we have to resize these they often end up distorted
@@ -239,7 +283,7 @@ namespace Emby.Drawing.Skia
             {
                 using (resultBitmap)
                 {
-                    return Decode(path, true, out origin);
+                    return Decode(path, true, fileSystem, out origin);
                 }
             }
 
@@ -251,13 +295,13 @@ namespace Emby.Drawing.Skia
         {
             if (cropWhitespace)
             {
-                using (var bitmap = Decode(path, forceAnalyzeBitmap, out origin))
+                using (var bitmap = Decode(path, forceAnalyzeBitmap, _fileSystem, out origin))
                 {
                     return CropWhiteSpace(bitmap);
                 }
             }
 
-            return Decode(path, forceAnalyzeBitmap, out origin);
+            return Decode(path, forceAnalyzeBitmap, _fileSystem, out origin);
         }
 
         private SKBitmap GetBitmap(string path, bool cropWhitespace, bool autoOrient)

+ 2 - 2
Emby.Drawing.Skia/StripCollageBuilder.cs

@@ -83,7 +83,7 @@ namespace Emby.Drawing.Skia
                 for (int i = 0; i < 4; i++)
                 {
                     SKCodecOrigin origin;
-                    using (var currentBitmap = SkiaEncoder.Decode(paths[imageIndex], false, out origin))
+                    using (var currentBitmap = SkiaEncoder.Decode(paths[imageIndex], false, _fileSystem, out origin))
                     {
                         // resize to the same aspect as the original
                         int iWidth = (int)Math.Abs(iHeight * currentBitmap.Width / currentBitmap.Height);
@@ -165,7 +165,7 @@ namespace Emby.Drawing.Skia
                     for (var y = 0; y < 2; y++)
                     {
                         SKCodecOrigin origin;
-                        using (var currentBitmap = SkiaEncoder.Decode(paths[imageIndex], false, out origin))
+                        using (var currentBitmap = SkiaEncoder.Decode(paths[imageIndex], false, _fileSystem, out origin))
                         {
                             using (var resizedBitmap = new SKBitmap(cellWidth, cellHeight, currentBitmap.ColorType, currentBitmap.AlphaType))
                             {

+ 1 - 1
Emby.Drawing.Skia/packages.config

@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="SkiaSharp" version="1.58.1" targetFramework="portable45-net45+win8" />
+  <package id="SkiaSharp" version="1.59.2" targetFramework="portable45-net45+win8" />
 </packages>

+ 30 - 33
Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs

@@ -195,52 +195,49 @@ namespace Emby.Server.Implementations.Configuration
             }
         }
 
-        public void DisableMetadataService(string service)
+        public bool SetOptimalValues()
         {
-            DisableMetadataService(typeof(Movie), Configuration, service);
-            DisableMetadataService(typeof(Episode), Configuration, service);
-            DisableMetadataService(typeof(Series), Configuration, service);
-            DisableMetadataService(typeof(Season), Configuration, service);
-            DisableMetadataService(typeof(MusicArtist), Configuration, service);
-            DisableMetadataService(typeof(MusicAlbum), Configuration, service);
-            DisableMetadataService(typeof(MusicVideo), Configuration, service);
-            DisableMetadataService(typeof(Video), Configuration, service);
-        }
+            var config = Configuration;
 
-        private void DisableMetadataService(Type type, ServerConfiguration config, string service)
-        {
-            var options = GetMetadataOptions(type, config);
+            var changed = false;
 
-            if (!options.DisabledMetadataSavers.Contains(service, StringComparer.OrdinalIgnoreCase))
+            if (!config.EnableCaseSensitiveItemIds)
             {
-                var list = options.DisabledMetadataSavers.ToList();
-
-                list.Add(service);
-
-                options.DisabledMetadataSavers = list.ToArray(list.Count);
+                config.EnableCaseSensitiveItemIds = true;
+                changed = true;
             }
-        }
 
-        private MetadataOptions GetMetadataOptions(Type type, ServerConfiguration config)
-        {
-            var options = config.MetadataOptions
-                .FirstOrDefault(i => string.Equals(i.ItemType, type.Name, StringComparison.OrdinalIgnoreCase));
+            if (!config.SkipDeserializationForBasicTypes)
+            {
+                config.SkipDeserializationForBasicTypes = true;
+                changed = true;
+            }
 
-            if (options == null)
+            if (!config.EnableSimpleArtistDetection)
             {
-                var list = config.MetadataOptions.ToList();
+                config.EnableSimpleArtistDetection = true;
+                changed = true;
+            }
 
-                options = new MetadataOptions
-                {
-                    ItemType = type.Name
-                };
+            if (!config.EnableNormalizedItemByNameIds)
+            {
+                config.EnableNormalizedItemByNameIds = true;
+                changed = true;
+            }
 
-                list.Add(options);
+            if (!config.DisableLiveTvChannelUserDataName)
+            {
+                config.DisableLiveTvChannelUserDataName = true;
+                changed = true;
+            }
 
-                config.MetadataOptions = list.ToArray(list.Count);
+            if (!config.EnableNewOmdbSupport)
+            {
+                config.EnableNewOmdbSupport = true;
+                changed = true;
             }
 
-            return options;
+            return changed;
         }
     }
 }

+ 2 - 1
Emby.Server.Implementations/Data/SqliteItemRepository.cs

@@ -5298,7 +5298,8 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
                 OfficialRatings = query.OfficialRatings,
                 GenreIds = query.GenreIds,
                 Genres = query.Genres,
-                Years = query.Years
+                Years = query.Years,
+                NameContains = query.NameContains
             };
 
             var outerWhereClauses = GetWhereClauses(outerQuery, null);

+ 2 - 2
Emby.Server.Implementations/Emby.Server.Implementations.csproj

@@ -651,8 +651,8 @@
     <Reference Include="SharpCompress, Version=0.18.2.0, Culture=neutral, PublicKeyToken=afb0a02973931d96, processorArchitecture=MSIL">
       <HintPath>..\packages\SharpCompress.0.18.2\lib\net45\SharpCompress.dll</HintPath>
     </Reference>
-    <Reference Include="SimpleInjector, Version=4.0.8.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
-      <HintPath>..\packages\SimpleInjector.4.0.8\lib\net45\SimpleInjector.dll</HintPath>
+    <Reference Include="SimpleInjector, Version=4.0.12.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
+      <HintPath>..\packages\SimpleInjector.4.0.12\lib\net45\SimpleInjector.dll</HintPath>
     </Reference>
     <Reference Include="SQLitePCL.pretty, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>..\packages\SQLitePCL.pretty.1.1.0\lib\portable-net45+netcore45+wpa81+wp8\SQLitePCL.pretty.dll</HintPath>

+ 1 - 1
Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs

@@ -160,7 +160,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
                     ProductionYear = video.Year,
                     Name = parseName ?
                         video.Name :
-                        Path.GetFileName(video.Files[0].Path),
+                        Path.GetFileNameWithoutExtension(video.Files[0].Path),
                     AdditionalParts = video.Files.Skip(1).Select(i => i.Path).ToArray(),
                     LocalAlternateVersions = video.AlternateVersions.Select(i => i.Path).ToArray()
                 };

+ 30 - 9
Emby.Server.Implementations/Library/SearchEngine.cs

@@ -99,8 +99,6 @@ namespace Emby.Server.Implementations.Library
 
             var terms = GetWords(searchTerm);
 
-            var hints = new List<Tuple<BaseItem, string, int>>();
-
             var excludeItemTypes = query.ExcludeItemTypes.ToList();
             var includeItemTypes = (query.IncludeItemTypes ?? new string[] { }).ToList();
 
@@ -161,8 +159,15 @@ namespace Emby.Server.Implementations.Library
 
             AddIfMissing(excludeItemTypes, typeof(CollectionFolder).Name);
             AddIfMissing(excludeItemTypes, typeof(Folder).Name);
+            var mediaTypes = query.MediaTypes.ToList();
+
+            if (includeItemTypes.Count > 0)
+            {
+                excludeItemTypes.Clear();
+                mediaTypes.Clear();
+            }
 
-            var mediaItems = _libraryManager.GetItemList(new InternalItemsQuery(user)
+            var searchQuery = new InternalItemsQuery(user)
             {
                 NameContains = searchTerm,
                 ExcludeItemTypes = excludeItemTypes.ToArray(excludeItemTypes.Count),
@@ -178,7 +183,7 @@ namespace Emby.Server.Implementations.Library
                 IsNews = query.IsNews,
                 IsSeries = query.IsSeries,
                 IsSports = query.IsSports,
-                MediaTypes = query.MediaTypes,
+                MediaTypes = mediaTypes.ToArray(),
 
                 DtoOptions = new DtoOptions
                 {
@@ -189,17 +194,33 @@ namespace Emby.Server.Implementations.Library
                          ItemFields.ChannelInfo
                     }
                 }
-            });
+            };
+
+            List<BaseItem> mediaItems;
+
+            if (searchQuery.IncludeItemTypes.Length == 1 && string.Equals(searchQuery.IncludeItemTypes[0], "MusicArtist", StringComparison.OrdinalIgnoreCase))
+            {
+                if (searchQuery.ParentId.HasValue)
+                {
+                    searchQuery.AncestorIds = new string[] { searchQuery.ParentId.Value.ToString("N") };
+                }
+                searchQuery.ParentId = null;
+                searchQuery.IncludeItemsByName = true;
+                searchQuery.IncludeItemTypes = new string[] { };
+                mediaItems = _libraryManager.GetArtists(searchQuery).Items.Select(i => i.Item1).ToList();
+            }
+            else
+            {
+                mediaItems = _libraryManager.GetItemList(searchQuery);
+            }
 
-            // Add search hints based on item name
-            hints.AddRange(mediaItems.Select(item =>
+            var returnValue = mediaItems.Select(item =>
             {
                 var index = GetIndex(item.Name, searchTerm, terms);
 
                 return new Tuple<BaseItem, string, int>(item, index.Item1, index.Item2);
-            }));
 
-            var returnValue = hints.Where(i => i.Item3 >= 0).OrderBy(i => i.Item3).ThenBy(i => i.Item1.SortName).Select(i => new SearchHintInfo
+            }).OrderBy(i => i.Item3).ThenBy(i => i.Item1.SortName).Select(i => new SearchHintInfo
             {
                 Item = i.Item1,
                 MatchedTerm = i.Item2

+ 1 - 1
Emby.Server.Implementations/LiveTv/TunerHosts/LiveStream.cs

@@ -44,7 +44,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
             EnableStreamSharing = true;
             SharedStreamIds = new List<string>();
             UniqueId = Guid.NewGuid().ToString("N");
-            TempFilePath = Path.Combine(appPaths.TranscodingTempPath, UniqueId + ".ts");
+            TempFilePath = Path.Combine(appPaths.GetTranscodingTempPath(), UniqueId + ".ts");
         }
 
         public virtual Task Open(CancellationToken openCancellationToken)

+ 1 - 6
Emby.Server.Implementations/Localization/Core/en-US.json

@@ -87,10 +87,5 @@
   "User": "User",
   "System": "System",
   "Application": "Application",
-  "Plugin": "Plugin",
-  "LabelExit": "Exit",
-  "LabelVisitCommunity": "Visit Community",
-  "LabelBrowseLibrary": "Browse Library",
-  "LabelConfigureServer": "Configure Emby",
-  "LabelRestartServer": "Restart Server"
+  "Plugin": "Plugin"
 }

+ 22 - 22
Emby.Server.Implementations/Localization/Core/hu.json

@@ -2,31 +2,31 @@
     "Latest": "Leg\u00fajabb",
     "ValueSpecialEpisodeName": "Special - {0}",
     "Inherit": "Inherit",
-    "Books": "Books",
-    "Music": "Music",
-    "Games": "Games",
-    "Photos": "Photos",
-    "MixedContent": "Mixed content",
-    "MusicVideos": "Music videos",
-    "HomeVideos": "Home videos",
-    "Playlists": "Playlists",
+    "Books": "K\u00f6nyvek",
+    "Music": "Zene",
+    "Games": "J\u00e1t\u00e9kok",
+    "Photos": "F\u00e9nyk\u00e9pek",
+    "MixedContent": "Vegyes tartalom",
+    "MusicVideos": "Zenei Vide\u00f3k",
+    "HomeVideos": "H\u00e1zi vide\u00f3k",
+    "Playlists": "Lej\u00e1tsz\u00e1si list\u00e1k",
     "HeaderRecordingGroups": "Recording Groups",
     "HeaderContinueWatching": "Vet\u00edt\u00e9s(ek) folytat\u00e1sa",
-    "HeaderFavoriteArtists": "Favorite Artists",
-    "HeaderFavoriteSongs": "Favorite Songs",
-    "HeaderAlbumArtists": "Album Artists",
-    "HeaderFavoriteAlbums": "Favorite Albums",
+    "HeaderFavoriteArtists": "Kedvenc M\u0171v\u00e9szek",
+    "HeaderFavoriteSongs": "Kedvenc Dalok",
+    "HeaderAlbumArtists": "Album El\u0151ad\u00f3k",
+    "HeaderFavoriteAlbums": "Kedvenc Albumok",
     "HeaderFavoriteEpisodes": "Kedvenc Epiz\u00f3dok",
     "HeaderFavoriteShows": "Kedvenc M\u0171sorok",
     "HeaderNextUp": "K\u00f6vetkezik",
-    "Favorites": "Favorites",
+    "Favorites": "Kedvencek",
     "Collections": "Gy\u0171jtem\u00e9nyek",
     "Channels": "Csatorn\u00e1k",
-    "Movies": "Movies",
-    "Albums": "Albums",
-    "Artists": "Artists",
-    "Folders": "Folders",
-    "Songs": "Songs",
+    "Movies": "Filmek",
+    "Albums": "Albumok",
+    "Artists": "El\u0151ad\u00f3k",
+    "Folders": "K\u00f6nyvt\u00e1rak",
+    "Songs": "Dalok",
     "TvShows": "TV Shows",
     "Shows": "Shows",
     "Genres": "M\u0171fajok",
@@ -38,15 +38,15 @@
     "ScheduledTaskFailedWithName": "{0} failed",
     "LabelRunningTimeValue": "Running time: {0}",
     "ScheduledTaskStartedWithName": "{0} started",
-    "VersionNumber": "Version {0}",
+    "VersionNumber": "Verzi\u00f3 {0}",
     "PluginInstalledWithName": "{0} telep\u00edtve",
     "StartupEmbyServerIsLoading": "Emby Szerver bet\u00f6lt\u0151dik. K\u00e9rj\u00fck, pr\u00f3b\u00e1ld meg \u00fajra k\u00e9s\u0151bb.",
-    "PluginUpdatedWithName": "{0} was updated",
+    "PluginUpdatedWithName": "{0} friss\u00edtve",
     "PluginUninstalledWithName": "{0} elt\u00e1vol\u00edtva",
     "ItemAddedWithName": "{0} was added to the library",
     "ItemRemovedWithName": "{0} was removed from the library",
-    "LabelIpAddressValue": "Ip address: {0}",
-    "DeviceOnlineWithName": "{0} is connected",
+    "LabelIpAddressValue": "Ip c\u00edm: {0}",
+    "DeviceOnlineWithName": "{0} bel\u00e9pett",
     "UserOnlineFromDevice": "{0} is online from {1}",
     "ProviderValue": "Provider: {0}",
     "SubtitlesDownloadedForItem": "Subtitles downloaded for {0}",

+ 13 - 0
Emby.Server.Implementations/Localization/LocalizationManager.cs

@@ -308,6 +308,19 @@ namespace Emby.Server.Implementations.Localization
             return value == null ? (int?)null : value.Value;
         }
 
+        public bool HasUnicodeCategory(string value, UnicodeCategory category)
+        {
+            foreach (var chr in value)
+            {
+                if (char.GetUnicodeCategory(chr) == category)
+                {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
         public string GetLocalizedString(string phrase)
         {
             return GetLocalizedString(phrase, _configurationManager.Configuration.UICulture);

+ 17 - 0
Emby.Server.Implementations/ServerApplicationPaths.cs

@@ -206,6 +206,23 @@ namespace Emby.Server.Implementations
             }
         }
 
+        public string GetTranscodingTempPath()
+        {
+            var path = TranscodingTempPath;
+
+            try
+            {
+                Directory.CreateDirectory(path);
+                return path;
+            }
+            catch
+            {
+                path = Path.Combine(ProgramDataPath, "transcoding-temp");
+                Directory.CreateDirectory(path);
+                return path;
+            }
+        }
+
         /// <summary>
         /// Gets the game genre path.
         /// </summary>

+ 1 - 1
Emby.Server.Implementations/packages.config

@@ -3,7 +3,7 @@
   <package id="Emby.XmlTv" version="1.0.10" targetFramework="net46" />
   <package id="ServiceStack.Text" version="4.5.8" targetFramework="net46" />
   <package id="SharpCompress" version="0.18.2" targetFramework="net46" />
-  <package id="SimpleInjector" version="4.0.8" targetFramework="net46" />
+  <package id="SimpleInjector" version="4.0.12" targetFramework="net46" />
   <package id="SQLitePCL.pretty" version="1.1.0" targetFramework="portable45-net45+win8" />
   <package id="SQLitePCLRaw.core" version="1.1.8" targetFramework="net46" />
 </packages>

+ 0 - 2
MediaBrowser.Api/ConfigurationService.cs

@@ -134,8 +134,6 @@ namespace MediaBrowser.Api
 
         public void Post(AutoSetMetadataOptions request)
         {
-            _configurationManager.DisableMetadataService("Emby Xml");
-            _configurationManager.SaveConfiguration();
         }
 
         /// <summary>

+ 1 - 11
MediaBrowser.Api/StartupWizardService.cs

@@ -63,7 +63,7 @@ namespace MediaBrowser.Api
         public void Post(ReportStartupWizardComplete request)
         {
             _config.Configuration.IsStartupWizardCompleted = true;
-            SetWizardFinishValues(_config.Configuration);
+            _config.SetOptimalValues();
             _config.SaveConfiguration();
         }
 
@@ -87,16 +87,6 @@ namespace MediaBrowser.Api
             return result;
         }
 
-        private void SetWizardFinishValues(ServerConfiguration config)
-        {
-            config.EnableCaseSensitiveItemIds = true;
-            config.SkipDeserializationForBasicTypes = true;
-            config.EnableSimpleArtistDetection = true;
-            config.EnableNormalizedItemByNameIds = true;
-            config.DisableLiveTvChannelUserDataName = true;
-            config.EnableNewOmdbSupport = true;
-        }
-
         public void Post(UpdateStartupConfiguration request)
         {
             _config.Configuration.UICulture = request.UICulture;

+ 1 - 5
MediaBrowser.Controller/Configuration/IServerConfigurationManager.cs

@@ -20,10 +20,6 @@ namespace MediaBrowser.Controller.Configuration
         /// <value>The configuration.</value>
         ServerConfiguration Configuration { get; }
 
-        /// <summary>
-        /// Sets the preferred metadata service.
-        /// </summary>
-        /// <param name="service">The service.</param>
-        void DisableMetadataService(string service);
+        bool SetOptimalValues();
     }
 }

+ 17 - 2
MediaBrowser.Controller/Entities/BaseItem.cs

@@ -1987,6 +1987,10 @@ namespace MediaBrowser.Controller.Entities
 
                 image.Path = file.FullName;
                 image.DateModified = imageInfo.DateModified;
+
+                // reset these values
+                image.Width = 0;
+                image.Height = 0;
             }
         }
 
@@ -2137,6 +2141,7 @@ namespace MediaBrowser.Controller.Entities
 
             var newImageList = new List<FileSystemMetadata>();
             var imageAdded = false;
+            var imageUpdated = false;
 
             foreach (var newImage in images)
             {
@@ -2157,7 +2162,17 @@ namespace MediaBrowser.Controller.Entities
                 {
                     if (existing.IsLocalFile)
                     {
-                        existing.DateModified = FileSystem.GetLastWriteTimeUtc(newImage);
+                        var newDateModified = FileSystem.GetLastWriteTimeUtc(newImage);
+
+                        // If date changed then we need to reset saved image dimensions
+                        if (existing.DateModified != newDateModified && (existing.Width > 0 || existing.Height > 0))
+                        {
+                            existing.Width = 0;
+                            existing.Height = 0;
+                            imageUpdated = true;
+                        }
+
+                        existing.DateModified = newDateModified;
                     }
                 }
             }
@@ -2190,7 +2205,7 @@ namespace MediaBrowser.Controller.Entities
                 ImageInfos = newList;
             }
 
-            return newImageList.Count > 0;
+            return imageUpdated || newImageList.Count > 0;
         }
 
         private ItemImageInfo GetImageInfo(FileSystemMetadata file, ImageType type)

+ 2 - 0
MediaBrowser.Controller/IServerApplicationPaths.cs

@@ -108,5 +108,7 @@ namespace MediaBrowser.Controller
         string InternalMetadataPath { get; }
 
         string ArtistsPath { get; }
+
+        string GetTranscodingTempPath();
     }
 }

+ 0 - 9
MediaBrowser.Model/Dlna/PlaybackException.cs

@@ -1,9 +0,0 @@
-using System;
-
-namespace MediaBrowser.Model.Dlna
-{
-    public class PlaybackException : Exception
-    {
-        public PlaybackErrorCode ErrorCode { get; set;}
-    }
-}

+ 0 - 9
MediaBrowser.Model/Dlna/StreamBuilder.cs

@@ -965,15 +965,6 @@ namespace MediaBrowser.Model.Dlna
                 return new Tuple<PlayMethod?, List<TranscodeReason>>(PlayMethod.DirectStream, new List<TranscodeReason>());
             }
 
-            if (videoStream == null)
-            {
-                _logger.Info("Profile: {0}, Cannot direct stream with no known video stream. Path: {1}",
-                    profile.Name ?? "Unknown Profile",
-                    mediaSource.Path ?? "Unknown path");
-
-                return new Tuple<PlayMethod?, List<TranscodeReason>>(null, new List<TranscodeReason> { TranscodeReason.UnknownVideoStreamInfo });
-            }
-
             // See if it can be direct played
             DirectPlayProfile directPlay = null;
             foreach (DirectPlayProfile i in profile.DirectPlayProfiles)

+ 3 - 0
MediaBrowser.Model/Globalization/ILocalizationManager.cs

@@ -1,5 +1,6 @@
 using System.Collections.Generic;
 using MediaBrowser.Model.Entities;
+using System.Globalization;
 
 namespace MediaBrowser.Model.Globalization
 {
@@ -54,5 +55,7 @@ namespace MediaBrowser.Model.Globalization
         string RemoveDiacritics(string text);
 
         string NormalizeFormKD(string text);
+
+        bool HasUnicodeCategory(string value, UnicodeCategory category);
     }
 }

+ 0 - 1
MediaBrowser.Model/MediaBrowser.Model.csproj

@@ -98,7 +98,6 @@
     <Compile Include="Dlna\ResponseProfile.cs" />
     <Compile Include="Dlna\StreamInfoSorter.cs" />
     <Compile Include="Dlna\PlaybackErrorCode.cs" />
-    <Compile Include="Dlna\PlaybackException.cs" />
     <Compile Include="Dlna\ResolutionConfiguration.cs" />
     <Compile Include="Dlna\ResolutionNormalizer.cs" />
     <Compile Include="Dlna\ResolutionOptions.cs" />

+ 12 - 1
MediaBrowser.Providers/Manager/ItemImageProvider.cs

@@ -412,7 +412,18 @@ namespace MediaBrowser.Providers.Manager
                     }
                     else
                     {
-                        currentImage.DateModified = _fileSystem.GetLastWriteTimeUtc(image.FileInfo);
+
+                        var newDateModified = _fileSystem.GetLastWriteTimeUtc(image.FileInfo);
+
+                        // If date changed then we need to reset saved image dimensions
+                        if (currentImage.DateModified != newDateModified && (currentImage.Width > 0 || currentImage.Height > 0))
+                        {
+                            currentImage.Width = 0;
+                            currentImage.Height = 0;
+                            changed = true;
+                        }
+
+                        currentImage.DateModified = newDateModified;
                     }
                 }
                 else

+ 21 - 11
MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs

@@ -92,24 +92,34 @@ namespace MediaBrowser.Providers.MediaInfo
 
         private string GetAudioImagePath(Audio item)
         {
-            var filename = item.Album ?? string.Empty;
-            filename += string.Join(",", item.Artists);
+            string filename;
 
-            if (!string.IsNullOrWhiteSpace(item.Album))
+            if (item.GetType() == typeof(Audio))
             {
-                filename += "_" + item.Album;
-            }
-            else if (!string.IsNullOrWhiteSpace(item.Name))
-            {
-                filename += "_" + item.Name;
+                filename = item.Album ?? string.Empty;
+                filename += string.Join(",", item.Artists);
+
+                if (!string.IsNullOrWhiteSpace(item.Album))
+                {
+                    filename += "_" + item.Album;
+                }
+                else if (!string.IsNullOrWhiteSpace(item.Name))
+                {
+                    filename += "_" + item.Name;
+                }
+                else
+                {
+                    filename += "_" + item.Id.ToString("N");
+                }
+
+                filename = filename.GetMD5() + ".jpg";
             }
             else
             {
-                filename += "_" + item.Id.ToString("N");
+                // If it's an audio book or audio podcast, allow unique image per item
+                filename = item.Id.ToString("N") + ".jpg";
             }
 
-            filename = filename.GetMD5() + ".jpg";
-
             var prefix = filename.Substring(0, 1);
 
             return Path.Combine(AudioImagesPath, prefix, filename);

+ 5 - 1
MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs

@@ -163,7 +163,11 @@ namespace MediaBrowser.Providers.MediaInfo
 
         private void FetchShortcutInfo(Video video)
         {
-			video.ShortcutPath = _fileSystem.ReadAllText(video.Path);
+			video.ShortcutPath = _fileSystem.ReadAllText(video.Path)
+                .Replace("\t", string.Empty)
+                .Replace("\r", string.Empty)
+                .Replace("\n", string.Empty)
+                .Trim();
         }
 
         public Task<ItemUpdateType> FetchAudioInfo<T>(T item, CancellationToken cancellationToken)

+ 4 - 2
MediaBrowser.Server.Mono/ImageEncoderHelper.cs

@@ -9,6 +9,7 @@ using MediaBrowser.Model.IO;
 using MediaBrowser.Model.Logging;
 using Emby.Drawing.Skia;
 using MediaBrowser.Model.System;
+using MediaBrowser.Model.Globalization;
 
 namespace MediaBrowser.Server.Startup.Common
 {
@@ -20,13 +21,14 @@ namespace MediaBrowser.Server.Startup.Common
             StartupOptions startupOptions, 
             Func<IHttpClient> httpClient,
             IApplicationPaths appPaths,
-            IEnvironmentInfo environment)
+            IEnvironmentInfo environment,
+            ILocalizationManager localizationManager)
         {
             if (!startupOptions.ContainsOption("-enablegdi"))
             {
                 try
                 {
-                    return new SkiaEncoder(logManager.GetLogger("Skia"), appPaths, httpClient, fileSystem);
+                    return new SkiaEncoder(logManager.GetLogger("Skia"), appPaths, httpClient, fileSystem, localizationManager);
                 }
                 catch (Exception ex)
                 {

+ 4 - 4
MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj

@@ -58,11 +58,11 @@
     <Reference Include="SharpCompress, Version=0.18.2.0, Culture=neutral, PublicKeyToken=afb0a02973931d96, processorArchitecture=MSIL">
       <HintPath>..\packages\SharpCompress.0.18.2\lib\net45\SharpCompress.dll</HintPath>
     </Reference>
-    <Reference Include="SimpleInjector, Version=4.0.8.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
-      <HintPath>..\packages\SimpleInjector.4.0.8\lib\net45\SimpleInjector.dll</HintPath>
+    <Reference Include="SimpleInjector, Version=4.0.12.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
+      <HintPath>..\packages\SimpleInjector.4.0.12\lib\net45\SimpleInjector.dll</HintPath>
     </Reference>
-    <Reference Include="SkiaSharp, Version=1.58.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
-      <HintPath>..\packages\SkiaSharp.1.58.1\lib\net45\SkiaSharp.dll</HintPath>
+    <Reference Include="SkiaSharp, Version=1.59.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
+      <HintPath>..\packages\SkiaSharp.1.59.2\lib\net45\SkiaSharp.dll</HintPath>
     </Reference>
     <Reference Include="SQLitePCLRaw.core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1488e028ca7ab535, processorArchitecture=MSIL">
       <HintPath>..\packages\SQLitePCLRaw.core.1.1.8\lib\net45\SQLitePCLRaw.core.dll</HintPath>

+ 1 - 1
MediaBrowser.Server.Mono/Program.cs

@@ -127,7 +127,7 @@ namespace MediaBrowser.Server.Mono
 
                 Task.WaitAll(task);
 
-                appHost.ImageProcessor.ImageEncoder = ImageEncoderHelper.GetImageEncoder(_logger, logManager, fileSystem, options, () => appHost.HttpClient, appPaths, environmentInfo);
+                appHost.ImageProcessor.ImageEncoder = ImageEncoderHelper.GetImageEncoder(_logger, logManager, fileSystem, options, () => appHost.HttpClient, appPaths, environmentInfo, appHost.LocalizationManager);
 
                 Console.WriteLine("Running startup tasks");
 

+ 2 - 2
MediaBrowser.Server.Mono/packages.config

@@ -3,8 +3,8 @@
   <package id="Mono.Posix" version="4.0.0.0" targetFramework="net45" />
   <package id="ServiceStack.Text" version="4.5.8" targetFramework="net46" />
   <package id="SharpCompress" version="0.18.2" targetFramework="net46" />
-  <package id="SimpleInjector" version="4.0.8" targetFramework="net46" />
-  <package id="SkiaSharp" version="1.58.1" targetFramework="net46" />
+  <package id="SimpleInjector" version="4.0.12" targetFramework="net46" />
+  <package id="SkiaSharp" version="1.59.2" targetFramework="net46" />
   <package id="SQLitePCLRaw.core" version="1.1.8" targetFramework="net46" />
   <package id="SQLitePCLRaw.provider.sqlite3.net45" version="1.1.8" targetFramework="net46" />
 </packages>

+ 4 - 2
MediaBrowser.ServerApplication/ImageEncoderHelper.cs

@@ -7,6 +7,7 @@ using MediaBrowser.Common.Net;
 using MediaBrowser.Controller.Drawing;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Globalization;
 
 namespace MediaBrowser.Server.Startup.Common
 {
@@ -17,11 +18,12 @@ namespace MediaBrowser.Server.Startup.Common
             IFileSystem fileSystem,
             StartupOptions startupOptions,
             Func<IHttpClient> httpClient,
-            IApplicationPaths appPaths)
+            IApplicationPaths appPaths,
+            ILocalizationManager localizationManager)
         {
             try
             {
-                return new SkiaEncoder(logManager.GetLogger("Skia"), appPaths, httpClient, fileSystem);
+                return new SkiaEncoder(logManager.GetLogger("Skia"), appPaths, httpClient, fileSystem, localizationManager);
             }
             catch
             {

+ 15 - 2
MediaBrowser.ServerApplication/MainStartup.cs

@@ -304,6 +304,19 @@ namespace MediaBrowser.ServerApplication
             }
         }
 
+        private static string UpdatePackageFileName
+        {
+            get
+            {
+                if (Environment.Is64BitOperatingSystem)
+                {
+                    return "embyserver-win-x64-{version}.zip";
+                }
+
+                return "embyserver-win-x86-{version}.zip";
+            }
+        }
+
         /// <summary>
         /// Runs the application.
         /// </summary>
@@ -324,7 +337,7 @@ namespace MediaBrowser.ServerApplication
                 options,
                 fileSystem,
                 new PowerManagement(),
-                "emby.windows.zip",
+                UpdatePackageFileName,
                 environmentInfo,
                 new NullImageEncoder(),
                 new SystemEvents(logManager.GetLogger("SystemEvents")),
@@ -355,7 +368,7 @@ namespace MediaBrowser.ServerApplication
                 }
 
                 // set image encoder here
-                appHost.ImageProcessor.ImageEncoder = ImageEncoderHelper.GetImageEncoder(_logger, logManager, fileSystem, options, () => appHost.HttpClient, appPaths);
+                appHost.ImageProcessor.ImageEncoder = ImageEncoderHelper.GetImageEncoder(_logger, logManager, fileSystem, options, () => appHost.HttpClient, appPaths, appHost.LocalizationManager);
 
                 task = task.ContinueWith(new Action<Task>(a => appHost.RunStartupTasks()), TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.AttachedToParent);
 

+ 6 - 6
MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj

@@ -80,11 +80,11 @@
     <Reference Include="SharpCompress, Version=0.18.2.0, Culture=neutral, PublicKeyToken=afb0a02973931d96, processorArchitecture=MSIL">
       <HintPath>..\packages\SharpCompress.0.18.2\lib\net45\SharpCompress.dll</HintPath>
     </Reference>
-    <Reference Include="SimpleInjector, Version=4.0.8.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
-      <HintPath>..\packages\SimpleInjector.4.0.8\lib\net45\SimpleInjector.dll</HintPath>
+    <Reference Include="SimpleInjector, Version=4.0.12.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
+      <HintPath>..\packages\SimpleInjector.4.0.12\lib\net45\SimpleInjector.dll</HintPath>
     </Reference>
-    <Reference Include="SkiaSharp, Version=1.58.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
-      <HintPath>..\packages\SkiaSharp.1.58.1\lib\net45\SkiaSharp.dll</HintPath>
+    <Reference Include="SkiaSharp, Version=1.59.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
+      <HintPath>..\packages\SkiaSharp.1.59.2\lib\net45\SkiaSharp.dll</HintPath>
     </Reference>
     <Reference Include="SQLitePCLRaw.core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1488e028ca7ab535, processorArchitecture=MSIL">
       <HintPath>..\packages\SQLitePCLRaw.core.1.1.8\lib\net45\SQLitePCLRaw.core.dll</HintPath>
@@ -161,11 +161,11 @@
     </EmbeddedResource>
   </ItemGroup>
   <ItemGroup>
-    <Content Include="..\packages\SkiaSharp.1.58.1\runtimes\win7-x64\native\libSkiaSharp.dll">
+    <Content Include="..\packages\SkiaSharp.1.59.2\runtimes\win7-x64\native\libSkiaSharp.dll">
       <Link>x64\libSkiaSharp.dll</Link>
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </Content>
-    <Content Include="..\packages\SkiaSharp.1.58.1\runtimes\win7-x86\native\libSkiaSharp.dll">
+    <Content Include="..\packages\SkiaSharp.1.59.2\runtimes\win7-x86\native\libSkiaSharp.dll">
       <Link>x86\libSkiaSharp.dll</Link>
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </Content>

+ 6 - 6
MediaBrowser.ServerApplication/ServerNotifyIcon.cs

@@ -144,12 +144,12 @@ namespace MediaBrowser.ServerApplication
         {
             _uiCulture = _configurationManager.Configuration.UICulture;
 
-            cmdExit.Text = _localization.GetLocalizedString("LabelExit");
-            cmdCommunity.Text = _localization.GetLocalizedString("LabelVisitCommunity");
-            cmdPremiere.Text = _localization.GetLocalizedString("Emby Premiere");
-            cmdBrowse.Text = _localization.GetLocalizedString("LabelBrowseLibrary");
-            cmdConfigure.Text = _localization.GetLocalizedString("LabelConfigureServer");
-            cmdRestart.Text = _localization.GetLocalizedString("LabelRestartServer");
+            cmdExit.Text = "Exit";
+            cmdCommunity.Text = "Visit Emby Community";
+            cmdPremiere.Text = "Emby Premiere";
+            cmdBrowse.Text = "Browse Library";
+            cmdConfigure.Text = "Configure Emby Server";
+            cmdRestart.Text = "Restart Emby Server";
         }
 
         private string _uiCulture;

+ 2 - 2
MediaBrowser.ServerApplication/packages.config

@@ -2,8 +2,8 @@
 <packages>
   <package id="ServiceStack.Text" version="4.5.8" targetFramework="net462" />
   <package id="SharpCompress" version="0.18.2" targetFramework="net462" />
-  <package id="SimpleInjector" version="4.0.8" targetFramework="net462" />
-  <package id="SkiaSharp" version="1.58.1" targetFramework="net462" />
+  <package id="SimpleInjector" version="4.0.12" targetFramework="net462" />
+  <package id="SkiaSharp" version="1.59.2" targetFramework="net462" />
   <package id="SQLitePCLRaw.core" version="1.1.8" targetFramework="net462" />
   <package id="SQLitePCLRaw.provider.sqlite3.net45" version="1.1.8" targetFramework="net462" />
 </packages>