Browse Source

isolate .net specific methods in model project

Luke Pulverenti 11 năm trước cách đây
mục cha
commit
20d35a6405
40 tập tin đã thay đổi với 336 bổ sung187 xóa
  1. 7 0
      MediaBrowser.Api/Images/ImageByNameService.cs
  2. 1 1
      MediaBrowser.Api/LiveTv/LiveTvService.cs
  3. 2 2
      MediaBrowser.Common.Implementations/Updates/InstallationManager.cs
  4. 1 1
      MediaBrowser.Controller/LiveTv/ChannelInfo.cs
  5. 2 2
      MediaBrowser.Controller/LiveTv/LiveTvChannel.cs
  6. 2 2
      MediaBrowser.Controller/LiveTv/LiveTvProgram.cs
  7. 1 1
      MediaBrowser.Controller/LiveTv/RecordingInfo.cs
  8. 12 3
      MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
  9. 12 3
      MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
  10. 1 1
      MediaBrowser.Model/ApiClient/IApiClient.cs
  11. 2 1
      MediaBrowser.Model/Configuration/NotificationOptions.cs
  12. 6 7
      MediaBrowser.Model/Dlna/ConditionProcessor.cs
  13. 5 4
      MediaBrowser.Model/Dlna/DeviceProfile.cs
  14. 2 1
      MediaBrowser.Model/Dlna/Filter.cs
  15. 74 73
      MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs
  16. 8 7
      MediaBrowser.Model/Dlna/SearchCriteria.cs
  17. 13 15
      MediaBrowser.Model/Dlna/StreamBuilder.cs
  18. 14 16
      MediaBrowser.Model/Dlna/StreamInfo.cs
  19. 3 5
      MediaBrowser.Model/Drawing/ImageSize.cs
  20. 12 11
      MediaBrowser.Model/Dto/BaseItemDto.cs
  21. 2 1
      MediaBrowser.Model/Dto/MediaSourceInfo.cs
  22. 3 2
      MediaBrowser.Model/Entities/MediaStream.cs
  23. 18 0
      MediaBrowser.Model/Extensions/DoubleHelper.cs
  24. 18 0
      MediaBrowser.Model/Extensions/IntHelper.cs
  25. 60 0
      MediaBrowser.Model/Extensions/StringHelper.cs
  26. 1 1
      MediaBrowser.Model/LiveTv/ChannelInfoDto.cs
  27. 1 1
      MediaBrowser.Model/LiveTv/ChannelType.cs
  28. 1 1
      MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs
  29. 1 1
      MediaBrowser.Model/LiveTv/RecordingInfoDto.cs
  30. 4 1
      MediaBrowser.Model/MediaBrowser.Model.csproj
  31. 29 6
      MediaBrowser.Providers/TV/MissingEpisodeProvider.cs
  32. 1 1
      MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs
  33. 2 2
      MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
  34. 2 1
      MediaBrowser.Server.Implementations/Localization/Server/server.json
  35. 5 4
      MediaBrowser.Server.Implementations/Session/SessionManager.cs
  36. 0 3
      MediaBrowser.ServerApplication/ApplicationHost.cs
  37. 3 1
      MediaBrowser.ServerApplication/FFMpeg/FFMpegDownloadInfo.cs
  38. 2 2
      Nuget/MediaBrowser.Common.Internal.nuspec
  39. 1 1
      Nuget/MediaBrowser.Common.nuspec
  40. 2 2
      Nuget/MediaBrowser.Server.Core.nuspec

+ 7 - 0
MediaBrowser.Api/Images/ImageByNameService.cs

@@ -93,6 +93,7 @@ namespace MediaBrowser.Api.Images
     {
         public string Name { get; set; }
         public string Theme { get; set; }
+        public string Context { get; set; }
         public long FileLength { get; set; }
         public string Format { get; set; }
     }
@@ -142,7 +143,13 @@ namespace MediaBrowser.Api.Images
                     {
                         Name = Path.GetFileNameWithoutExtension(i.FullName),
                         FileLength = i.Length,
+
+                        // For themeable images, use the Theme property
+                        // For general images, the same object structure is fine,
+                        // but it's not owned by a theme, so call it Context
                         Theme = supportsThemes ? GetThemeName(i.FullName, path) : null,
+                        Context = supportsThemes ? null : GetThemeName(i.FullName, path),
+
                         Format = i.Extension.ToLower().TrimStart('.')
                     })
                     .OrderBy(i => i.Name)

+ 1 - 1
MediaBrowser.Api/LiveTv/LiveTvService.cs

@@ -21,7 +21,7 @@ namespace MediaBrowser.Api.LiveTv
     public class GetChannels : IReturn<QueryResult<ChannelInfoDto>>
     {
         [ApiMember(Name = "Type", Description = "Optional filter by channel type.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
-        public LiveTvChannelType? Type { get; set; }
+        public ChannelType? Type { get; set; }
 
         [ApiMember(Name = "UserId", Description = "Optional filter by user and attach user data.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
         public string UserId { get; set; }

+ 2 - 2
MediaBrowser.Common.Implementations/Updates/InstallationManager.cs

@@ -169,8 +169,8 @@ namespace MediaBrowser.Common.Implementations.Updates
             {
                 // Let dev users get results more often for testing purposes
                 var cacheLength = _config.CommonConfiguration.SystemUpdateLevel == PackageVersionClass.Dev
-                                      ? TimeSpan.FromMinutes(5)
-                                      : TimeSpan.FromHours(12);
+                                      ? TimeSpan.FromMinutes(3)
+                                      : TimeSpan.FromHours(4);
 
                 if ((DateTime.UtcNow - _lastPackageListResult.Item2) < cacheLength)
                 {

+ 1 - 1
MediaBrowser.Controller/LiveTv/ChannelInfo.cs

@@ -29,7 +29,7 @@ namespace MediaBrowser.Controller.LiveTv
         /// Gets or sets the type of the channel.
         /// </summary>
         /// <value>The type of the channel.</value>
-        public LiveTvChannelType ChannelType { get; set; }
+        public ChannelType ChannelType { get; set; }
 
         /// <summary>
         /// Supply the image path if it can be accessed directly from the file system

+ 2 - 2
MediaBrowser.Controller/LiveTv/LiveTvChannel.cs

@@ -63,7 +63,7 @@ namespace MediaBrowser.Controller.LiveTv
         /// Gets or sets the type of the channel.
         /// </summary>
         /// <value>The type of the channel.</value>
-        public LiveTvChannelType ChannelType { get; set; }
+        public ChannelType ChannelType { get; set; }
 
         public string ServiceName { get; set; }
 
@@ -101,7 +101,7 @@ namespace MediaBrowser.Controller.LiveTv
         {
             get
             {
-                return ChannelType == LiveTvChannelType.Radio ? Model.Entities.MediaType.Audio : Model.Entities.MediaType.Video;
+                return ChannelType == ChannelType.Radio ? Model.Entities.MediaType.Audio : Model.Entities.MediaType.Video;
             }
         }
 

+ 2 - 2
MediaBrowser.Controller/LiveTv/LiveTvProgram.cs

@@ -35,7 +35,7 @@ namespace MediaBrowser.Controller.LiveTv
         /// Gets or sets the type of the channel.
         /// </summary>
         /// <value>The type of the channel.</value>
-        public LiveTvChannelType ChannelType { get; set; }
+        public ChannelType ChannelType { get; set; }
 
         /// <summary>
         /// The start date of the program, in UTC.
@@ -161,7 +161,7 @@ namespace MediaBrowser.Controller.LiveTv
         {
             get
             {
-                return ChannelType == LiveTvChannelType.TV ? Model.Entities.MediaType.Video : Model.Entities.MediaType.Audio;
+                return ChannelType == ChannelType.TV ? Model.Entities.MediaType.Video : Model.Entities.MediaType.Audio;
             }
         }
 

+ 1 - 1
MediaBrowser.Controller/LiveTv/RecordingInfo.cs

@@ -26,7 +26,7 @@ namespace MediaBrowser.Controller.LiveTv
         /// Gets or sets the type of the channel.
         /// </summary>
         /// <value>The type of the channel.</value>
-        public LiveTvChannelType ChannelType { get; set; }
+        public ChannelType ChannelType { get; set; }
      
         /// <summary>
         /// Name of the recording.

+ 12 - 3
MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj

@@ -428,6 +428,15 @@
     <Compile Include="..\MediaBrowser.Model\Events\GenericEventArgs.cs">
       <Link>Events\GenericEventArgs.cs</Link>
     </Compile>
+    <Compile Include="..\MediaBrowser.Model\Extensions\DoubleHelper.cs">
+      <Link>Extensions\DoubleHelper.cs</Link>
+    </Compile>
+    <Compile Include="..\MediaBrowser.Model\Extensions\IntHelper.cs">
+      <Link>Extensions\IntHelper.cs</Link>
+    </Compile>
+    <Compile Include="..\MediaBrowser.Model\Extensions\StringHelper.cs">
+      <Link>Extensions\StringHelper.cs</Link>
+    </Compile>
     <Compile Include="..\MediaBrowser.Model\FileOrganization\EpisodeFileOrganizationRequest.cs">
       <Link>FileOrganization\EpisodeFileOrganizationRequest.cs</Link>
     </Compile>
@@ -482,6 +491,9 @@
     <Compile Include="..\MediaBrowser.Model\LiveTv\ChannelInfoDto.cs">
       <Link>LiveTv\ChannelInfoDto.cs</Link>
     </Compile>
+    <Compile Include="..\MediaBrowser.Model\LiveTv\ChannelType.cs">
+      <Link>LiveTv\ChannelType.cs</Link>
+    </Compile>
     <Compile Include="..\MediaBrowser.Model\LiveTv\DayPattern.cs">
       <Link>LiveTv\DayPattern.cs</Link>
     </Compile>
@@ -491,9 +503,6 @@
     <Compile Include="..\MediaBrowser.Model\LiveTv\LiveTvChannelQuery.cs">
       <Link>LiveTv\LiveTvChannelQuery.cs</Link>
     </Compile>
-    <Compile Include="..\MediaBrowser.Model\LiveTv\LiveTvChannelType.cs">
-      <Link>LiveTv\LiveTvChannelType.cs</Link>
-    </Compile>
     <Compile Include="..\MediaBrowser.Model\LiveTv\LiveTvInfo.cs">
       <Link>LiveTv\LiveTvInfo.cs</Link>
     </Compile>

+ 12 - 3
MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj

@@ -415,6 +415,15 @@
     <Compile Include="..\MediaBrowser.Model\Events\GenericEventArgs.cs">
       <Link>Events\GenericEventArgs.cs</Link>
     </Compile>
+    <Compile Include="..\MediaBrowser.Model\Extensions\DoubleHelper.cs">
+      <Link>Extensions\DoubleHelper.cs</Link>
+    </Compile>
+    <Compile Include="..\MediaBrowser.Model\Extensions\IntHelper.cs">
+      <Link>Extensions\IntHelper.cs</Link>
+    </Compile>
+    <Compile Include="..\MediaBrowser.Model\Extensions\StringHelper.cs">
+      <Link>Extensions\StringHelper.cs</Link>
+    </Compile>
     <Compile Include="..\MediaBrowser.Model\FileOrganization\EpisodeFileOrganizationRequest.cs">
       <Link>FileOrganization\EpisodeFileOrganizationRequest.cs</Link>
     </Compile>
@@ -463,6 +472,9 @@
     <Compile Include="..\MediaBrowser.Model\LiveTv\ChannelInfoDto.cs">
       <Link>LiveTv\ChannelInfoDto.cs</Link>
     </Compile>
+    <Compile Include="..\MediaBrowser.Model\LiveTv\ChannelType.cs">
+      <Link>LiveTv\ChannelType.cs</Link>
+    </Compile>
     <Compile Include="..\MediaBrowser.Model\LiveTv\DayPattern.cs">
       <Link>LiveTv\DayPattern.cs</Link>
     </Compile>
@@ -472,9 +484,6 @@
     <Compile Include="..\MediaBrowser.Model\LiveTv\LiveTvChannelQuery.cs">
       <Link>LiveTv\LiveTvChannelQuery.cs</Link>
     </Compile>
-    <Compile Include="..\MediaBrowser.Model\LiveTv\LiveTvChannelType.cs">
-      <Link>LiveTv\LiveTvChannelType.cs</Link>
-    </Compile>
     <Compile Include="..\MediaBrowser.Model\LiveTv\LiveTvInfo.cs">
       <Link>LiveTv\LiveTvInfo.cs</Link>
     </Compile>

+ 1 - 1
MediaBrowser.Model/ApiClient/IApiClient.cs

@@ -218,7 +218,7 @@ namespace MediaBrowser.Model.ApiClient
         /// </summary>
         /// <param name="itemId">The item identifier.</param>
         /// <returns>Task{BaseItemDto[]}.</returns>
-        Task<BaseItemDto[]> GetAdditionalParts(string itemId);
+        Task<BaseItemDto[]> GetAdditionalParts(string itemId, string userId);
         
         /// <summary>
         /// Gets the users async.

+ 2 - 1
MediaBrowser.Model/Configuration/NotificationOptions.cs

@@ -1,5 +1,6 @@
 using System;
 using System.Linq;
+using MediaBrowser.Model.Extensions;
 
 namespace MediaBrowser.Model.Configuration
 {
@@ -72,7 +73,7 @@ namespace MediaBrowser.Model.Configuration
         {
             foreach (NotificationOption i in Options)
             {
-                if (string.Equals(type, i.Type, StringComparison.OrdinalIgnoreCase)) return i;
+                if (StringHelper.EqualsIgnoreCase(type, i.Type)) return i;
             }
             return null;
         }

+ 6 - 7
MediaBrowser.Model/Dlna/ConditionProcessor.cs

@@ -1,6 +1,6 @@
-using MediaBrowser.Model.MediaInfo;
+using MediaBrowser.Model.Extensions;
+using MediaBrowser.Model.MediaInfo;
 using System;
-using System.Globalization;
 
 namespace MediaBrowser.Model.Dlna
 {
@@ -98,7 +98,6 @@ namespace MediaBrowser.Model.Dlna
             }
         }
 
-        private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
         private bool IsConditionSatisfied(ProfileCondition condition, int? currentValue)
         {
             if (!currentValue.HasValue)
@@ -108,7 +107,7 @@ namespace MediaBrowser.Model.Dlna
             }
 
             int expected;
-            if (int.TryParse(condition.Value, NumberStyles.Any, UsCulture, out expected))
+            if (IntHelper.TryParseCultureInvariant(condition.Value, out expected))
             {
                 switch (condition.Condition)
                 {
@@ -141,9 +140,9 @@ namespace MediaBrowser.Model.Dlna
             switch (condition.Condition)
             {
                 case ProfileConditionType.Equals:
-                    return string.Equals(currentValue, expected, StringComparison.OrdinalIgnoreCase);
+                    return StringHelper.EqualsIgnoreCase(currentValue, expected);
                 case ProfileConditionType.NotEquals:
-                    return !string.Equals(currentValue, expected, StringComparison.OrdinalIgnoreCase);
+                    return !StringHelper.EqualsIgnoreCase(currentValue, expected);
                 default:
                     throw new InvalidOperationException("Unexpected ProfileConditionType");
             }
@@ -158,7 +157,7 @@ namespace MediaBrowser.Model.Dlna
             }
 
             double expected;
-            if (double.TryParse(condition.Value, NumberStyles.Any, UsCulture, out expected))
+            if (DoubleHelper.TryParseCultureInvariant(condition.Value, out expected))
             {
                 switch (condition.Condition)
                 {

+ 5 - 4
MediaBrowser.Model/Dlna/DeviceProfile.cs

@@ -1,4 +1,5 @@
-using MediaBrowser.Model.MediaInfo;
+using MediaBrowser.Model.Extensions;
+using MediaBrowser.Model.MediaInfo;
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -125,7 +126,7 @@ namespace MediaBrowser.Model.Dlna
                     continue;
                 }
 
-                if (!string.Equals(container, i.Container, StringComparison.OrdinalIgnoreCase))
+                if (!StringHelper.EqualsIgnoreCase(container, i.Container))
                 {
                     continue;
                 }
@@ -151,7 +152,7 @@ namespace MediaBrowser.Model.Dlna
                     continue;
                 }
 
-                if (!string.Equals(container, i.Container, StringComparison.OrdinalIgnoreCase))
+                if (!StringHelper.EqualsIgnoreCase(container, i.Container))
                 {
                     continue;
                 }
@@ -161,7 +162,7 @@ namespace MediaBrowser.Model.Dlna
                     continue;
                 }
 
-                if (!string.Equals(videoCodec, i.VideoCodec, StringComparison.OrdinalIgnoreCase))
+                if (!StringHelper.EqualsIgnoreCase(videoCodec, i.VideoCodec))
                 {
                     continue;
                 }

+ 2 - 1
MediaBrowser.Model/Dlna/Filter.cs

@@ -1,6 +1,7 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using MediaBrowser.Model.Extensions;
 
 namespace MediaBrowser.Model.Dlna
 {
@@ -17,7 +18,7 @@ namespace MediaBrowser.Model.Dlna
 
         public Filter(string filter)
         {
-            _all = string.Equals(filter, "*", StringComparison.OrdinalIgnoreCase);
+            _all = StringHelper.EqualsIgnoreCase(filter, "*");
 
             List<string> list = new List<string>();
             foreach (string s in (filter ?? string.Empty).Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries))

+ 74 - 73
MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs

@@ -1,4 +1,5 @@
-using MediaBrowser.Model.MediaInfo;
+using MediaBrowser.Model.Extensions;
+using MediaBrowser.Model.MediaInfo;
 using System;
 using System.Collections.Generic;
 
@@ -8,53 +9,53 @@ namespace MediaBrowser.Model.Dlna
     {
         public IEnumerable<MediaFormatProfile> ResolveVideoFormat(string container, string videoCodec, string audioCodec, int? width, int? height, TransportStreamTimestamp timestampType)
         {
-            if (string.Equals(container, "asf", StringComparison.OrdinalIgnoreCase))
+            if (StringHelper.EqualsIgnoreCase(container, "asf"))
             {
                 MediaFormatProfile? val = ResolveVideoASFFormat(videoCodec, audioCodec, width, height);
                 return val.HasValue ? new List<MediaFormatProfile> { val.Value } : new List<MediaFormatProfile>();
             }
 
-            if (string.Equals(container, "mp4", StringComparison.OrdinalIgnoreCase))
+            if (StringHelper.EqualsIgnoreCase(container, "mp4"))
             {
                 MediaFormatProfile? val = ResolveVideoMP4Format(videoCodec, audioCodec, width, height);
                 return val.HasValue ? new List<MediaFormatProfile> { val.Value } : new List<MediaFormatProfile>();
             }
 
-            if (string.Equals(container, "avi", StringComparison.OrdinalIgnoreCase))
+            if (StringHelper.EqualsIgnoreCase(container, "avi"))
                 return new[] { MediaFormatProfile.AVI };
 
-            if (string.Equals(container, "mkv", StringComparison.OrdinalIgnoreCase))
+            if (StringHelper.EqualsIgnoreCase(container, "mkv"))
                 return new[] { MediaFormatProfile.MATROSKA };
 
-            if (string.Equals(container, "mpeg2ps", StringComparison.OrdinalIgnoreCase) ||
-                string.Equals(container, "ts", StringComparison.OrdinalIgnoreCase))
+            if (StringHelper.EqualsIgnoreCase(container, "mpeg2ps") ||
+                StringHelper.EqualsIgnoreCase(container, "ts"))
 
                 return new[] { MediaFormatProfile.MPEG_PS_NTSC, MediaFormatProfile.MPEG_PS_PAL };
 
-            if (string.Equals(container, "mpeg1video", StringComparison.OrdinalIgnoreCase))
+            if (StringHelper.EqualsIgnoreCase(container, "mpeg1video"))
                 return new[] { MediaFormatProfile.MPEG1 };
 
-            if (string.Equals(container, "mpeg2ts", StringComparison.OrdinalIgnoreCase) ||
-                string.Equals(container, "mpegts", StringComparison.OrdinalIgnoreCase) ||
-                string.Equals(container, "m2ts", StringComparison.OrdinalIgnoreCase))
+            if (StringHelper.EqualsIgnoreCase(container, "mpeg2ts") ||
+                StringHelper.EqualsIgnoreCase(container, "mpegts") ||
+                StringHelper.EqualsIgnoreCase(container, "m2ts"))
             {
 
                 return ResolveVideoMPEG2TSFormat(videoCodec, audioCodec, width, height, timestampType);
             }
 
-            if (string.Equals(container, "flv", StringComparison.OrdinalIgnoreCase))
+            if (StringHelper.EqualsIgnoreCase(container, "flv"))
                 return new[] { MediaFormatProfile.FLV };
 
-            if (string.Equals(container, "wtv", StringComparison.OrdinalIgnoreCase))
+            if (StringHelper.EqualsIgnoreCase(container, "wtv"))
                 return new[] { MediaFormatProfile.WTV };
 
-            if (string.Equals(container, "3gp", StringComparison.OrdinalIgnoreCase))
+            if (StringHelper.EqualsIgnoreCase(container, "3gp"))
             {
                 MediaFormatProfile? val = ResolveVideo3GPFormat(videoCodec, audioCodec);
                 return val.HasValue ? new List<MediaFormatProfile> { val.Value } : new List<MediaFormatProfile>();
             }
 
-            if (string.Equals(container, "ogv", StringComparison.OrdinalIgnoreCase) || string.Equals(container, "ogg", StringComparison.OrdinalIgnoreCase))
+            if (StringHelper.EqualsIgnoreCase(container, "ogv") || StringHelper.EqualsIgnoreCase(container, "ogg"))
                 return new[] { MediaFormatProfile.OGV };
 
             return new List<MediaFormatProfile>();
@@ -80,7 +81,7 @@ namespace MediaBrowser.Model.Dlna
                 resolution = "H";
             }
 
-            if (string.Equals(videoCodec, "mpeg2video", StringComparison.OrdinalIgnoreCase))
+            if (StringHelper.EqualsIgnoreCase(videoCodec, "mpeg2video"))
             {
                 List<MediaFormatProfile> list = new List<MediaFormatProfile>();
 
@@ -88,18 +89,18 @@ namespace MediaBrowser.Model.Dlna
                 list.Add(ValueOf("MPEG_TS_SD_EU" + suffix));
                 list.Add(ValueOf("MPEG_TS_SD_KO" + suffix));
 
-                if ((timestampType == TransportStreamTimestamp.Valid) && string.Equals(audioCodec, "aac", StringComparison.OrdinalIgnoreCase))
+                if ((timestampType == TransportStreamTimestamp.Valid) && StringHelper.EqualsIgnoreCase(audioCodec, "aac"))
                 {
                     list.Add(MediaFormatProfile.MPEG_TS_JP_T);
                 }
                 return list;
             }
-            if (string.Equals(videoCodec, "h264", StringComparison.OrdinalIgnoreCase))
+            if (StringHelper.EqualsIgnoreCase(videoCodec, "h264"))
             {
-                if (string.Equals(audioCodec, "lpcm", StringComparison.OrdinalIgnoreCase))
+                if (StringHelper.EqualsIgnoreCase(audioCodec, "lpcm"))
                     return new[] { MediaFormatProfile.AVC_TS_HD_50_LPCM_T };
 
-                if (string.Equals(audioCodec, "dts", StringComparison.OrdinalIgnoreCase))
+                if (StringHelper.EqualsIgnoreCase(audioCodec, "dts"))
                 {
                     if (timestampType == TransportStreamTimestamp.None)
                     {
@@ -108,7 +109,7 @@ namespace MediaBrowser.Model.Dlna
                     return new[] { MediaFormatProfile.AVC_TS_HD_DTS_T };
                 }
 
-                if (string.Equals(audioCodec, "mp3", StringComparison.OrdinalIgnoreCase))
+                if (StringHelper.EqualsIgnoreCase(audioCodec, "mp3"))
                 {
                     if (timestampType == TransportStreamTimestamp.None)
                     {
@@ -118,19 +119,19 @@ namespace MediaBrowser.Model.Dlna
                     return new[] { ValueOf(string.Format("AVC_TS_HP_{0}D_MPEG1_L2_T", resolution)) };
                 }
 
-                if (string.Equals(audioCodec, "aac", StringComparison.OrdinalIgnoreCase))
+                if (StringHelper.EqualsIgnoreCase(audioCodec, "aac"))
                     return new[] { ValueOf(string.Format("AVC_TS_MP_{0}D_AAC_MULT5{1}", resolution, suffix)) };
 
-                if (string.Equals(audioCodec, "mp3", StringComparison.OrdinalIgnoreCase))
+                if (StringHelper.EqualsIgnoreCase(audioCodec, "mp3"))
                     return new[] { ValueOf(string.Format("AVC_TS_MP_{0}D_MPEG1_L3{1}", resolution, suffix)) };
 
                 if (string.IsNullOrEmpty(audioCodec) ||
-                    string.Equals(audioCodec, "ac3", StringComparison.OrdinalIgnoreCase))
+                    StringHelper.EqualsIgnoreCase(audioCodec, "ac3"))
                     return new[] { ValueOf(string.Format("AVC_TS_MP_{0}D_AC3{1}", resolution, suffix)) };
             }
-            else if (string.Equals(videoCodec, "vc1", StringComparison.OrdinalIgnoreCase))
+            else if (StringHelper.EqualsIgnoreCase(videoCodec, "vc1"))
             {
-                if (string.IsNullOrEmpty(audioCodec) || string.Equals(audioCodec, "ac3", StringComparison.OrdinalIgnoreCase))
+                if (string.IsNullOrEmpty(audioCodec) || StringHelper.EqualsIgnoreCase(audioCodec, "ac3"))
                 {
                     if ((width.HasValue && width.Value > 720) || (height.HasValue && height.Value > 576))
                     {
@@ -138,23 +139,23 @@ namespace MediaBrowser.Model.Dlna
                     }
                     return new[] { MediaFormatProfile.VC1_TS_AP_L1_AC3_ISO };
                 }
-                if (string.Equals(audioCodec, "dts", StringComparison.OrdinalIgnoreCase))
+                if (StringHelper.EqualsIgnoreCase(audioCodec, "dts"))
                 {
-                    suffix = string.Equals(suffix, "_ISO") ? suffix : "_T";
+                    suffix = StringHelper.EqualsIgnoreCase(suffix, "_ISO") ? suffix : "_T";
 
                     return new[] { ValueOf(string.Format("VC1_TS_HD_DTS{0}", suffix)) };
                 }
 
             }
-            else if (string.Equals(videoCodec, "mpeg4", StringComparison.OrdinalIgnoreCase) || string.Equals(videoCodec, "msmpeg4", StringComparison.OrdinalIgnoreCase))
+            else if (StringHelper.EqualsIgnoreCase(videoCodec, "mpeg4") || StringHelper.EqualsIgnoreCase(videoCodec, "msmpeg4"))
             {
-                if (string.Equals(audioCodec, "aac", StringComparison.OrdinalIgnoreCase))
+                if (StringHelper.EqualsIgnoreCase(audioCodec, "aac"))
                     return new[] { ValueOf(string.Format("MPEG4_P2_TS_ASP_AAC{0}", suffix)) };
-                if (string.Equals(audioCodec, "mp3", StringComparison.OrdinalIgnoreCase))
+                if (StringHelper.EqualsIgnoreCase(audioCodec, "mp3"))
                     return new[] { ValueOf(string.Format("MPEG4_P2_TS_ASP_MPEG1_L3{0}", suffix)) };
-                if (string.Equals(audioCodec, "mp2", StringComparison.OrdinalIgnoreCase))
+                if (StringHelper.EqualsIgnoreCase(audioCodec, "mp2"))
                     return new[] { ValueOf(string.Format("MPEG4_P2_TS_ASP_MPEG2_L2{0}", suffix)) };
-                if (string.Equals(audioCodec, "ac3", StringComparison.OrdinalIgnoreCase))
+                if (StringHelper.EqualsIgnoreCase(audioCodec, "ac3"))
                     return new[] { ValueOf(string.Format("MPEG4_P2_TS_ASP_AC3{0}", suffix)) };
             }
 
@@ -168,16 +169,16 @@ namespace MediaBrowser.Model.Dlna
 
         private MediaFormatProfile? ResolveVideoMP4Format(string videoCodec, string audioCodec, int? width, int? height)
         {
-            if (string.Equals(videoCodec, "h264", StringComparison.OrdinalIgnoreCase))
+            if (StringHelper.EqualsIgnoreCase(videoCodec, "h264"))
             {
-                if (string.Equals(audioCodec, "lpcm", StringComparison.OrdinalIgnoreCase))
+                if (StringHelper.EqualsIgnoreCase(audioCodec, "lpcm"))
                     return MediaFormatProfile.AVC_MP4_LPCM;
                 if (string.IsNullOrEmpty(audioCodec) ||
-                    string.Equals(audioCodec, "ac3", StringComparison.OrdinalIgnoreCase))
+                    StringHelper.EqualsIgnoreCase(audioCodec, "ac3"))
                 {
                     return MediaFormatProfile.AVC_MP4_MP_SD_AC3;
                 }
-                if (string.Equals(audioCodec, "mp3", StringComparison.OrdinalIgnoreCase))
+                if (StringHelper.EqualsIgnoreCase(audioCodec, "mp3"))
                 {
                     return MediaFormatProfile.AVC_MP4_MP_SD_MPEG1_L3;
                 }
@@ -185,41 +186,41 @@ namespace MediaBrowser.Model.Dlna
                 {
                     if ((width.Value <= 720) && (height.Value <= 576))
                     {
-                        if (string.Equals(audioCodec, "aac", StringComparison.OrdinalIgnoreCase))
+                        if (StringHelper.EqualsIgnoreCase(audioCodec, "aac"))
                             return MediaFormatProfile.AVC_MP4_MP_SD_AAC_MULT5;
                     }
                     else if ((width.Value <= 1280) && (height.Value <= 720))
                     {
-                        if (string.Equals(audioCodec, "aac", StringComparison.OrdinalIgnoreCase))
+                        if (StringHelper.EqualsIgnoreCase(audioCodec, "aac"))
                             return MediaFormatProfile.AVC_MP4_MP_HD_720p_AAC;
                     }
                     else if ((width.Value <= 1920) && (height.Value <= 1080))
                     {
-                        if (string.Equals(audioCodec, "aac", StringComparison.OrdinalIgnoreCase))
+                        if (StringHelper.EqualsIgnoreCase(audioCodec, "aac"))
                         {
                             return MediaFormatProfile.AVC_MP4_MP_HD_1080i_AAC;
                         }
                     }
                 }
             }
-            else if (string.Equals(videoCodec, "mpeg4", StringComparison.OrdinalIgnoreCase) ||
-                string.Equals(videoCodec, "msmpeg4", StringComparison.OrdinalIgnoreCase))
+            else if (StringHelper.EqualsIgnoreCase(videoCodec, "mpeg4") ||
+                StringHelper.EqualsIgnoreCase(videoCodec, "msmpeg4"))
             {
                 if (width.HasValue && height.HasValue && width.Value <= 720 && height.Value <= 576)
                 {
-                    if (string.IsNullOrEmpty(audioCodec) || string.Equals(audioCodec, "aac", StringComparison.OrdinalIgnoreCase))
+                    if (string.IsNullOrEmpty(audioCodec) || StringHelper.EqualsIgnoreCase(audioCodec, "aac"))
                         return MediaFormatProfile.MPEG4_P2_MP4_ASP_AAC;
-                    if (string.Equals(audioCodec, "ac3", StringComparison.OrdinalIgnoreCase) || string.Equals(audioCodec, "mp3", StringComparison.OrdinalIgnoreCase))
+                    if (StringHelper.EqualsIgnoreCase(audioCodec, "ac3") || StringHelper.EqualsIgnoreCase(audioCodec, "mp3"))
                     {
                         return MediaFormatProfile.MPEG4_P2_MP4_NDSD;
                     }
                 }
-                else if (string.IsNullOrEmpty(audioCodec) || string.Equals(audioCodec, "aac", StringComparison.OrdinalIgnoreCase))
+                else if (string.IsNullOrEmpty(audioCodec) || StringHelper.EqualsIgnoreCase(audioCodec, "aac"))
                 {
                     return MediaFormatProfile.MPEG4_P2_MP4_SP_L6_AAC;
                 }
             }
-            else if (string.Equals(videoCodec, "h263", StringComparison.OrdinalIgnoreCase) && string.Equals(audioCodec, "aac", StringComparison.OrdinalIgnoreCase))
+            else if (StringHelper.EqualsIgnoreCase(videoCodec, "h263") && StringHelper.EqualsIgnoreCase(audioCodec, "aac"))
             {
                 return MediaFormatProfile.MPEG4_H263_MP4_P0_L10_AAC;
             }
@@ -229,20 +230,20 @@ namespace MediaBrowser.Model.Dlna
 
         private MediaFormatProfile? ResolveVideo3GPFormat(string videoCodec, string audioCodec)
         {
-            if (string.Equals(videoCodec, "h264", StringComparison.OrdinalIgnoreCase))
+            if (StringHelper.EqualsIgnoreCase(videoCodec, "h264"))
             {
-                if (string.IsNullOrEmpty(audioCodec) || string.Equals(audioCodec, "aac", StringComparison.OrdinalIgnoreCase))
+                if (string.IsNullOrEmpty(audioCodec) || StringHelper.EqualsIgnoreCase(audioCodec, "aac"))
                     return MediaFormatProfile.AVC_3GPP_BL_QCIF15_AAC;
             }
-            else if (string.Equals(videoCodec, "mpeg4", StringComparison.OrdinalIgnoreCase) ||
-                string.Equals(videoCodec, "msmpeg4", StringComparison.OrdinalIgnoreCase))
+            else if (StringHelper.EqualsIgnoreCase(videoCodec, "mpeg4") ||
+                StringHelper.EqualsIgnoreCase(videoCodec, "msmpeg4"))
             {
-                if (string.IsNullOrEmpty(audioCodec) || string.Equals(audioCodec, "wma", StringComparison.OrdinalIgnoreCase))
+                if (string.IsNullOrEmpty(audioCodec) || StringHelper.EqualsIgnoreCase(audioCodec, "wma"))
                     return MediaFormatProfile.MPEG4_P2_3GPP_SP_L0B_AAC;
-                if (string.Equals(audioCodec, "amrnb", StringComparison.OrdinalIgnoreCase))
+                if (StringHelper.EqualsIgnoreCase(audioCodec, "amrnb"))
                     return MediaFormatProfile.MPEG4_P2_3GPP_SP_L0B_AMR;
             }
-            else if (string.Equals(videoCodec, "h263", StringComparison.OrdinalIgnoreCase) && string.Equals(audioCodec, "amrnb", StringComparison.OrdinalIgnoreCase))
+            else if (StringHelper.EqualsIgnoreCase(videoCodec, "h263") && StringHelper.EqualsIgnoreCase(audioCodec, "amrnb"))
             {
                 return MediaFormatProfile.MPEG4_H263_3GPP_P0_L10_AMR;
             }
@@ -252,15 +253,15 @@ namespace MediaBrowser.Model.Dlna
 
         private MediaFormatProfile? ResolveVideoASFFormat(string videoCodec, string audioCodec, int? width, int? height)
         {
-            if (string.Equals(videoCodec, "wmv", StringComparison.OrdinalIgnoreCase) &&
-                (string.IsNullOrEmpty(audioCodec) || string.Equals(audioCodec, "wma", StringComparison.OrdinalIgnoreCase) || string.Equals(videoCodec, "wmapro", StringComparison.OrdinalIgnoreCase)))
+            if (StringHelper.EqualsIgnoreCase(videoCodec, "wmv") &&
+                (string.IsNullOrEmpty(audioCodec) || StringHelper.EqualsIgnoreCase(audioCodec, "wma") || StringHelper.EqualsIgnoreCase(videoCodec, "wmapro")))
             {
 
                 if (width.HasValue && height.HasValue)
                 {
                     if ((width.Value <= 720) && (height.Value <= 576))
                     {
-                        if (string.IsNullOrEmpty(audioCodec) || string.Equals(audioCodec, "wma", StringComparison.OrdinalIgnoreCase))
+                        if (string.IsNullOrEmpty(audioCodec) || StringHelper.EqualsIgnoreCase(audioCodec, "wma"))
                         {
                             return MediaFormatProfile.WMVMED_FULL;
                         }
@@ -268,14 +269,14 @@ namespace MediaBrowser.Model.Dlna
                     }
                 }
 
-                if (string.IsNullOrEmpty(audioCodec) || string.Equals(audioCodec, "wma", StringComparison.OrdinalIgnoreCase))
+                if (string.IsNullOrEmpty(audioCodec) || StringHelper.EqualsIgnoreCase(audioCodec, "wma"))
                 {
                     return MediaFormatProfile.WMVHIGH_FULL;
                 }
                 return MediaFormatProfile.WMVHIGH_PRO;
             }
 
-            if (string.Equals(videoCodec, "vc1", StringComparison.OrdinalIgnoreCase))
+            if (StringHelper.EqualsIgnoreCase(videoCodec, "vc1"))
             {
                 if (width.HasValue && height.HasValue)
                 {
@@ -287,7 +288,7 @@ namespace MediaBrowser.Model.Dlna
                         return MediaFormatProfile.VC1_ASF_AP_L3_WMA;
                 }
             }
-            else if (string.Equals(videoCodec, "mpeg2video", StringComparison.OrdinalIgnoreCase))
+            else if (StringHelper.EqualsIgnoreCase(videoCodec, "mpeg2video"))
             {
                 return MediaFormatProfile.DVR_MS;
             }
@@ -297,27 +298,27 @@ namespace MediaBrowser.Model.Dlna
 
         public MediaFormatProfile? ResolveAudioFormat(string container, int? bitrate, int? frequency, int? channels)
         {
-            if (string.Equals(container, "asf", StringComparison.OrdinalIgnoreCase))
+            if (StringHelper.EqualsIgnoreCase(container, "asf"))
                 return ResolveAudioASFFormat(bitrate);
 
-            if (string.Equals(container, "mp3", StringComparison.OrdinalIgnoreCase))
+            if (StringHelper.EqualsIgnoreCase(container, "mp3"))
                 return MediaFormatProfile.MP3;
 
-            if (string.Equals(container, "lpcm", StringComparison.OrdinalIgnoreCase))
+            if (StringHelper.EqualsIgnoreCase(container, "lpcm"))
                 return ResolveAudioLPCMFormat(frequency, channels);
 
-            if (string.Equals(container, "mp4", StringComparison.OrdinalIgnoreCase) ||
-                string.Equals(container, "aac", StringComparison.OrdinalIgnoreCase))
+            if (StringHelper.EqualsIgnoreCase(container, "mp4") ||
+                StringHelper.EqualsIgnoreCase(container, "aac"))
                 return ResolveAudioMP4Format(bitrate);
 
-            if (string.Equals(container, "adts", StringComparison.OrdinalIgnoreCase))
+            if (StringHelper.EqualsIgnoreCase(container, "adts"))
                 return ResolveAudioADTSFormat(bitrate);
 
-            if (string.Equals(container, "flac", StringComparison.OrdinalIgnoreCase))
+            if (StringHelper.EqualsIgnoreCase(container, "flac"))
                 return MediaFormatProfile.FLAC;
 
-            if (string.Equals(container, "oga", StringComparison.OrdinalIgnoreCase) ||
-                string.Equals(container, "ogg", StringComparison.OrdinalIgnoreCase))
+            if (StringHelper.EqualsIgnoreCase(container, "oga") ||
+                StringHelper.EqualsIgnoreCase(container, "ogg"))
                 return MediaFormatProfile.OGG;
 
             return null;
@@ -379,17 +380,17 @@ namespace MediaBrowser.Model.Dlna
 
         public MediaFormatProfile? ResolveImageFormat(string container, int? width, int? height)
         {
-            if (string.Equals(container, "jpeg", StringComparison.OrdinalIgnoreCase) ||
-                string.Equals(container, "jpg", StringComparison.OrdinalIgnoreCase))
+            if (StringHelper.EqualsIgnoreCase(container, "jpeg") ||
+                StringHelper.EqualsIgnoreCase(container, "jpg"))
                 return ResolveImageJPGFormat(width, height);
 
-            if (string.Equals(container, "png", StringComparison.OrdinalIgnoreCase))
+            if (StringHelper.EqualsIgnoreCase(container, "png"))
                 return MediaFormatProfile.PNG_LRG;
 
-            if (string.Equals(container, "gif", StringComparison.OrdinalIgnoreCase))
+            if (StringHelper.EqualsIgnoreCase(container, "gif"))
                 return MediaFormatProfile.GIF_LRG;
 
-            if (string.Equals(container, "raw", StringComparison.OrdinalIgnoreCase))
+            if (StringHelper.EqualsIgnoreCase(container, "raw"))
                 return MediaFormatProfile.RAW;
 
             return null;

+ 8 - 7
MediaBrowser.Model/Dlna/SearchCriteria.cs

@@ -1,4 +1,5 @@
-using System;
+using MediaBrowser.Model.Extensions;
+using System;
 
 namespace MediaBrowser.Model.Dlna
 {
@@ -15,22 +16,22 @@ namespace MediaBrowser.Model.Dlna
 
             SearchType = SearchType.Unknown;
 
-            if (search.IndexOf("upnp:class", StringComparison.OrdinalIgnoreCase) != -1 &&
-                search.IndexOf("derivedfrom", StringComparison.OrdinalIgnoreCase) != -1)
+            if (StringHelper.IndexOfIgnoreCase(search, "upnp:class") != -1 &&
+                StringHelper.IndexOfIgnoreCase(search, "derivedfrom") != -1)
             {
-                if (search.IndexOf("object.item.audioItem", StringComparison.OrdinalIgnoreCase) != -1)
+                if (StringHelper.IndexOfIgnoreCase(search, "object.item.audioItem") != -1)
                 {
                     SearchType = SearchType.Audio;
                 }
-                else if (search.IndexOf("object.item.imageItem", StringComparison.OrdinalIgnoreCase) != -1)
+                else if (StringHelper.IndexOfIgnoreCase(search, "object.item.imageItem") != -1)
                 {
                     SearchType = SearchType.Image;
                 }
-                else if (search.IndexOf("object.item.videoItem", StringComparison.OrdinalIgnoreCase) != -1)
+                else if (StringHelper.IndexOfIgnoreCase(search, "object.item.videoItem") != -1)
                 {
                     SearchType = SearchType.Video;
                 }
-                else if (search.IndexOf("object.container.playlistContainer", StringComparison.OrdinalIgnoreCase) != -1)
+                else if (StringHelper.IndexOfIgnoreCase(search, "object.container.playlistContainer") != -1)
                 {
                     SearchType = SearchType.Playlist;
                 }

+ 13 - 15
MediaBrowser.Model/Dlna/StreamBuilder.cs

@@ -1,17 +1,15 @@
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Extensions;
 using MediaBrowser.Model.MediaInfo;
 using System;
 using System.Collections.Generic;
-using System.Globalization;
 using System.Linq;
 
 namespace MediaBrowser.Model.Dlna
 {
     public class StreamBuilder
     {
-        private readonly CultureInfo _usCulture = new CultureInfo("en-US");
-
         public StreamInfo BuildAudioItem(AudioOptions options)
         {
             ValidateAudioInput(options);
@@ -27,7 +25,7 @@ namespace MediaBrowser.Model.Dlna
                 mediaSources = new List<MediaSourceInfo>();
                 foreach (MediaSourceInfo i in mediaSources)
                 {
-                    if (string.Equals(i.Id, mediaSourceId, StringComparison.OrdinalIgnoreCase))
+                    if (StringHelper.EqualsIgnoreCase(i.Id, mediaSourceId))
                         mediaSources.Add(i);
                 }
             }
@@ -60,7 +58,7 @@ namespace MediaBrowser.Model.Dlna
                 mediaSources = new List<MediaSourceInfo>();
                 foreach (MediaSourceInfo i in mediaSources)
                 {
-                    if (string.Equals(i.Id, mediaSourceId, StringComparison.OrdinalIgnoreCase))
+                    if (StringHelper.EqualsIgnoreCase(i.Id, mediaSourceId))
                         mediaSources.Add(i);
                 }
             }
@@ -505,7 +503,7 @@ namespace MediaBrowser.Model.Dlna
                     case ProfileConditionValue.AudioBitrate:
                         {
                             int num;
-                            if (int.TryParse(value, NumberStyles.Any, _usCulture, out num))
+                            if (IntHelper.TryParseCultureInvariant(value, out num))
                             {
                                 item.AudioBitrate = num;
                             }
@@ -514,7 +512,7 @@ namespace MediaBrowser.Model.Dlna
                     case ProfileConditionValue.AudioChannels:
                         {
                             int num;
-                            if (int.TryParse(value, NumberStyles.Any, _usCulture, out num))
+                            if (IntHelper.TryParseCultureInvariant(value, out num))
                             {
                                 item.MaxAudioChannels = num;
                             }
@@ -537,7 +535,7 @@ namespace MediaBrowser.Model.Dlna
                     case ProfileConditionValue.Height:
                         {
                             int num;
-                            if (int.TryParse(value, NumberStyles.Any, _usCulture, out num))
+                            if (IntHelper.TryParseCultureInvariant(value, out num))
                             {
                                 item.MaxHeight = num;
                             }
@@ -546,7 +544,7 @@ namespace MediaBrowser.Model.Dlna
                     case ProfileConditionValue.VideoBitrate:
                         {
                             int num;
-                            if (int.TryParse(value, NumberStyles.Any, _usCulture, out num))
+                            if (IntHelper.TryParseCultureInvariant(value, out num))
                             {
                                 item.VideoBitrate = num;
                             }
@@ -554,8 +552,8 @@ namespace MediaBrowser.Model.Dlna
                         }
                     case ProfileConditionValue.VideoFramerate:
                         {
-                            int num;
-                            if (int.TryParse(value, NumberStyles.Any, _usCulture, out num))
+                            double num;
+                            if (DoubleHelper.TryParseCultureInvariant(value, out num))
                             {
                                 item.MaxFramerate = num;
                             }
@@ -564,7 +562,7 @@ namespace MediaBrowser.Model.Dlna
                     case ProfileConditionValue.VideoLevel:
                         {
                             int num;
-                            if (int.TryParse(value, NumberStyles.Any, _usCulture, out num))
+                            if (IntHelper.TryParseCultureInvariant(value, out num))
                             {
                                 item.VideoLevel = num;
                             }
@@ -573,7 +571,7 @@ namespace MediaBrowser.Model.Dlna
                     case ProfileConditionValue.Width:
                         {
                             int num;
-                            if (int.TryParse(value, NumberStyles.Any, _usCulture, out num))
+                            if (IntHelper.TryParseCultureInvariant(value, out num))
                             {
                                 item.MaxWidth = num;
                             }
@@ -594,7 +592,7 @@ namespace MediaBrowser.Model.Dlna
                 bool any = false;
                 foreach (string i in profile.GetContainers())
                 {
-                    if (string.Equals(i, mediaContainer, StringComparison.OrdinalIgnoreCase))
+                    if (StringHelper.EqualsIgnoreCase(i, mediaContainer))
                     {
                         any = true;
                         break;
@@ -624,7 +622,7 @@ namespace MediaBrowser.Model.Dlna
                 bool any = false;
                 foreach (string i in profile.GetContainers())
                 {
-                    if (string.Equals(i, mediaContainer, StringComparison.OrdinalIgnoreCase))
+                    if (StringHelper.EqualsIgnoreCase(i, mediaContainer))
                     {
                         any = true;
                         break;

+ 14 - 16
MediaBrowser.Model/Dlna/StreamInfo.cs

@@ -1,10 +1,10 @@
 using MediaBrowser.Model.Drawing;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Extensions;
 using MediaBrowser.Model.MediaInfo;
 using System;
 using System.Collections.Generic;
-using System.Globalization;
 
 namespace MediaBrowser.Model.Dlna
 {
@@ -45,7 +45,7 @@ namespace MediaBrowser.Model.Dlna
         public int? MaxWidth { get; set; }
         public int? MaxHeight { get; set; }
 
-        public int? MaxFramerate { get; set; }
+        public double? MaxFramerate { get; set; }
 
         public string DeviceProfileId { get; set; }
         public string DeviceId { get; set; }
@@ -89,7 +89,7 @@ namespace MediaBrowser.Model.Dlna
                 return string.Format("{0}/audio/{1}/stream{2}?{3}", baseUrl, ItemId, extension, dlnaCommand);
             }
 
-            if (string.Equals(Protocol, "hls", StringComparison.OrdinalIgnoreCase))
+            if (StringHelper.EqualsIgnoreCase(Protocol, "hls"))
             {
                 return string.Format("{0}/videos/{1}/stream.m3u8?{2}", baseUrl, ItemId, dlnaCommand);
             }
@@ -97,8 +97,6 @@ namespace MediaBrowser.Model.Dlna
             return string.Format("{0}/videos/{1}/stream{2}?{3}", baseUrl, ItemId, extension, dlnaCommand);
         }
 
-        private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
-
         private static string BuildDlnaParam(StreamInfo item)
         {
             List<string> list = new List<string>
@@ -109,16 +107,16 @@ namespace MediaBrowser.Model.Dlna
                 (item.IsDirectStream).ToString().ToLower(),
                 item.VideoCodec ?? string.Empty,
                 item.AudioCodec ?? string.Empty,
-                item.AudioStreamIndex.HasValue ? item.AudioStreamIndex.Value.ToString(UsCulture) : string.Empty,
-                item.SubtitleStreamIndex.HasValue ? item.SubtitleStreamIndex.Value.ToString(UsCulture) : string.Empty,
-                item.VideoBitrate.HasValue ? item.VideoBitrate.Value.ToString(UsCulture) : string.Empty,
-                item.AudioBitrate.HasValue ? item.AudioBitrate.Value.ToString(UsCulture) : string.Empty,
-                item.MaxAudioChannels.HasValue ? item.MaxAudioChannels.Value.ToString(UsCulture) : string.Empty,
-                item.MaxFramerate.HasValue ? item.MaxFramerate.Value.ToString(UsCulture) : string.Empty,
-                item.MaxWidth.HasValue ? item.MaxWidth.Value.ToString(UsCulture) : string.Empty,
-                item.MaxHeight.HasValue ? item.MaxHeight.Value.ToString(UsCulture) : string.Empty,
-                item.StartPositionTicks.ToString(UsCulture),
-                item.VideoLevel.HasValue ? item.VideoLevel.Value.ToString(UsCulture) : string.Empty
+                item.AudioStreamIndex.HasValue ? StringHelper.ToStringCultureInvariant(item.AudioStreamIndex.Value) : string.Empty,
+                item.SubtitleStreamIndex.HasValue ? StringHelper.ToStringCultureInvariant(item.SubtitleStreamIndex.Value) : string.Empty,
+                item.VideoBitrate.HasValue ? StringHelper.ToStringCultureInvariant(item.VideoBitrate.Value) : string.Empty,
+                item.AudioBitrate.HasValue ? StringHelper.ToStringCultureInvariant(item.AudioBitrate.Value) : string.Empty,
+                item.MaxAudioChannels.HasValue ? StringHelper.ToStringCultureInvariant(item.MaxAudioChannels.Value) : string.Empty,
+                item.MaxFramerate.HasValue ? StringHelper.ToStringCultureInvariant(item.MaxFramerate.Value) : string.Empty,
+                item.MaxWidth.HasValue ? StringHelper.ToStringCultureInvariant(item.MaxWidth.Value) : string.Empty,
+                item.MaxHeight.HasValue ? StringHelper.ToStringCultureInvariant(item.MaxHeight.Value) : string.Empty,
+                StringHelper.ToStringCultureInvariant(item.StartPositionTicks),
+                item.VideoLevel.HasValue ? StringHelper.ToStringCultureInvariant(item.VideoLevel.Value) : string.Empty
             };
 
             return string.Format("Params={0}", string.Join(";", list.ToArray()));
@@ -332,7 +330,7 @@ namespace MediaBrowser.Model.Dlna
         {
             get
             {
-                TransportStreamTimestamp defaultValue = string.Equals(Container, "m2ts", StringComparison.OrdinalIgnoreCase)
+                TransportStreamTimestamp defaultValue = StringHelper.EqualsIgnoreCase(Container, "m2ts")
                     ? TransportStreamTimestamp.Valid
                     : TransportStreamTimestamp.None;
 

+ 3 - 5
MediaBrowser.Model/Drawing/ImageSize.cs

@@ -1,4 +1,4 @@
-using System.Globalization;
+using MediaBrowser.Model.Extensions;
 
 namespace MediaBrowser.Model.Drawing
 {
@@ -7,8 +7,6 @@ namespace MediaBrowser.Model.Drawing
     /// </summary>
     public struct ImageSize
     {
-        private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
-
         private double _height;
         private double _width;
 
@@ -67,12 +65,12 @@ namespace MediaBrowser.Model.Drawing
                 {
                     double val;
 
-                    if (double.TryParse(parts[0], NumberStyles.Any, UsCulture, out val))
+                    if (DoubleHelper.TryParseCultureInvariant(parts[0], out val))
                     {
                         _width = val;
                     }
 
-                    if (double.TryParse(parts[1], NumberStyles.Any, UsCulture, out val))
+                    if (DoubleHelper.TryParseCultureInvariant(parts[1], out val))
                     {
                         _height = val;
                     }

+ 12 - 11
MediaBrowser.Model/Dto/BaseItemDto.cs

@@ -1,4 +1,5 @@
 using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Extensions;
 using MediaBrowser.Model.Library;
 using System;
 using System.Collections.Generic;
@@ -523,7 +524,7 @@ namespace MediaBrowser.Model.Dto
         /// <returns><c>true</c> if the specified type is type; otherwise, <c>false</c>.</returns>
         public bool IsType(string type)
         {
-            return Type.Equals(type, StringComparison.OrdinalIgnoreCase);
+            return StringHelper.EqualsIgnoreCase(Type, type);
         }
 
         /// <summary>
@@ -837,7 +838,7 @@ namespace MediaBrowser.Model.Dto
         [IgnoreDataMember]
         public bool IsVideo
         {
-            get { return string.Equals(MediaType, Entities.MediaType.Video, StringComparison.OrdinalIgnoreCase); }
+            get { return StringHelper.EqualsIgnoreCase(MediaType, Entities.MediaType.Video); }
         }
 
         /// <summary>
@@ -847,7 +848,7 @@ namespace MediaBrowser.Model.Dto
         [IgnoreDataMember]
         public bool IsAudio
         {
-            get { return string.Equals(MediaType, Entities.MediaType.Audio, StringComparison.OrdinalIgnoreCase); }
+            get { return StringHelper.EqualsIgnoreCase(MediaType, Entities.MediaType.Audio); }
         }
 
         /// <summary>
@@ -857,7 +858,7 @@ namespace MediaBrowser.Model.Dto
         [IgnoreDataMember]
         public bool IsGame
         {
-            get { return string.Equals(MediaType, Entities.MediaType.Game, StringComparison.OrdinalIgnoreCase); }
+            get { return StringHelper.EqualsIgnoreCase(MediaType, Entities.MediaType.Game); }
         }
 
         /// <summary>
@@ -867,7 +868,7 @@ namespace MediaBrowser.Model.Dto
         [IgnoreDataMember]
         public bool IsPerson
         {
-            get { return string.Equals(Type, "Person", StringComparison.OrdinalIgnoreCase); }
+            get { return StringHelper.EqualsIgnoreCase(Type, "Person"); }
         }
 
         /// <summary>
@@ -877,37 +878,37 @@ namespace MediaBrowser.Model.Dto
         [IgnoreDataMember]
         public bool IsRoot
         {
-            get { return string.Equals(Type, "AggregateFolder", StringComparison.OrdinalIgnoreCase); }
+            get { return StringHelper.EqualsIgnoreCase(Type, "AggregateFolder"); }
         }
 
         [IgnoreDataMember]
         public bool IsMusicGenre
         {
-            get { return string.Equals(Type, "MusicGenre", StringComparison.OrdinalIgnoreCase); }
+            get { return StringHelper.EqualsIgnoreCase(Type, "MusicGenre"); }
         }
 
         [IgnoreDataMember]
         public bool IsGameGenre
         {
-            get { return string.Equals(Type, "GameGenre", StringComparison.OrdinalIgnoreCase); }
+            get { return StringHelper.EqualsIgnoreCase(Type, "GameGenre"); }
         }
 
         [IgnoreDataMember]
         public bool IsGenre
         {
-            get { return string.Equals(Type, "Genre", StringComparison.OrdinalIgnoreCase); }
+            get { return StringHelper.EqualsIgnoreCase(Type, "Genre"); }
         }
 
         [IgnoreDataMember]
         public bool IsArtist
         {
-            get { return string.Equals(Type, "Artist", StringComparison.OrdinalIgnoreCase); }
+            get { return StringHelper.EqualsIgnoreCase(Type, "Artist"); }
         }
 
         [IgnoreDataMember]
         public bool IsStudio
         {
-            get { return string.Equals(Type, "Studio", StringComparison.OrdinalIgnoreCase); }
+            get { return StringHelper.EqualsIgnoreCase(Type, "Studio"); }
         }
 
         /// <summary>

+ 2 - 1
MediaBrowser.Model/Dto/MediaSourceInfo.cs

@@ -1,4 +1,5 @@
 using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Extensions;
 using MediaBrowser.Model.MediaInfo;
 using System;
 using System.Collections.Generic;
@@ -89,7 +90,7 @@ namespace MediaBrowser.Model.Dto
             {
                 foreach (MediaStream i in MediaStreams)
                 {
-                    if (i.Type == MediaStreamType.Video && (i.Codec ?? string.Empty).IndexOf("jpeg", StringComparison.OrdinalIgnoreCase) == -1)
+                    if (i.Type == MediaStreamType.Video && StringHelper.IndexOfIgnoreCase((i.Codec ?? string.Empty), "jpeg") == -1)
                     {
                         return i;
                     }

+ 3 - 2
MediaBrowser.Model/Entities/MediaStream.cs

@@ -1,6 +1,7 @@
 using System;
 using System.Diagnostics;
 using System.Runtime.Serialization;
+using MediaBrowser.Model.Extensions;
 
 namespace MediaBrowser.Model.Entities
 {
@@ -139,8 +140,8 @@ namespace MediaBrowser.Model.Entities
 
                 var codec = Codec ?? string.Empty;
 
-                return codec.IndexOf("pgs", StringComparison.OrdinalIgnoreCase) != -1 ||
-                       codec.IndexOf("dvd", StringComparison.OrdinalIgnoreCase) != -1;
+                return StringHelper.IndexOfIgnoreCase(codec, "pgs") != -1 ||
+                       StringHelper.IndexOfIgnoreCase(codec, "dvd") != -1;
             }
         }
 

+ 18 - 0
MediaBrowser.Model/Extensions/DoubleHelper.cs

@@ -0,0 +1,18 @@
+using System.Globalization;
+
+namespace MediaBrowser.Model.Extensions
+{
+    public static class DoubleHelper
+    {
+        /// <summary>
+        /// Tries the parse culture invariant.
+        /// </summary>
+        /// <param name="s">The s.</param>
+        /// <param name="result">The result.</param>
+        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
+        public static bool TryParseCultureInvariant(string s, out double result)
+        {
+            return double.TryParse(s, NumberStyles.Any, CultureInfo.InvariantCulture, out result);
+        }
+    }
+}

+ 18 - 0
MediaBrowser.Model/Extensions/IntHelper.cs

@@ -0,0 +1,18 @@
+using System.Globalization;
+
+namespace MediaBrowser.Model.Extensions
+{
+    public static class IntHelper
+    {
+        /// <summary>
+        /// Tries the parse culture invariant.
+        /// </summary>
+        /// <param name="s">The s.</param>
+        /// <param name="result">The result.</param>
+        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
+        public static bool TryParseCultureInvariant(string s, out int result)
+        {
+            return int.TryParse(s, NumberStyles.Any, CultureInfo.InvariantCulture, out result);
+        }
+    }
+}

+ 60 - 0
MediaBrowser.Model/Extensions/StringHelper.cs

@@ -0,0 +1,60 @@
+using System;
+using System.Globalization;
+
+namespace MediaBrowser.Model.Extensions
+{
+    public static class StringHelper
+    {
+        /// <summary>
+        /// Equalses the ignore case.
+        /// </summary>
+        /// <param name="str1">The STR1.</param>
+        /// <param name="str2">The STR2.</param>
+        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
+        public static bool EqualsIgnoreCase(string str1, string str2)
+        {
+            return string.Equals(str1, str2, StringComparison.OrdinalIgnoreCase);
+        }
+
+        /// <summary>
+        /// Indexes the of ignore case.
+        /// </summary>
+        /// <param name="str">The string.</param>
+        /// <param name="value">The value.</param>
+        /// <returns>System.Int32.</returns>
+        public static int IndexOfIgnoreCase(string str, string value)
+        {
+            return str.IndexOf(value, StringComparison.OrdinalIgnoreCase);
+        }
+
+        /// <summary>
+        /// To the string culture invariant.
+        /// </summary>
+        /// <param name="val">The value.</param>
+        /// <returns>System.String.</returns>
+        public static string ToStringCultureInvariant(int val)
+        {
+            return val.ToString(CultureInfo.InvariantCulture);
+        }
+
+        /// <summary>
+        /// To the string culture invariant.
+        /// </summary>
+        /// <param name="val">The value.</param>
+        /// <returns>System.String.</returns>
+        public static string ToStringCultureInvariant(long val)
+        {
+            return val.ToString(CultureInfo.InvariantCulture);
+        }
+
+        /// <summary>
+        /// To the string culture invariant.
+        /// </summary>
+        /// <param name="val">The value.</param>
+        /// <returns>System.String.</returns>
+        public static string ToStringCultureInvariant(double val)
+        {
+            return val.ToString(CultureInfo.InvariantCulture);
+        }
+    }
+}

+ 1 - 1
MediaBrowser.Model/LiveTv/ChannelInfoDto.cs

@@ -62,7 +62,7 @@ namespace MediaBrowser.Model.LiveTv
         /// Gets or sets the type of the channel.
         /// </summary>
         /// <value>The type of the channel.</value>
-        public LiveTvChannelType ChannelType { get; set; }
+        public ChannelType ChannelType { get; set; }
 
         /// <summary>
         /// Gets or sets the type.

+ 1 - 1
MediaBrowser.Model/LiveTv/LiveTvChannelType.cs → MediaBrowser.Model/LiveTv/ChannelType.cs

@@ -4,7 +4,7 @@ namespace MediaBrowser.Model.LiveTv
     /// <summary>
     /// Enum ChannelType
     /// </summary>
-    public enum LiveTvChannelType
+    public enum ChannelType
     {
         /// <summary>
         /// The TV

+ 1 - 1
MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs

@@ -10,7 +10,7 @@ namespace MediaBrowser.Model.LiveTv
         /// Gets or sets the type of the channel.
         /// </summary>
         /// <value>The type of the channel.</value>
-        public LiveTvChannelType? ChannelType { get; set; }
+        public ChannelType? ChannelType { get; set; }
 
         /// <summary>
         /// Gets or sets a value indicating whether this instance is favorite.

+ 1 - 1
MediaBrowser.Model/LiveTv/RecordingInfoDto.cs

@@ -164,7 +164,7 @@ namespace MediaBrowser.Model.LiveTv
         /// Gets or sets the type of the channel.
         /// </summary>
         /// <value>The type of the channel.</value>
-        public LiveTvChannelType ChannelType { get; set; }
+        public ChannelType ChannelType { get; set; }
 
         /// <summary>
         /// Gets or sets the official rating.

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

@@ -144,6 +144,9 @@
     <Compile Include="Entities\SortOrder.cs" />
     <Compile Include="Entities\VideoSize.cs" />
     <Compile Include="Events\GenericEventArgs.cs" />
+    <Compile Include="Extensions\DoubleHelper.cs" />
+    <Compile Include="Extensions\IntHelper.cs" />
+    <Compile Include="Extensions\StringHelper.cs" />
     <Compile Include="FileOrganization\EpisodeFileOrganizationRequest.cs" />
     <Compile Include="FileOrganization\FileOrganizationResult.cs" />
     <Compile Include="FileOrganization\FileOrganizationResultQuery.cs" />
@@ -200,7 +203,7 @@
     <Compile Include="IO\IIsoManager.cs" />
     <Compile Include="IO\IIsoMount.cs" />
     <Compile Include="IO\IIsoMounter.cs" />
-    <Compile Include="LiveTv\LiveTvChannelType.cs" />
+    <Compile Include="LiveTv\ChannelType.cs" />
     <Compile Include="LiveTv\LiveTvServiceInfo.cs" />
     <Compile Include="LiveTv\RecordingInfoDto.cs" />
     <Compile Include="Net\WebSocketMessage.cs" />

+ 29 - 6
MediaBrowser.Providers/TV/MissingEpisodeProvider.cs

@@ -93,10 +93,10 @@ namespace MediaBrowser.Providers.TV
 
             var hasBadData = HasInvalidContent(group);
 
-            var anySeasonsRemoved = await RemoveObsoleteOrMissingSeasons(group, episodeLookup, cancellationToken)
+            var anySeasonsRemoved = await RemoveObsoleteOrMissingSeasons(group, episodeLookup, hasBadData)
                 .ConfigureAwait(false);
 
-            var anyEpisodesRemoved = await RemoveObsoleteOrMissingEpisodes(group, episodeLookup, cancellationToken)
+            var anyEpisodesRemoved = await RemoveObsoleteOrMissingEpisodes(group, episodeLookup, hasBadData)
                 .ConfigureAwait(false);
 
             var hasNewEpisodes = false;
@@ -143,7 +143,16 @@ namespace MediaBrowser.Providers.TV
             var allItems = group.ToList().SelectMany(i => i.RecursiveChildren).ToList();
 
             return allItems.OfType<Season>().Any(i => !i.IndexNumber.HasValue) ||
-                   allItems.OfType<Episode>().Any(i => !i.IndexNumber.HasValue || !i.ParentIndexNumber.HasValue);
+                   allItems.OfType<Episode>().Any(i =>
+                   {
+                       if (!i.ParentIndexNumber.HasValue)
+                       {
+                           return true;
+                       }
+
+                       // You could have episodes under season 0 with no number
+                       return false;
+                   });
         }
 
         /// <summary>
@@ -271,7 +280,9 @@ namespace MediaBrowser.Providers.TV
         /// <summary>
         /// Removes the virtual entry after a corresponding physical version has been added
         /// </summary>
-        private async Task<bool> RemoveObsoleteOrMissingEpisodes(IEnumerable<Series> series, IEnumerable<Tuple<int, int>> episodeLookup, CancellationToken cancellationToken)
+        private async Task<bool> RemoveObsoleteOrMissingEpisodes(IEnumerable<Series> series, 
+            IEnumerable<Tuple<int, int>> episodeLookup, 
+            bool forceRemoveAll)
         {
             var existingEpisodes = (from s in series
                                     let seasonOffset = TvdbSeriesProvider.GetSeriesOffset(s.ProviderIds) ?? ((s.AnimeSeriesIndex ?? 1) - 1)
@@ -290,6 +301,11 @@ namespace MediaBrowser.Providers.TV
             var episodesToRemove = virtualEpisodes
                 .Where(i =>
                 {
+                    if (forceRemoveAll)
+                    {
+                        return true;
+                    }
+
                     if (i.Episode.IndexNumber.HasValue && i.Episode.ParentIndexNumber.HasValue)
                     {
                         var seasonNumber = i.Episode.ParentIndexNumber.Value + i.SeasonOffset;
@@ -335,9 +351,11 @@ namespace MediaBrowser.Providers.TV
         /// </summary>
         /// <param name="series">The series.</param>
         /// <param name="episodeLookup">The episode lookup.</param>
-        /// <param name="cancellationToken">The cancellation token.</param>
+        /// <param name="forceRemoveAll">if set to <c>true</c> [force remove all].</param>
         /// <returns>Task{System.Boolean}.</returns>
-        private async Task<bool> RemoveObsoleteOrMissingSeasons(IEnumerable<Series> series, IEnumerable<Tuple<int, int>> episodeLookup, CancellationToken cancellationToken)
+        private async Task<bool> RemoveObsoleteOrMissingSeasons(IEnumerable<Series> series, 
+            IEnumerable<Tuple<int, int>> episodeLookup,
+            bool forceRemoveAll)
         {
             var existingSeasons = (from s in series
                                    let seasonOffset = TvdbSeriesProvider.GetSeriesOffset(s.ProviderIds) ?? ((s.AnimeSeriesIndex ?? 1) - 1)
@@ -356,6 +374,11 @@ namespace MediaBrowser.Providers.TV
             var seasonsToRemove = virtualSeasons
                 .Where(i =>
                 {
+                    if (forceRemoveAll)
+                    {
+                        return true;
+                    }
+
                     if (i.Season.IndexNumber.HasValue)
                     {
                         var seasonNumber = i.Season.IndexNumber.Value + i.SeasonOffset;

+ 1 - 1
MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs

@@ -206,7 +206,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
                 IsRepeat = info.IsRepeat,
                 EpisodeTitle = info.EpisodeTitle,
                 ChannelType = info.ChannelType,
-                MediaType = info.ChannelType == LiveTvChannelType.Radio ? MediaType.Audio : MediaType.Video,
+                MediaType = info.ChannelType == ChannelType.Radio ? MediaType.Audio : MediaType.Video,
                 CommunityRating = GetClientCommunityRating(info.CommunityRating),
                 OfficialRating = info.OfficialRating,
                 Audio = info.Audio,

+ 2 - 2
MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs

@@ -416,7 +416,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
             return item;
         }
 
-        private LiveTvProgram GetProgram(ProgramInfo info, LiveTvChannelType channelType, string serviceName, CancellationToken cancellationToken)
+        private LiveTvProgram GetProgram(ProgramInfo info, ChannelType channelType, string serviceName, CancellationToken cancellationToken)
         {
             var id = _tvDtoService.GetInternalProgramId(serviceName, info.Id);
 
@@ -475,7 +475,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
 
             if (item == null)
             {
-                if (info.ChannelType == LiveTvChannelType.TV)
+                if (info.ChannelType == ChannelType.TV)
                 {
                     item = new LiveTvVideoRecording
                     {

+ 2 - 1
MediaBrowser.Server.Implementations/Localization/Server/server.json

@@ -795,5 +795,6 @@
 	"MessageNoCollectionsAvailable": "Collections allow you to enjoy personalized groupings of Movies, Series, Albums, Books and Games. Click the New button to start creating Collections.",
 	"HeaderWelcomeToMediaBrowserWebClient": "Welcome to the Media Browser Web Client",
 	"ButtonDismiss": "Dismiss",
-	"MessageLearnHowToCustomize": "Learn how to customize this page to your own personal tastes. Click your user icon in the top right corner of the screen to view and update your preferences."
+	"MessageLearnHowToCustomize": "Learn how to customize this page to your own personal tastes. Click your user icon in the top right corner of the screen to view and update your preferences.",
+	"ButtonEditOtherUserPreferences": "Edit this user's personal preferences."
 }

+ 5 - 4
MediaBrowser.Server.Implementations/Session/SessionManager.cs

@@ -256,7 +256,7 @@ namespace MediaBrowser.Server.Implementations.Session
 
             try
             {
-                var session = GetSession(sessionId);
+                var session = GetSession(sessionId, false);
 
                 if (session != null)
                 {
@@ -710,13 +710,14 @@ namespace MediaBrowser.Server.Implementations.Session
         /// Gets the session.
         /// </summary>
         /// <param name="sessionId">The session identifier.</param>
+        /// <param name="throwOnMissing">if set to <c>true</c> [throw on missing].</param>
         /// <returns>SessionInfo.</returns>
         /// <exception cref="ResourceNotFoundException"></exception>
-        private SessionInfo GetSession(string sessionId)
+        private SessionInfo GetSession(string sessionId, bool throwOnMissing = true)
         {
-            var session = Sessions.First(i => string.Equals(i.Id, sessionId));
+            var session = Sessions.FirstOrDefault(i => string.Equals(i.Id, sessionId));
 
-            if (session == null)
+            if (session == null && throwOnMissing)
             {
                 throw new ResourceNotFoundException(string.Format("Session {0} not found.", sessionId));
             }

+ 0 - 3
MediaBrowser.ServerApplication/ApplicationHost.cs

@@ -1,7 +1,6 @@
 using MediaBrowser.Api;
 using MediaBrowser.Common;
 using MediaBrowser.Common.Configuration;
-using MediaBrowser.Common.Constants;
 using MediaBrowser.Common.Events;
 using MediaBrowser.Common.Extensions;
 using MediaBrowser.Common.Implementations;
@@ -37,9 +36,7 @@ using MediaBrowser.Controller.Themes;
 using MediaBrowser.Dlna;
 using MediaBrowser.Dlna.ConnectionManager;
 using MediaBrowser.Dlna.ContentDirectory;
-using MediaBrowser.Dlna.Eventing;
 using MediaBrowser.Dlna.Main;
-using MediaBrowser.Dlna.Server;
 using MediaBrowser.MediaEncoding.BdInfo;
 using MediaBrowser.MediaEncoding.Encoder;
 using MediaBrowser.Model.Logging;

+ 3 - 1
MediaBrowser.ServerApplication/FFMpeg/FFMpegDownloadInfo.cs

@@ -149,8 +149,10 @@ namespace MediaBrowser.ServerApplication.FFMpeg
 
                     //No Unix version available 
                     return new string[] { };
+
+                default:
+                    throw new ApplicationException("No ffmpeg download available for " + pid);
             }
-            return new string[] { };
         }
     }
 

+ 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.387</version>
+        <version>3.0.388</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.387" />
+            <dependency id="MediaBrowser.Common" version="3.0.388" />
             <dependency id="NLog" version="2.1.0" />
             <dependency id="SimpleInjector" version="2.5.0" />
             <dependency id="sharpcompress" version="0.10.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.387</version>
+        <version>3.0.388</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.387</version>
+        <version>3.0.388</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.387" />
+            <dependency id="MediaBrowser.Common" version="3.0.388" />
         </dependencies>
     </metadata>
     <files>