瀏覽代碼

Merge pull request #2251 from MediaBrowser/dev

Dev
Luke 8 年之前
父節點
當前提交
165b4c2fb8
共有 100 個文件被更改,包括 1037 次插入1329 次删除
  1. 3 5
      Emby.Drawing/Emby.Drawing.csproj
  2. 21 4
      MediaBrowser.Api/BaseApiService.cs
  3. 5 0
      MediaBrowser.Api/ItemUpdateService.cs
  4. 1 7
      MediaBrowser.Api/MediaBrowser.Api.csproj
  5. 1 1
      MediaBrowser.Api/Movies/MoviesService.cs
  6. 6 1
      MediaBrowser.Api/Playback/BaseStreamingService.cs
  7. 6 1
      MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
  8. 1 1
      MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
  9. 2 1
      MediaBrowser.Api/Playback/Hls/VideoHlsService.cs
  10. 10 0
      MediaBrowser.Api/Playback/Progressive/VideoService.cs
  11. 0 1
      MediaBrowser.Api/packages.config
  12. 24 7
      MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
  13. 1 7
      MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
  14. 2 2
      MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs
  15. 0 1
      MediaBrowser.Common.Implementations/packages.config
  16. 0 4
      MediaBrowser.Common/MediaBrowser.Common.csproj
  17. 4 2
      MediaBrowser.Common/Net/HttpResponseInfo.cs
  18. 0 13
      MediaBrowser.Common/Net/INetworkManager.cs
  19. 7 7
      MediaBrowser.Controller/Entities/CollectionFolder.cs
  20. 0 1
      MediaBrowser.Controller/Entities/TV/Season.cs
  21. 11 5
      MediaBrowser.Controller/Entities/TV/Series.cs
  22. 8 8
      MediaBrowser.Controller/Entities/User.cs
  23. 65 110
      MediaBrowser.Controller/Entities/UserViewBuilder.cs
  24. 1 1
      MediaBrowser.Controller/Library/NameExtensions.cs
  25. 4 6
      MediaBrowser.Controller/MediaBrowser.Controller.csproj
  26. 1 1
      MediaBrowser.Controller/Threading/PeriodicTimer.cs
  27. 0 1
      MediaBrowser.Controller/packages.config
  28. 59 30
      MediaBrowser.Dlna/DlnaManager.cs
  29. 42 68
      MediaBrowser.Dlna/MediaBrowser.Dlna.csproj
  30. 68 0
      MediaBrowser.Dlna/ProfileSerialization/CodecProfile.cs
  31. 31 0
      MediaBrowser.Dlna/ProfileSerialization/ContainerProfile.cs
  32. 351 0
      MediaBrowser.Dlna/ProfileSerialization/DeviceProfile.cs
  33. 51 0
      MediaBrowser.Dlna/ProfileSerialization/DirectPlayProfile.cs
  34. 17 0
      MediaBrowser.Dlna/ProfileSerialization/HttpHeaderInfo.cs
  35. 39 0
      MediaBrowser.Dlna/ProfileSerialization/ProfileCondition.cs
  36. 64 0
      MediaBrowser.Dlna/ProfileSerialization/ResponseProfile.cs
  37. 48 0
      MediaBrowser.Dlna/ProfileSerialization/SubtitleProfile.cs
  38. 58 0
      MediaBrowser.Dlna/ProfileSerialization/TranscodingProfile.cs
  39. 13 0
      MediaBrowser.Dlna/ProfileSerialization/XmlAttribute.cs
  40. 0 0
      MediaBrowser.Dlna/Profiles/Json/BubbleUPnp.json
  41. 0 0
      MediaBrowser.Dlna/Profiles/Json/Default.json
  42. 0 0
      MediaBrowser.Dlna/Profiles/Json/Denon AVR.json
  43. 0 0
      MediaBrowser.Dlna/Profiles/Json/DirecTV HD-DVR.json
  44. 0 0
      MediaBrowser.Dlna/Profiles/Json/Dish Hopper-Joey.json
  45. 0 0
      MediaBrowser.Dlna/Profiles/Json/Kodi.json
  46. 0 0
      MediaBrowser.Dlna/Profiles/Json/LG Smart TV.json
  47. 0 0
      MediaBrowser.Dlna/Profiles/Json/Linksys DMA2100.json
  48. 0 0
      MediaBrowser.Dlna/Profiles/Json/MediaMonkey.json
  49. 0 0
      MediaBrowser.Dlna/Profiles/Json/Panasonic Viera.json
  50. 0 0
      MediaBrowser.Dlna/Profiles/Json/Popcorn Hour.json
  51. 0 0
      MediaBrowser.Dlna/Profiles/Json/Samsung Smart TV.json
  52. 0 0
      MediaBrowser.Dlna/Profiles/Json/Sony Blu-ray Player 2013.json
  53. 0 0
      MediaBrowser.Dlna/Profiles/Json/Sony Blu-ray Player 2014.json
  54. 0 0
      MediaBrowser.Dlna/Profiles/Json/Sony Blu-ray Player 2015.json
  55. 0 0
      MediaBrowser.Dlna/Profiles/Json/Sony Blu-ray Player 2016.json
  56. 0 0
      MediaBrowser.Dlna/Profiles/Json/Sony Blu-ray Player.json
  57. 0 0
      MediaBrowser.Dlna/Profiles/Json/Sony Bravia (2010).json
  58. 0 0
      MediaBrowser.Dlna/Profiles/Json/Sony Bravia (2011).json
  59. 0 0
      MediaBrowser.Dlna/Profiles/Json/Sony Bravia (2012).json
  60. 0 0
      MediaBrowser.Dlna/Profiles/Json/Sony Bravia (2013).json
  61. 0 0
      MediaBrowser.Dlna/Profiles/Json/Sony Bravia (2014).json
  62. 0 0
      MediaBrowser.Dlna/Profiles/Json/Sony PlayStation 3.json
  63. 0 0
      MediaBrowser.Dlna/Profiles/Json/Sony PlayStation 4.json
  64. 0 0
      MediaBrowser.Dlna/Profiles/Json/Vlc.json
  65. 0 0
      MediaBrowser.Dlna/Profiles/Json/WDTV Live.json
  66. 0 0
      MediaBrowser.Dlna/Profiles/Json/Xbox 360.json
  67. 0 0
      MediaBrowser.Dlna/Profiles/Json/Xbox One.json
  68. 0 0
      MediaBrowser.Dlna/Profiles/Json/foobar2000.json
  69. 0 29
      MediaBrowser.Dlna/Profiles/Xml/BubbleUPnp.xml
  70. 0 23
      MediaBrowser.Dlna/Profiles/Xml/Default.xml
  71. 0 28
      MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml
  72. 0 29
      MediaBrowser.Dlna/Profiles/Xml/DirecTV HD-DVR.xml
  73. 0 92
      MediaBrowser.Dlna/Profiles/Xml/Dish Hopper-Joey.xml
  74. 0 29
      MediaBrowser.Dlna/Profiles/Xml/Kodi.xml
  75. 0 29
      MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml
  76. 0 27
      MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml
  77. 0 29
      MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml
  78. 0 30
      MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml
  79. 0 23
      MediaBrowser.Dlna/Profiles/Xml/Popcorn Hour.xml
  80. 0 29
      MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml
  81. 0 33
      MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml
  82. 0 33
      MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2014.xml
  83. 0 31
      MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2015.xml
  84. 0 31
      MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2016.xml
  85. 0 31
      MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml
  86. 0 133
      MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml
  87. 0 31
      MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml
  88. 0 31
      MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml
  89. 0 31
      MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml
  90. 0 31
      MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2014).xml
  91. 0 31
      MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml
  92. 0 31
      MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 4.xml
  93. 0 29
      MediaBrowser.Dlna/Profiles/Xml/Vlc.xml
  94. 0 30
      MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml
  95. 0 31
      MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml
  96. 0 30
      MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml
  97. 0 29
      MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml
  98. 0 1
      MediaBrowser.Dlna/packages.config
  99. 3 2
      MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj
  100. 9 6
      MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj

+ 3 - 5
Emby.Drawing/Emby.Drawing.csproj

@@ -9,9 +9,10 @@
     <AppDesignerFolder>Properties</AppDesignerFolder>
     <RootNamespace>Emby.Drawing</RootNamespace>
     <AssemblyName>Emby.Drawing</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
     <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
+    <TargetFrameworkProfile />
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugSymbols>true</DebugSymbols>
@@ -42,9 +43,6 @@
     <Reference Include="Patterns.Logging">
       <HintPath>..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll</HintPath>
     </Reference>
-    <Reference Include="policy.2.0.taglib-sharp">
-      <HintPath>..\packages\taglib.2.1.0.0\lib\policy.2.0.taglib-sharp.dll</HintPath>
-    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
     <Reference Include="System.Drawing" />
@@ -54,7 +52,7 @@
     <Reference Include="System.Data" />
     <Reference Include="System.Xml" />
     <Reference Include="taglib-sharp">
-      <HintPath>..\packages\taglib.2.1.0.0\lib\taglib-sharp.dll</HintPath>
+      <HintPath>..\ThirdParty\taglib\taglib-sharp.dll</HintPath>
     </Reference>
   </ItemGroup>
   <ItemGroup>

+ 21 - 4
MediaBrowser.Api/BaseApiService.cs

@@ -6,9 +6,9 @@ using MediaBrowser.Controller.Net;
 using MediaBrowser.Controller.Session;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Logging;
-using ServiceStack.Text.Controller;
 using ServiceStack.Web;
 using System;
+using System.Collections.Generic;
 using System.Linq;
 using System.Threading.Tasks;
 
@@ -275,8 +275,8 @@ namespace MediaBrowser.Api
 
         protected string GetPathValue(int index)
         {
-            var pathInfo = PathInfo.Parse(Request.PathInfo);
-            var first = pathInfo.GetArgumentValue<string>(0);
+            var pathInfo = Parse(Request.PathInfo);
+            var first = pathInfo[0];
 
             // backwards compatibility
             if (string.Equals(first, "mediabrowser", StringComparison.OrdinalIgnoreCase) ||
@@ -285,7 +285,24 @@ namespace MediaBrowser.Api
                 index++;
             }
 
-            return pathInfo.GetArgumentValue<string>(index);
+            return pathInfo[index];
+        }
+
+        private static List<string> Parse(string pathUri)
+        {
+            var actionParts = pathUri.Split(new[] { "://" }, StringSplitOptions.None);
+
+            var pathInfo = actionParts[actionParts.Length - 1];
+
+            var optionsPos = pathInfo.LastIndexOf('?');
+            if (optionsPos != -1)
+            {
+                pathInfo = pathInfo.Substring(0, optionsPos);
+            }
+
+            var args = pathInfo.Split('/');
+
+            return args.Skip(1).ToList();
         }
 
         /// <summary>

+ 5 - 0
MediaBrowser.Api/ItemUpdateService.cs

@@ -295,6 +295,11 @@ namespace MediaBrowser.Api
             item.OfficialRating = string.IsNullOrWhiteSpace(request.OfficialRating) ? null : request.OfficialRating;
             item.CustomRating = request.CustomRating;
 
+            if (request.ProductionLocations != null)
+            {
+                item.ProductionLocations = request.ProductionLocations.ToList();
+            }
+
             item.PreferredMetadataCountryCode = request.PreferredMetadataCountryCode;
             item.PreferredMetadataLanguage = request.PreferredMetadataLanguage;
 

+ 1 - 7
MediaBrowser.Api/MediaBrowser.Api.csproj

@@ -11,7 +11,7 @@
     <AssemblyName>MediaBrowser.Api</AssemblyName>
     <FileAlignment>512</FileAlignment>
     <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
-    <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
     <ReleaseVersion>
     </ReleaseVersion>
     <TargetFrameworkProfile />
@@ -50,9 +50,6 @@
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\packages\CommonIO.1.0.0.9\lib\net45\CommonIO.dll</HintPath>
     </Reference>
-    <Reference Include="MoreLinq">
-      <HintPath>..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll</HintPath>
-    </Reference>
     <Reference Include="Patterns.Logging">
       <HintPath>..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll</HintPath>
     </Reference>
@@ -64,9 +61,6 @@
     <Reference Include="ServiceStack.Interfaces">
       <HintPath>..\ThirdParty\ServiceStack\ServiceStack.Interfaces.dll</HintPath>
     </Reference>
-    <Reference Include="ServiceStack.Text">
-      <HintPath>..\ThirdParty\ServiceStack.Text\ServiceStack.Text.dll</HintPath>
-    </Reference>
   </ItemGroup>
   <ItemGroup>
     <Compile Include="..\SharedVersion.cs">

+ 1 - 1
MediaBrowser.Api/Movies/MoviesService.cs

@@ -8,7 +8,6 @@ using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Querying;
-using MoreLinq;
 using ServiceStack;
 using System;
 using System.Collections.Generic;
@@ -16,6 +15,7 @@ using System.Linq;
 using System.Threading.Tasks;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.LiveTv;
+using MediaBrowser.Model.Extensions;
 
 namespace MediaBrowser.Api.Movies
 {

+ 6 - 1
MediaBrowser.Api/Playback/BaseStreamingService.cs

@@ -352,6 +352,11 @@ namespace MediaBrowser.Api.Playback
             return defaultEncoder;
         }
 
+        protected virtual string GetDefaultH264Preset()
+        {
+            return "superfast";
+        }
+
         /// <summary>
         /// Gets the video bitrate to specify on the command line
         /// </summary>
@@ -375,7 +380,7 @@ namespace MediaBrowser.Api.Playback
                 }
                 else
                 {
-                    param += "-preset superfast";
+                    param += "-preset " + GetDefaultH264Preset();
                 }
 
                 if (encodingOptions.H264Crf >= 0 && encodingOptions.H264Crf <= 51)

+ 6 - 1
MediaBrowser.Api/Playback/Hls/BaseHlsService.cs

@@ -256,7 +256,7 @@ namespace MediaBrowser.Api.Playback.Hls
                     "hls/" + Path.GetFileNameWithoutExtension(outputPath));
             }
 
-            var args = string.Format("{0} {1} {2} -map_metadata -1 -threads {3} {4} {5} -sc_threshold 0 {6} -hls_time {7} -start_number {8} -hls_list_size {9}{10} -y \"{11}\"",
+            var args = string.Format("{0} {1} {2} -map_metadata -1 -threads {3} {4} {5} -avoid_negative_ts make_zero -fflags +genpts -sc_threshold 0 {6} -hls_time {7} -start_number {8} -hls_list_size {9}{10} -y \"{11}\"",
                 itsOffset,
                 inputModifier,
                 GetInputArgument(state),
@@ -274,6 +274,11 @@ namespace MediaBrowser.Api.Playback.Hls
             return args;
         }
 
+        protected override string GetDefaultH264Preset()
+        {
+            return "veryfast";
+        }
+
         protected virtual int GetStartNumber(StreamState state)
         {
             return 0;

+ 1 - 1
MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs

@@ -886,7 +886,7 @@ namespace MediaBrowser.Api.Playback.Hls
 
             var mapArgs = state.IsOutputVideo ? GetMapArgs(state) : string.Empty;
             var enableSplittingOnNonKeyFrames = state.VideoRequest.EnableSplittingOnNonKeyFrames && string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase);
-            enableSplittingOnNonKeyFrames = false;
+
             // TODO: check libavformat version for 57 50.100 and use -hls_flags split_by_time
             var hlsProtocolSupportsSplittingByTime = false;
 

+ 2 - 1
MediaBrowser.Api/Playback/Hls/VideoHlsService.cs

@@ -91,6 +91,7 @@ namespace MediaBrowser.Api.Playback.Hls
                 {
                     args += " -bsf:v h264_mp4toannexb";
                 }
+                args += " -flags +global_header";
                 return args;
             }
 
@@ -113,7 +114,7 @@ namespace MediaBrowser.Api.Playback.Hls
                 args += GetGraphicalSubtitleParam(state, codec);
             }
 
-            args += " -flags -global_header";
+            args += " -flags +global_header";
 
             return args;
         }

+ 10 - 0
MediaBrowser.Api/Playback/Progressive/VideoService.cs

@@ -150,6 +150,11 @@ namespace MediaBrowser.Api.Playback.Progressive
                     args += " -copyts -avoid_negative_ts disabled -start_at_zero";
                 }
 
+                if (!state.RunTimeTicks.HasValue)
+                {
+                    args += " -fflags +genpts -flags +global_header";
+                }
+
                 return args;
             }
 
@@ -191,6 +196,11 @@ namespace MediaBrowser.Api.Playback.Progressive
                 args += GetGraphicalSubtitleParam(state, videoCodec);
             }
 
+            if (!state.RunTimeTicks.HasValue)
+            {
+                args += " -fflags +genpts -flags +global_header";
+            }
+
             return args;
         }
 

+ 0 - 1
MediaBrowser.Api/packages.config

@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
   <package id="CommonIO" version="1.0.0.9" targetFramework="net45" />
-  <package id="morelinq" version="1.4.0" targetFramework="net45" />
   <package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
 </packages>

+ 24 - 7
MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs

@@ -342,7 +342,6 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
                             ResponseUrl = url,
                             Content = memoryStream,
                             StatusCode = HttpStatusCode.OK,
-                            Headers = new NameValueCollection(),
                             ContentLength = memoryStream.Length
                         };
                     }
@@ -487,7 +486,7 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
 
         private HttpResponseInfo GetResponseInfo(HttpWebResponse httpResponse, Stream content, long? contentLength, IDisposable disposable)
         {
-            return new HttpResponseInfo(disposable)
+            var responseInfo = new HttpResponseInfo(disposable)
             {
                 Content = content,
 
@@ -495,17 +494,22 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
 
                 ContentType = httpResponse.ContentType,
 
-                Headers = new NameValueCollection(httpResponse.Headers),
-
                 ContentLength = contentLength,
 
                 ResponseUrl = httpResponse.ResponseUri.ToString()
             };
+
+            if (httpResponse.Headers != null)
+            {
+                SetHeaders(httpResponse.Headers, responseInfo);
+            }
+
+            return responseInfo;
         }
 
         private HttpResponseInfo GetResponseInfo(HttpWebResponse httpResponse, string tempFile, long? contentLength)
         {
-            return new HttpResponseInfo
+            var responseInfo = new HttpResponseInfo
             {
                 TempFilePath = tempFile,
 
@@ -513,10 +517,23 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
 
                 ContentType = httpResponse.ContentType,
 
-                Headers = httpResponse.Headers,
-
                 ContentLength = contentLength
             };
+
+            if (httpResponse.Headers != null)
+            {
+                SetHeaders(httpResponse.Headers, responseInfo);
+            }
+
+            return responseInfo;
+        }
+
+        private void SetHeaders(WebHeaderCollection headers, HttpResponseInfo responseInfo)
+        {
+            foreach (var key in headers.AllKeys)
+            {
+                responseInfo.Headers[key] = headers[key];
+            }
         }
 
         public Task<HttpResponseInfo> Post(HttpRequestOptions options)

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

@@ -13,7 +13,7 @@
     <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
     <ProductVersion>10.0.0</ProductVersion>
     <SchemaVersion>2.0</SchemaVersion>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
     <TargetFrameworkProfile />
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
@@ -24,7 +24,6 @@
     <DefineConstants>DEBUG;TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
-    <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
     <DebugType>none</DebugType>
@@ -33,7 +32,6 @@
     <DefineConstants>TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release Mono|AnyCPU' ">
     <DebugType>none</DebugType>
@@ -42,7 +40,6 @@
     <DefineConstants>TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
   </PropertyGroup>
   <PropertyGroup>
     <RunPostBuildEvent>Always</RunPostBuildEvent>
@@ -56,9 +53,6 @@
       <HintPath>..\packages\Microsoft.IO.RecyclableMemoryStream.1.1.0.0\lib\net45\Microsoft.IO.RecyclableMemoryStream.dll</HintPath>
       <Private>True</Private>
     </Reference>
-    <Reference Include="MoreLinq">
-      <HintPath>..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll</HintPath>
-    </Reference>
     <Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
       <HintPath>..\packages\NLog.4.3.8\lib\net45\NLog.dll</HintPath>
       <Private>True</Private>

+ 2 - 2
MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs

@@ -6,7 +6,7 @@ using System.Linq;
 using System.Net;
 using System.Net.NetworkInformation;
 using System.Net.Sockets;
-using MoreLinq;
+using MediaBrowser.Model.Extensions;
 
 namespace MediaBrowser.Common.Implementations.Networking
 {
@@ -308,7 +308,7 @@ namespace MediaBrowser.Common.Implementations.Networking
             string[] values = endpointstring.Split(new char[] { ':' });
             IPAddress ipaddy;
             int port = -1;
-
+          
             //check if we have an IPv6 or ports
             if (values.Length <= 2) // ipv4 or hostname
             {

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

@@ -2,7 +2,6 @@
 <packages>
   <package id="CommonIO" version="1.0.0.9" targetFramework="net45" />
   <package id="Microsoft.IO.RecyclableMemoryStream" version="1.1.0.0" targetFramework="net45" />
-  <package id="morelinq" version="1.4.0" targetFramework="net45" />
   <package id="NLog" version="4.3.8" targetFramework="net45" />
   <package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
   <package id="SimpleInjector" version="3.2.2" targetFramework="net45" />

+ 0 - 4
MediaBrowser.Common/MediaBrowser.Common.csproj

@@ -24,7 +24,6 @@
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
     <PlatformTarget>AnyCPU</PlatformTarget>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
     <DebugType>none</DebugType>
@@ -33,7 +32,6 @@
     <DefineConstants>TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release Mono|AnyCPU' ">
     <DebugType>none</DebugType>
@@ -42,7 +40,6 @@
     <DefineConstants>TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
   </PropertyGroup>
   <ItemGroup>
     <Reference Include="System" />
@@ -91,7 +88,6 @@
     <Compile Include="Security\IRequiresRegistration.cs" />
     <Compile Include="Security\ISecurityManager.cs" />
     <Compile Include="Security\PaymentRequiredException.cs" />
-    <Compile Include="Threading\PeriodicTimer.cs" />
     <Compile Include="Updates\IInstallationManager.cs" />
     <Compile Include="Updates\InstallationEventArgs.cs" />
     <Compile Include="Updates\InstallationFailedEventArgs.cs" />

+ 4 - 2
MediaBrowser.Common/Net/HttpResponseInfo.cs

@@ -1,5 +1,5 @@
 using System;
-using System.Collections.Specialized;
+using System.Collections.Generic;
 using System.IO;
 using System.Net;
 
@@ -50,16 +50,18 @@ namespace MediaBrowser.Common.Net
         /// Gets or sets the headers.
         /// </summary>
         /// <value>The headers.</value>
-        public NameValueCollection Headers { get; set; }
+        public Dictionary<string,string> Headers { get; set; }
 
         private readonly IDisposable _disposable;
 
         public HttpResponseInfo(IDisposable disposable)
         {
             _disposable = disposable;
+            Headers = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
         }
         public HttpResponseInfo()
         {
+            Headers = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
         }
 
         public void Dispose()

+ 0 - 13
MediaBrowser.Common/Net/INetworkManager.cs

@@ -7,12 +7,6 @@ namespace MediaBrowser.Common.Net
 {
     public interface INetworkManager
     {
-        /// <summary>
-        /// Gets the machine's local ip address
-        /// </summary>
-        /// <returns>IPAddress.</returns>
-		IEnumerable<IPAddress> GetLocalIpAddresses();
-
         /// <summary>
         /// Gets a random port number that is currently available
         /// </summary>
@@ -45,13 +39,6 @@ namespace MediaBrowser.Common.Net
         /// <returns>PC's in the Domain</returns>
         IEnumerable<FileSystemEntryInfo> GetNetworkDevices();
 
-        /// <summary>
-        /// Parses the specified endpointstring.
-        /// </summary>
-        /// <param name="endpointstring">The endpointstring.</param>
-        /// <returns>IPEndPoint.</returns>
-        IPEndPoint Parse(string endpointstring);
-
         /// <summary>
         /// Determines whether [is in local network] [the specified endpoint].
         /// </summary>

+ 7 - 7
MediaBrowser.Controller/Entities/CollectionFolder.cs

@@ -11,8 +11,8 @@ using System.Threading.Tasks;
 using CommonIO;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Model.Configuration;
+using MediaBrowser.Model.Extensions;
 using MediaBrowser.Model.Serialization;
-using MoreLinq;
 
 namespace MediaBrowser.Controller.Entities
 {
@@ -29,7 +29,7 @@ namespace MediaBrowser.Controller.Entities
             PhysicalLocationsList = new List<string>();
         }
 
-        [IgnoreDataMember]
+        [System.Runtime.Serialization.IgnoreDataMember]
         protected override bool SupportsShortcutChildren
         {
             get
@@ -38,7 +38,7 @@ namespace MediaBrowser.Controller.Entities
             }
         }
 
-        [IgnoreDataMember]
+        [System.Runtime.Serialization.IgnoreDataMember]
         public override bool SupportsPlayedStatus
         {
             get
@@ -129,7 +129,7 @@ namespace MediaBrowser.Controller.Entities
         /// Allow different display preferences for each collection folder
         /// </summary>
         /// <value>The display prefs id.</value>
-        [IgnoreDataMember]
+        [System.Runtime.Serialization.IgnoreDataMember]
         public override Guid DisplayPreferencesId
         {
             get
@@ -138,7 +138,7 @@ namespace MediaBrowser.Controller.Entities
             }
         }
 
-        [IgnoreDataMember]
+        [System.Runtime.Serialization.IgnoreDataMember]
         public override IEnumerable<string> PhysicalLocations
         {
             get
@@ -283,7 +283,7 @@ namespace MediaBrowser.Controller.Entities
         /// Our children are actually just references to the ones in the physical root...
         /// </summary>
         /// <value>The actual children.</value>
-        [IgnoreDataMember]
+        [System.Runtime.Serialization.IgnoreDataMember]
         protected override IEnumerable<BaseItem> ActualChildren
         {
             get { return GetActualChildren(); }
@@ -322,7 +322,7 @@ namespace MediaBrowser.Controller.Entities
             return result;
         }
 
-        [IgnoreDataMember]
+        [System.Runtime.Serialization.IgnoreDataMember]
         public override bool SupportsPeople
         {
             get

+ 0 - 1
MediaBrowser.Controller/Entities/TV/Season.cs

@@ -2,7 +2,6 @@
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Model.Querying;
 using MediaBrowser.Model.Users;
-using MoreLinq;
 using System.Collections.Generic;
 using System.Linq;
 using System.Runtime.Serialization;

+ 11 - 5
MediaBrowser.Controller/Entities/TV/Series.cs

@@ -9,8 +9,8 @@ using System.Linq;
 using System.Runtime.Serialization;
 using System.Threading;
 using System.Threading.Tasks;
+using MediaBrowser.Model.Extensions;
 using MediaBrowser.Model.Providers;
-using MoreLinq;
 
 namespace MediaBrowser.Controller.Entities.TV
 {
@@ -106,6 +106,12 @@ namespace MediaBrowser.Controller.Entities.TV
 
         private string AddLibrariesToPresentationUniqueKey(string key)
         {
+            var lang = GetPreferredMetadataLanguage();
+            if (!string.IsNullOrWhiteSpace(lang))
+            {
+                key += "-" + lang;
+            }
+
             var folders = LibraryManager.GetCollectionFolders(this)
                 .Select(i => i.Id.ToString("N"))
                 .ToArray();
@@ -209,8 +215,8 @@ namespace MediaBrowser.Controller.Entities.TV
             var query = new InternalItemsQuery(user)
             {
                 AncestorWithPresentationUniqueKey = seriesKey,
-                IncludeItemTypes = new[] {typeof (Season).Name},
-                SortBy = new[] {ItemSortBy.SortName}
+                IncludeItemTypes = new[] { typeof(Season).Name },
+                SortBy = new[] { ItemSortBy.SortName }
             };
 
             if (!config.DisplayMissingEpisodes && !config.DisplayUnairedEpisodes)
@@ -267,8 +273,8 @@ namespace MediaBrowser.Controller.Entities.TV
             var query = new InternalItemsQuery(user)
             {
                 AncestorWithPresentationUniqueKey = seriesKey,
-                IncludeItemTypes = new[] {typeof (Episode).Name, typeof (Season).Name},
-                SortBy = new[] {ItemSortBy.SortName}
+                IncludeItemTypes = new[] { typeof(Episode).Name, typeof(Season).Name },
+                SortBy = new[] { ItemSortBy.SortName }
             };
             var config = user.Configuration;
             if (!config.DisplayMissingEpisodes && !config.DisplayUnairedEpisodes)

+ 8 - 8
MediaBrowser.Controller/Entities/User.cs

@@ -42,7 +42,7 @@ namespace MediaBrowser.Controller.Entities
         /// Gets or sets the path.
         /// </summary>
         /// <value>The path.</value>
-        [IgnoreDataMember]
+        [System.Runtime.Serialization.IgnoreDataMember]
         public override string Path
         {
             get
@@ -81,7 +81,7 @@ namespace MediaBrowser.Controller.Entities
         /// If the item is a folder, it returns the folder itself
         /// </summary>
         /// <value>The containing folder path.</value>
-        [IgnoreDataMember]
+        [System.Runtime.Serialization.IgnoreDataMember]
         public override string ContainingFolderPath
         {
             get
@@ -94,7 +94,7 @@ namespace MediaBrowser.Controller.Entities
         /// Gets a value indicating whether this instance is owned item.
         /// </summary>
         /// <value><c>true</c> if this instance is owned item; otherwise, <c>false</c>.</value>
-        [IgnoreDataMember]
+        [System.Runtime.Serialization.IgnoreDataMember]
         public override bool IsOwnedItem
         {
             get
@@ -107,7 +107,7 @@ namespace MediaBrowser.Controller.Entities
         /// Gets the root folder.
         /// </summary>
         /// <value>The root folder.</value>
-        [IgnoreDataMember]
+        [System.Runtime.Serialization.IgnoreDataMember]
         public Folder RootFolder
         {
             get
@@ -129,7 +129,7 @@ namespace MediaBrowser.Controller.Entities
 
         private volatile UserConfiguration _config;
         private readonly object _configSyncLock = new object();
-        [IgnoreDataMember]
+        [System.Runtime.Serialization.IgnoreDataMember]
         public UserConfiguration Configuration
         {
             get
@@ -152,7 +152,7 @@ namespace MediaBrowser.Controller.Entities
 
         private volatile UserPolicy _policy;
         private readonly object _policySyncLock = new object();
-        [IgnoreDataMember]
+        [System.Runtime.Serialization.IgnoreDataMember]
         public UserPolicy Policy
         {
             get
@@ -232,7 +232,7 @@ namespace MediaBrowser.Controller.Entities
         /// Gets the path to the user's configuration directory
         /// </summary>
         /// <value>The configuration directory path.</value>
-        [IgnoreDataMember]
+        [System.Runtime.Serialization.IgnoreDataMember]
         public string ConfigurationDirectoryPath
         {
             get
@@ -308,7 +308,7 @@ namespace MediaBrowser.Controller.Entities
             return Configuration.GroupedFolders.Select(i => new Guid(i)).Contains(id);
         }
 
-        [IgnoreDataMember]
+        [System.Runtime.Serialization.IgnoreDataMember]
         public override bool SupportsPeople
         {
             get

+ 65 - 110
MediaBrowser.Controller/Entities/UserViewBuilder.cs

@@ -17,7 +17,7 @@ using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
 using MediaBrowser.Controller.Configuration;
-using MoreLinq;
+using MediaBrowser.Model.Extensions;
 
 namespace MediaBrowser.Controller.Entities
 {
@@ -201,7 +201,7 @@ namespace MediaBrowser.Controller.Entities
                     return await GetMusicFolders(queryParent, user, query).ConfigureAwait(false);
 
                 case SpecialFolder.MusicGenres:
-                    return await GetMusicGenres(queryParent, user, query).ConfigureAwait(false);
+                    return GetMusicGenres(queryParent, user, query);
 
                 case SpecialFolder.MusicGenre:
                     return await GetMusicGenreItems(queryParent, displayParent, user, query).ConfigureAwait(false);
@@ -290,32 +290,20 @@ namespace MediaBrowser.Controller.Entities
             return GetResult(list, parent, query);
         }
 
-        private async Task<QueryResult<BaseItem>> GetMusicGenres(Folder parent, User user, InternalItemsQuery query)
+        private QueryResult<BaseItem> GetMusicGenres(Folder parent, User user, InternalItemsQuery query)
         {
-            var tasks = GetRecursiveChildren(parent, user, new[] { CollectionType.Music, CollectionType.MusicVideos })
-                .Where(i => !i.IsFolder)
-                .SelectMany(i => i.Genres)
-                .DistinctNames()
-                .Select(i =>
-                {
-                    try
-                    {
-                        return _libraryManager.GetMusicGenre(i);
-                    }
-                    catch
-                    {
-                        // Full exception logged at lower levels
-                        _logger.Error("Error getting genre");
-                        return null;
-                    }
-
-                })
-                .Where(i => i != null)
-                .Select(i => GetUserView(i.Name, SpecialFolder.MusicGenre, i.SortName, parent));
-
-            var genres = await Task.WhenAll(tasks).ConfigureAwait(false);
+            var result = _libraryManager.GetMusicGenres(new InternalItemsQuery(user)
+            {
+                AncestorIds = new[] { parent.Id.ToString("N") },
+                StartIndex = query.StartIndex,
+                Limit = query.Limit
+            });
 
-            return GetResult(genres, parent, query);
+            return new QueryResult<BaseItem>
+            {
+                TotalRecordCount = result.TotalRecordCount,
+                Items = result.Items.Select(i => i.Item1).ToArray()
+            };
         }
 
         private async Task<QueryResult<BaseItem>> GetMusicGenreItems(Folder queryParent, Folder displayParent, User user, InternalItemsQuery query)
@@ -332,50 +320,51 @@ namespace MediaBrowser.Controller.Entities
 
         private QueryResult<BaseItem> GetMusicAlbumArtists(Folder parent, User user, InternalItemsQuery query)
         {
-            var items = parent.QueryRecursive(new InternalItemsQuery(user)
+            var artists = _libraryManager.GetAlbumArtists(new InternalItemsQuery(user)
             {
-                Recursive = true,
-                ParentId = parent.Id,
-                IncludeItemTypes = new[] { typeof(Audio.Audio).Name },
-                EnableTotalRecordCount = false
-
-            }).Items.Cast<IHasAlbumArtist>();
-
-            var artists = _libraryManager.GetAlbumArtists(items);
+                AncestorIds = new[] { parent.Id.ToString("N") },
+                StartIndex = query.StartIndex,
+                Limit = query.Limit
+            });
 
-            return GetResult(artists, parent, query);
+            return new QueryResult<BaseItem>
+            {
+                TotalRecordCount = artists.TotalRecordCount,
+                Items = artists.Items.Select(i => i.Item1).ToArray()
+            };
         }
 
         private QueryResult<BaseItem> GetMusicArtists(Folder parent, User user, InternalItemsQuery query)
         {
-            var items = parent.QueryRecursive(new InternalItemsQuery(user)
+            var artists = _libraryManager.GetArtists(new InternalItemsQuery(user)
             {
-                Recursive = true,
-                ParentId = parent.Id,
-                IncludeItemTypes = new[] { typeof(Audio.Audio).Name, typeof(MusicVideo).Name },
-                EnableTotalRecordCount = false
-
-            }).Items.Cast<IHasArtist>();
-
-            var artists = _libraryManager.GetArtists(items);
+                AncestorIds = new[] { parent.Id.ToString("N") },
+                StartIndex = query.StartIndex,
+                Limit = query.Limit
+            });
 
-            return GetResult(artists, parent, query);
+            return new QueryResult<BaseItem>
+            {
+                TotalRecordCount = artists.TotalRecordCount,
+                Items = artists.Items.Select(i => i.Item1).ToArray()
+            };
         }
 
         private QueryResult<BaseItem> GetFavoriteArtists(Folder parent, User user, InternalItemsQuery query)
         {
-            var items = parent.QueryRecursive(new InternalItemsQuery(user)
+            var artists = _libraryManager.GetArtists(new InternalItemsQuery(user)
             {
-                Recursive = true,
-                ParentId = parent.Id,
-                IncludeItemTypes = new[] { typeof(Audio.Audio).Name },
-                EnableTotalRecordCount = false
-
-            }).Items.Cast<IHasAlbumArtist>();
-
-            var artists = _libraryManager.GetAlbumArtists(items).Where(i => _userDataManager.GetUserData(user, i).IsFavorite);
+                AncestorIds = new[] { parent.Id.ToString("N") },
+                StartIndex = query.StartIndex,
+                Limit = query.Limit,
+                IsFavorite = true
+            });
 
-            return GetResult(artists, parent, query);
+            return new QueryResult<BaseItem>
+            {
+                TotalRecordCount = artists.TotalRecordCount,
+                Items = artists.Items.Select(i => i.Item1).ToArray()
+            };
         }
 
         private QueryResult<BaseItem> GetMusicPlaylists(Folder parent, User user, InternalItemsQuery query)
@@ -577,35 +566,18 @@ namespace MediaBrowser.Controller.Entities
 
         private async Task<QueryResult<BaseItem>> GetMovieGenres(Folder parent, User user, InternalItemsQuery query)
         {
-            var tasks = parent.QueryRecursive(new InternalItemsQuery(user)
+            var result = _libraryManager.GetGenres(new InternalItemsQuery(user)
             {
-                IncludeItemTypes = new[] { typeof(Movie).Name },
-                Recursive = true,
-                EnableTotalRecordCount = false
-
-            }).Items
-                .SelectMany(i => i.Genres)
-                .DistinctNames()
-                .Select(i =>
-                {
-                    try
-                    {
-                        return _libraryManager.GetGenre(i);
-                    }
-                    catch
-                    {
-                        // Full exception logged at lower levels
-                        _logger.Error("Error getting genre");
-                        return null;
-                    }
-
-                })
-                .Where(i => i != null)
-                .Select(i => GetUserView(i.Name, SpecialFolder.MovieGenre, i.SortName, parent));
-
-            var genres = await Task.WhenAll(tasks).ConfigureAwait(false);
+                AncestorIds = new[] { parent.Id.ToString("N") },
+                StartIndex = query.StartIndex,
+                Limit = query.Limit
+            });
 
-            return GetResult(genres, parent, query);
+            return new QueryResult<BaseItem>
+            {
+                TotalRecordCount = result.TotalRecordCount,
+                Items = result.Items.Select(i => i.Item1).ToArray()
+            };
         }
 
         private async Task<QueryResult<BaseItem>> GetMovieGenreItems(Folder queryParent, Folder displayParent, User user, InternalItemsQuery query)
@@ -720,35 +692,18 @@ namespace MediaBrowser.Controller.Entities
 
         private async Task<QueryResult<BaseItem>> GetTvGenres(Folder parent, User user, InternalItemsQuery query)
         {
-            var tasks = parent.QueryRecursive(new InternalItemsQuery(user)
+            var result = _libraryManager.GetGenres(new InternalItemsQuery(user)
             {
-                IncludeItemTypes = new[] { typeof(Series).Name },
-                Recursive = true,
-                EnableTotalRecordCount = false
-
-            }).Items
-                .SelectMany(i => i.Genres)
-                .DistinctNames()
-                .Select(i =>
-                {
-                    try
-                    {
-                        return _libraryManager.GetGenre(i);
-                    }
-                    catch
-                    {
-                        // Full exception logged at lower levels
-                        _logger.Error("Error getting genre");
-                        return null;
-                    }
-
-                })
-                .Where(i => i != null)
-                .Select(i => GetUserView(i.Name, SpecialFolder.TvGenre, i.SortName, parent));
-
-            var genres = await Task.WhenAll(tasks).ConfigureAwait(false);
+                AncestorIds = new[] { parent.Id.ToString("N") },
+                StartIndex = query.StartIndex,
+                Limit = query.Limit
+            });
 
-            return GetResult(genres, parent, query);
+            return new QueryResult<BaseItem>
+            {
+                TotalRecordCount = result.TotalRecordCount,
+                Items = result.Items.Select(i => i.Item1).ToArray()
+            };
         }
 
         private QueryResult<BaseItem> GetTvGenreItems(Folder queryParent, Folder displayParent, User user, InternalItemsQuery query)

+ 1 - 1
MediaBrowser.Controller/Library/NameExtensions.cs

@@ -1,9 +1,9 @@
 using MediaBrowser.Common.Extensions;
-using MoreLinq;
 using System;
 using System.Collections.Generic;
 using System.Globalization;
 using System.Linq;
+using MediaBrowser.Model.Extensions;
 
 namespace MediaBrowser.Controller.Library
 {

+ 4 - 6
MediaBrowser.Controller/MediaBrowser.Controller.csproj

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -11,9 +11,10 @@
     <AssemblyName>MediaBrowser.Controller</AssemblyName>
     <FileAlignment>512</FileAlignment>
     <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
     <ReleaseVersion>
     </ReleaseVersion>
+    <TargetFrameworkProfile />
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugSymbols>true</DebugSymbols>
@@ -51,9 +52,6 @@
     <Reference Include="Interfaces.IO">
       <HintPath>..\packages\Interfaces.IO.1.0.0.5\lib\portable-net45+sl4+wp71+win8+wpa81\Interfaces.IO.dll</HintPath>
     </Reference>
-    <Reference Include="MoreLinq">
-      <HintPath>..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll</HintPath>
-    </Reference>
     <Reference Include="Patterns.Logging">
       <HintPath>..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll</HintPath>
     </Reference>
@@ -168,7 +166,6 @@
     <Compile Include="Entities\UserView.cs" />
     <Compile Include="Entities\UserViewBuilder.cs" />
     <Compile Include="FileOrganization\IFileOrganizationService.cs" />
-    <Compile Include="Health\IHealthMonitor.cs" />
     <Compile Include="IO\ThrottledStream.cs" />
     <Compile Include="Library\DeleteOptions.cs" />
     <Compile Include="Library\ILibraryPostScanTask.cs" />
@@ -391,6 +388,7 @@
     <Compile Include="Sync\ISyncRepository.cs" />
     <Compile Include="Sync\SyncedFileInfo.cs" />
     <Compile Include="Sync\SyncedItemProgress.cs" />
+    <Compile Include="Threading\PeriodicTimer.cs" />
     <Compile Include="TV\ITVSeriesManager.cs" />
   </ItemGroup>
   <ItemGroup>

+ 1 - 1
MediaBrowser.Common/Threading/PeriodicTimer.cs → MediaBrowser.Controller/Threading/PeriodicTimer.cs

@@ -2,7 +2,7 @@
 using System.Threading;
 using Microsoft.Win32;
 
-namespace MediaBrowser.Common.Threading
+namespace MediaBrowser.Controller.Threading
 {
     public class PeriodicTimer : IDisposable
     {

+ 0 - 1
MediaBrowser.Controller/packages.config

@@ -2,6 +2,5 @@
 <packages>
   <package id="CommonIO" version="1.0.0.9" targetFramework="net45" />
   <package id="Interfaces.IO" version="1.0.0.5" targetFramework="net45" />
-  <package id="morelinq" version="1.4.0" targetFramework="net45" />
   <package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
 </packages>

+ 59 - 30
MediaBrowser.Dlna/DlnaManager.cs

@@ -277,9 +277,27 @@ namespace MediaBrowser.Dlna
         {
             try
             {
-                return _fileSystem.GetFiles(path)
+                var allFiles = _fileSystem.GetFiles(path)
+                    .ToList();
+
+                var xmlFies = allFiles
                     .Where(i => string.Equals(i.Extension, ".xml", StringComparison.OrdinalIgnoreCase))
-                    .Select(i => ParseProfileXmlFile(i.FullName, type))
+                    .ToList();
+
+                var jsonFiles = allFiles
+                    .Where(i => string.Equals(i.Extension, ".json", StringComparison.OrdinalIgnoreCase))
+                    .ToList();
+
+                var jsonFileNames = jsonFiles
+                    .Select(i => Path.GetFileNameWithoutExtension(i.Name))
+                    .ToList();
+
+                var parseFiles = jsonFiles.ToList();
+
+                parseFiles.AddRange(xmlFies.Where(i => !jsonFileNames.Contains(Path.GetFileNameWithoutExtension(i.Name), StringComparer.Ordinal)));
+
+                return parseFiles
+                    .Select(i => ParseProfileFile(i.FullName, type))
                     .Where(i => i != null)
                     .ToList();
             }
@@ -289,7 +307,7 @@ namespace MediaBrowser.Dlna
             }
         }
 
-        private DeviceProfile ParseProfileXmlFile(string path, DeviceProfileType type)
+        private DeviceProfile ParseProfileFile(string path, DeviceProfileType type)
         {
             lock (_profiles)
             {
@@ -301,7 +319,19 @@ namespace MediaBrowser.Dlna
 
                 try
                 {
-                    var profile = (DeviceProfile)_xmlSerializer.DeserializeFromFile(typeof(DeviceProfile), path);
+                    DeviceProfile profile;
+
+                    if (string.Equals(Path.GetExtension(path), ".xml", StringComparison.OrdinalIgnoreCase))
+                    {
+                        var tempProfile = (MediaBrowser.Dlna.ProfileSerialization.DeviceProfile)_xmlSerializer.DeserializeFromFile(typeof(MediaBrowser.Dlna.ProfileSerialization.DeviceProfile), path);
+
+                        var json = _jsonSerializer.SerializeToString(tempProfile);
+                        profile = (DeviceProfile)_jsonSerializer.DeserializeFromString<DeviceProfile>(json);
+                    }
+                    else
+                    {
+                        profile = (DeviceProfile)_jsonSerializer.DeserializeFromFile(typeof(DeviceProfile), path);
+                    }
 
                     profile.Id = path.ToLower().GetMD5().ToString("N");
                     profile.ProfileType = type;
@@ -312,7 +342,7 @@ namespace MediaBrowser.Dlna
                 }
                 catch (Exception ex)
                 {
-                    _logger.ErrorException("Error parsing profile xml: {0}", ex, path);
+                    _logger.ErrorException("Error parsing profile file: {0}", ex, path);
 
                     return null;
                 }
@@ -328,7 +358,7 @@ namespace MediaBrowser.Dlna
 
             var info = GetProfileInfosInternal().First(i => string.Equals(i.Info.Id, id, StringComparison.OrdinalIgnoreCase));
 
-            return ParseProfileXmlFile(info.Path, info.Info.Type);
+            return ParseProfileFile(info.Path, info.Info.Type);
         }
 
         private IEnumerable<InternalProfileInfo> GetProfileInfosInternal()
@@ -348,21 +378,6 @@ namespace MediaBrowser.Dlna
             return GetProfileInfosInternal().Select(i => i.Info);
         }
 
-        private IEnumerable<InternalProfileInfo> GetProfileInfos(string path, DeviceProfileType type)
-        {
-            try
-            {
-                return _fileSystem.GetFiles(path)
-                    .Where(i => string.Equals(i.Extension, ".xml", StringComparison.OrdinalIgnoreCase))
-                    .Select(i => GetInternalProfileInfo(i, type))
-                    .ToList();
-            }
-            catch (DirectoryNotFoundException)
-            {
-                return new List<InternalProfileInfo>();
-            }
-        }
-
         private InternalProfileInfo GetInternalProfileInfo(FileSystemMetadata file, DeviceProfileType type)
         {
             return new InternalProfileInfo
@@ -381,7 +396,7 @@ namespace MediaBrowser.Dlna
         private void ExtractSystemProfiles()
         {
             var assembly = GetType().Assembly;
-            var namespaceName = GetType().Namespace + ".Profiles.Xml.";
+            var namespaceName = GetType().Namespace + ".Profiles.Json.";
 
             var systemProfilesPath = SystemProfilesPath;
 
@@ -439,7 +454,7 @@ namespace MediaBrowser.Dlna
                 throw new ArgumentException("Profile is missing Name");
             }
 
-            var newFilename = _fileSystem.GetValidFilename(profile.Name) + ".xml";
+            var newFilename = _fileSystem.GetValidFilename(profile.Name) + ".json";
             var path = Path.Combine(UserProfilesPath, newFilename);
 
             SaveProfile(profile, path, DeviceProfileType.User);
@@ -460,7 +475,7 @@ namespace MediaBrowser.Dlna
 
             var current = GetProfileInfosInternal().First(i => string.Equals(i.Info.Id, profile.Id, StringComparison.OrdinalIgnoreCase));
 
-            var newFilename = _fileSystem.GetValidFilename(profile.Name) + ".xml";
+            var newFilename = _fileSystem.GetValidFilename(profile.Name) + ".json";
             var path = Path.Combine(UserProfilesPath, newFilename);
 
             if (!string.Equals(path, current.Path, StringComparison.Ordinal) &&
@@ -478,7 +493,21 @@ namespace MediaBrowser.Dlna
             {
                 _profiles[path] = new Tuple<InternalProfileInfo, DeviceProfile>(GetInternalProfileInfo(_fileSystem.GetFileInfo(path), type), profile);
             }
-            _xmlSerializer.SerializeToFile(profile, path);
+            SerializeToJson(profile, path);
+        }
+
+        internal void SerializeToJson(DeviceProfile profile, string path)
+        {
+            _jsonSerializer.SerializeToFile(profile, path);
+
+            try
+            {
+                File.Delete(Path.ChangeExtension(path, ".xml"));
+            }
+            catch
+            {
+
+            }
         }
 
         /// <summary>
@@ -532,14 +561,14 @@ namespace MediaBrowser.Dlna
     class DlnaProfileEntryPoint : IServerEntryPoint
     {
         private readonly IApplicationPaths _appPaths;
-        private readonly IXmlSerializer _xmlSerializer;
+        private readonly IJsonSerializer _jsonSerializer;
         private readonly IFileSystem _fileSystem;
 
-        public DlnaProfileEntryPoint(IApplicationPaths appPaths, IXmlSerializer xmlSerializer, IFileSystem fileSystem)
+        public DlnaProfileEntryPoint(IApplicationPaths appPaths, IFileSystem fileSystem, IJsonSerializer jsonSerializer)
         {
             _appPaths = appPaths;
-            _xmlSerializer = xmlSerializer;
             _fileSystem = fileSystem;
+            _jsonSerializer = jsonSerializer;
         }
 
         public void Run()
@@ -587,9 +616,9 @@ namespace MediaBrowser.Dlna
 
             foreach (var item in list)
             {
-                var path = Path.Combine(_appPaths.ProgramDataPath, _fileSystem.GetValidFilename(item.Name) + ".xml");
+                var path = Path.Combine(_appPaths.ProgramDataPath, _fileSystem.GetValidFilename(item.Name) + ".json");
 
-                _xmlSerializer.SerializeToFile(item, path);
+                _jsonSerializer.SerializeToFile(item, path);
             }
         }
 

+ 42 - 68
MediaBrowser.Dlna/MediaBrowser.Dlna.csproj

@@ -12,7 +12,7 @@
     <FileAlignment>512</FileAlignment>
     <ProductVersion>10.0.0</ProductVersion>
     <SchemaVersion>2.0</SchemaVersion>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
     <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
     <TargetFrameworkProfile />
   </PropertyGroup>
@@ -24,7 +24,6 @@
     <DefineConstants>DEBUG;TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
-    <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
     <DebugType>none</DebugType>
@@ -33,7 +32,6 @@
     <DefineConstants>TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
-    <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release Mono|AnyCPU' ">
     <Optimize>false</Optimize>
@@ -45,9 +43,6 @@
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\packages\CommonIO.1.0.0.9\lib\net45\CommonIO.dll</HintPath>
     </Reference>
-    <Reference Include="MoreLinq">
-      <HintPath>..\packages\morelinq.1.4.0\lib\net35\MoreLinq.dll</HintPath>
-    </Reference>
     <Reference Include="Patterns.Logging">
       <HintPath>..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll</HintPath>
     </Reference>
@@ -96,6 +91,16 @@
     <Compile Include="Common\DeviceService.cs" />
     <Compile Include="Didl\DidlBuilder.cs" />
     <Compile Include="PlayTo\PlayToController.cs" />
+    <Compile Include="ProfileSerialization\CodecProfile.cs" />
+    <Compile Include="ProfileSerialization\ContainerProfile.cs" />
+    <Compile Include="ProfileSerialization\DeviceProfile.cs" />
+    <Compile Include="ProfileSerialization\DirectPlayProfile.cs" />
+    <Compile Include="ProfileSerialization\HttpHeaderInfo.cs" />
+    <Compile Include="ProfileSerialization\ProfileCondition.cs" />
+    <Compile Include="ProfileSerialization\ResponseProfile.cs" />
+    <Compile Include="ProfileSerialization\SubtitleProfile.cs" />
+    <Compile Include="ProfileSerialization\TranscodingProfile.cs" />
+    <Compile Include="ProfileSerialization\XmlAttribute.cs" />
     <Compile Include="Profiles\BubbleUpnpProfile.cs" />
     <Compile Include="Profiles\DefaultProfile.cs" />
     <Compile Include="Profiles\DirectTvProfile.cs" />
@@ -173,55 +178,16 @@
       <Name>MediaBrowser.Model</Name>
     </ProjectReference>
   </ItemGroup>
-  <ItemGroup>
-    <EmbeddedResource Include="Profiles\Xml\Denon AVR.xml" />
-    <EmbeddedResource Include="Profiles\Xml\foobar2000.xml" />
-    <EmbeddedResource Include="Profiles\Xml\LG Smart TV.xml" />
-    <EmbeddedResource Include="Profiles\Xml\Linksys DMA2100.xml" />
-    <EmbeddedResource Include="Profiles\Xml\Panasonic Viera.xml" />
-    <EmbeddedResource Include="Profiles\Xml\Samsung Smart TV.xml" />
-    <EmbeddedResource Include="Profiles\Xml\Sony Blu-ray Player 2013.xml" />
-    <EmbeddedResource Include="Profiles\Xml\Sony Blu-ray Player.xml" />
-    <EmbeddedResource Include="Profiles\Xml\Sony Bravia %282010%29.xml" />
-    <EmbeddedResource Include="Profiles\Xml\Sony Bravia %282011%29.xml" />
-    <EmbeddedResource Include="Profiles\Xml\Sony Bravia %282012%29.xml" />
-    <EmbeddedResource Include="Profiles\Xml\Sony Bravia %282013%29.xml">
-      <SubType>Designer</SubType>
-    </EmbeddedResource>
-    <EmbeddedResource Include="Profiles\Xml\Sony PlayStation 3.xml" />
-    <EmbeddedResource Include="Profiles\Xml\WDTV Live.xml" />
-    <EmbeddedResource Include="Profiles\Xml\Xbox 360.xml">
-      <SubType>Designer</SubType>
-    </EmbeddedResource>
-    <EmbeddedResource Include="Profiles\Xml\Xbox One.xml" />
-  </ItemGroup>
-  <ItemGroup>
-    <EmbeddedResource Include="Profiles\Xml\Default.xml">
-      <SubType>Designer</SubType>
-    </EmbeddedResource>
-  </ItemGroup>
   <ItemGroup>
     <EmbeddedResource Include="Images\logo120.jpg" />
     <EmbeddedResource Include="Images\logo120.png" />
     <EmbeddedResource Include="Images\logo48.jpg" />
     <EmbeddedResource Include="Images\logo48.png" />
   </ItemGroup>
-  <ItemGroup>
-    <EmbeddedResource Include="Profiles\Xml\MediaMonkey.xml" />
-  </ItemGroup>
   <ItemGroup>
     <EmbeddedResource Include="Images\logo240.jpg" />
     <EmbeddedResource Include="Images\logo240.png" />
   </ItemGroup>
-  <ItemGroup>
-    <EmbeddedResource Include="Profiles\Xml\DirecTV HD-DVR.xml" />
-  </ItemGroup>
-  <ItemGroup>
-    <EmbeddedResource Include="Profiles\Xml\Dish Hopper-Joey.xml" />
-  </ItemGroup>
-  <ItemGroup>
-    <EmbeddedResource Include="Profiles\Xml\Popcorn Hour.xml" />
-  </ItemGroup>
   <ItemGroup>
     <EmbeddedResource Include="Images\people48.jpg" />
     <EmbeddedResource Include="Images\people48.png" />
@@ -230,31 +196,39 @@
     <EmbeddedResource Include="Images\people480.jpg" />
     <EmbeddedResource Include="Images\people480.png" />
   </ItemGroup>
-  <ItemGroup>
-    <EmbeddedResource Include="Profiles\Xml\BubbleUPnp.xml" />
-    <EmbeddedResource Include="Profiles\Xml\Vlc.xml" />
-  </ItemGroup>
-  <ItemGroup>
-    <EmbeddedResource Include="Profiles\Xml\Sony PlayStation 4.xml" />
-  </ItemGroup>
-  <ItemGroup>
-    <EmbeddedResource Include="Profiles\Xml\Kodi.xml">
-      <SubType>Designer</SubType>
-    </EmbeddedResource>
-  </ItemGroup>
-  <ItemGroup>
-    <EmbeddedResource Include="Profiles\Xml\Sony Bravia %282014%29.xml">
-      <SubType>Designer</SubType>
-    </EmbeddedResource>
-  </ItemGroup>
   <ItemGroup>
     <None Include="packages.config" />
-  </ItemGroup>
-  <ItemGroup>
-    <EmbeddedResource Include="Profiles\Xml\Sony Blu-ray Player 2014.xml" />
-    <EmbeddedResource Include="Profiles\Xml\Sony Blu-ray Player 2015.xml" />
-    <EmbeddedResource Include="Profiles\Xml\Sony Blu-ray Player 2016.xml" />
-  </ItemGroup>
+    <EmbeddedResource Include="Profiles\Json\BubbleUPnp.json" />
+    <EmbeddedResource Include="Profiles\Json\Default.json" />
+    <EmbeddedResource Include="Profiles\Json\Denon AVR.json" />
+    <EmbeddedResource Include="Profiles\Json\DirecTV HD-DVR.json" />
+    <EmbeddedResource Include="Profiles\Json\Dish Hopper-Joey.json" />
+    <EmbeddedResource Include="Profiles\Json\foobar2000.json" />
+    <EmbeddedResource Include="Profiles\Json\Kodi.json" />
+    <EmbeddedResource Include="Profiles\Json\LG Smart TV.json" />
+    <EmbeddedResource Include="Profiles\Json\Linksys DMA2100.json" />
+    <EmbeddedResource Include="Profiles\Json\MediaMonkey.json" />
+    <EmbeddedResource Include="Profiles\Json\Panasonic Viera.json" />
+    <EmbeddedResource Include="Profiles\Json\Popcorn Hour.json" />
+    <EmbeddedResource Include="Profiles\Json\Samsung Smart TV.json" />
+    <EmbeddedResource Include="Profiles\Json\Sony Blu-ray Player 2013.json" />
+    <EmbeddedResource Include="Profiles\Json\Sony Blu-ray Player 2014.json" />
+    <EmbeddedResource Include="Profiles\Json\Sony Blu-ray Player 2015.json" />
+    <EmbeddedResource Include="Profiles\Json\Sony Blu-ray Player 2016.json" />
+    <EmbeddedResource Include="Profiles\Json\Sony Blu-ray Player.json" />
+    <EmbeddedResource Include="Profiles\Json\Sony Bravia %282010%29.json" />
+    <EmbeddedResource Include="Profiles\Json\Sony Bravia %282011%29.json" />
+    <EmbeddedResource Include="Profiles\Json\Sony Bravia %282012%29.json" />
+    <EmbeddedResource Include="Profiles\Json\Sony Bravia %282013%29.json" />
+    <EmbeddedResource Include="Profiles\Json\Sony Bravia %282014%29.json" />
+    <EmbeddedResource Include="Profiles\Json\Sony PlayStation 3.json" />
+    <EmbeddedResource Include="Profiles\Json\Sony PlayStation 4.json" />
+    <EmbeddedResource Include="Profiles\Json\Vlc.json" />
+    <EmbeddedResource Include="Profiles\Json\WDTV Live.json" />
+    <EmbeddedResource Include="Profiles\Json\Xbox 360.json" />
+    <EmbeddedResource Include="Profiles\Json\Xbox One.json" />
+  </ItemGroup>
+  <ItemGroup />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.

+ 68 - 0
MediaBrowser.Dlna/ProfileSerialization/CodecProfile.cs

@@ -0,0 +1,68 @@
+using MediaBrowser.Model.Extensions;
+using System.Collections.Generic;
+using System.Xml.Serialization;
+using MediaBrowser.Model.Dlna;
+
+namespace MediaBrowser.Dlna.ProfileSerialization
+{
+    public class CodecProfile
+    {
+        [XmlAttribute("type")]
+        public CodecType Type { get; set; }
+       
+        public ProfileCondition[] Conditions { get; set; }
+
+        public ProfileCondition[] ApplyConditions { get; set; }
+
+        [XmlAttribute("codec")]
+        public string Codec { get; set; }
+
+        [XmlAttribute("container")]
+        public string Container { get; set; }
+
+        public CodecProfile()
+        {
+            Conditions = new ProfileCondition[] {};
+            ApplyConditions = new ProfileCondition[] { };
+        }
+
+        public List<string> GetCodecs()
+        {
+            List<string> list = new List<string>();
+            foreach (string i in (Codec ?? string.Empty).Split(','))
+            {
+                if (!string.IsNullOrEmpty(i)) list.Add(i);
+            }
+            return list;
+        }
+
+        public List<string> GetContainers()
+        {
+            List<string> list = new List<string>();
+            foreach (string i in (Container ?? string.Empty).Split(','))
+            {
+                if (!string.IsNullOrEmpty(i)) list.Add(i);
+            }
+            return list;
+        }
+
+        private bool ContainsContainer(string container)
+        {
+            List<string> containers = GetContainers();
+
+            return containers.Count == 0 || ListHelper.ContainsIgnoreCase(containers, container ?? string.Empty);
+        }
+
+        public bool ContainsCodec(string codec, string container)
+        {
+            if (!ContainsContainer(container))
+            {
+                return false;
+            }
+
+            List<string> codecs = GetCodecs();
+
+            return codecs.Count == 0 || ListHelper.ContainsIgnoreCase(codecs, codec);
+        }
+    }
+}

+ 31 - 0
MediaBrowser.Dlna/ProfileSerialization/ContainerProfile.cs

@@ -0,0 +1,31 @@
+using System.Collections.Generic;
+using System.Xml.Serialization;
+using MediaBrowser.Model.Dlna;
+
+namespace MediaBrowser.Dlna.ProfileSerialization
+{
+    public class ContainerProfile
+    {
+        [XmlAttribute("type")]
+        public DlnaProfileType Type { get; set; }
+        public ProfileCondition[] Conditions { get; set; }
+
+        [XmlAttribute("container")]
+        public string Container { get; set; }
+
+        public ContainerProfile()
+        {
+            Conditions = new ProfileCondition[] { };
+        }
+
+        public List<string> GetContainers()
+        {
+            List<string> list = new List<string>();
+            foreach (string i in (Container ?? string.Empty).Split(','))
+            {
+                if (!string.IsNullOrEmpty(i)) list.Add(i);
+            }
+            return list;
+        }
+    }
+}

+ 351 - 0
MediaBrowser.Dlna/ProfileSerialization/DeviceProfile.cs

@@ -0,0 +1,351 @@
+using MediaBrowser.Model.Extensions;
+using MediaBrowser.Model.MediaInfo;
+using System.Collections.Generic;
+using System.Xml.Serialization;
+
+namespace MediaBrowser.Dlna.ProfileSerialization
+{
+    [XmlRoot("Profile")]
+    public class DeviceProfile
+    {
+        /// <summary>
+        /// Gets or sets the name.
+        /// </summary>
+        /// <value>The name.</value>
+        public string Name { get; set; }
+
+        [XmlIgnore]
+        public string Id { get; set; }
+
+        [XmlIgnore]
+        public MediaBrowser.Model.Dlna.DeviceProfileType ProfileType { get; set; }
+
+        /// <summary>
+        /// Gets or sets the identification.
+        /// </summary>
+        /// <value>The identification.</value>
+        public MediaBrowser.Model.Dlna.DeviceIdentification Identification { get; set; }
+
+        public string FriendlyName { get; set; }
+        public string Manufacturer { get; set; }
+        public string ManufacturerUrl { get; set; }
+        public string ModelName { get; set; }
+        public string ModelDescription { get; set; }
+        public string ModelNumber { get; set; }
+        public string ModelUrl { get; set; }
+        public string SerialNumber { get; set; }
+
+        public bool EnableAlbumArtInDidl { get; set; }
+        public bool EnableSingleAlbumArtLimit { get; set; }
+        public bool EnableSingleSubtitleLimit { get; set; }
+
+        public string SupportedMediaTypes { get; set; }
+
+        public string UserId { get; set; }
+
+        public string AlbumArtPn { get; set; }
+
+        public int MaxAlbumArtWidth { get; set; }
+        public int MaxAlbumArtHeight { get; set; }
+
+        public int? MaxIconWidth { get; set; }
+        public int? MaxIconHeight { get; set; }
+
+        public int? MaxStreamingBitrate { get; set; }
+        public int? MaxStaticBitrate { get; set; }
+
+        public int? MusicStreamingTranscodingBitrate { get; set; }
+        public int? MaxStaticMusicBitrate { get; set; }
+
+        /// <summary>
+        /// Controls the content of the X_DLNADOC element in the urn:schemas-dlna-org:device-1-0 namespace.
+        /// </summary>
+        public string XDlnaDoc { get; set; }
+        /// <summary>
+        /// Controls the content of the X_DLNACAP element in the urn:schemas-dlna-org:device-1-0 namespace.
+        /// </summary>
+        public string XDlnaCap { get; set; }
+        /// <summary>
+        /// Controls the content of the aggregationFlags element in the urn:schemas-sonycom:av namespace.
+        /// </summary>
+        public string SonyAggregationFlags { get; set; }
+
+        public string ProtocolInfo { get; set; }
+
+        public int TimelineOffsetSeconds { get; set; }
+        public bool RequiresPlainVideoItems { get; set; }
+        public bool RequiresPlainFolders { get; set; }
+
+        public bool EnableMSMediaReceiverRegistrar { get; set; }
+        public bool IgnoreTranscodeByteRangeRequests { get; set; }
+
+        public XmlAttribute[] XmlRootAttributes { get; set; }
+
+        /// <summary>
+        /// Gets or sets the direct play profiles.
+        /// </summary>
+        /// <value>The direct play profiles.</value>
+        public DirectPlayProfile[] DirectPlayProfiles { get; set; }
+
+        /// <summary>
+        /// Gets or sets the transcoding profiles.
+        /// </summary>
+        /// <value>The transcoding profiles.</value>
+        public TranscodingProfile[] TranscodingProfiles { get; set; }
+
+        public ContainerProfile[] ContainerProfiles { get; set; }
+
+        public CodecProfile[] CodecProfiles { get; set; }
+        public ResponseProfile[] ResponseProfiles { get; set; }
+
+        public SubtitleProfile[] SubtitleProfiles { get; set; }
+
+        public DeviceProfile()
+        {
+            DirectPlayProfiles = new DirectPlayProfile[] { };
+            TranscodingProfiles = new TranscodingProfile[] { };
+            ResponseProfiles = new ResponseProfile[] { };
+            CodecProfiles = new CodecProfile[] { };
+            ContainerProfiles = new ContainerProfile[] { };
+            SubtitleProfiles = new SubtitleProfile[] { };
+
+            XmlRootAttributes = new XmlAttribute[] { };
+
+            SupportedMediaTypes = "Audio,Photo,Video";
+            MaxStreamingBitrate = 8000000;
+            MaxStaticBitrate = 8000000;
+            MusicStreamingTranscodingBitrate = 128000;
+        }
+
+        public List<string> GetSupportedMediaTypes()
+        {
+            List<string> list = new List<string>();
+            foreach (string i in (SupportedMediaTypes ?? string.Empty).Split(','))
+            {
+                if (!string.IsNullOrEmpty(i))
+                    list.Add(i);
+            }
+            return list;
+        }
+
+        public TranscodingProfile GetAudioTranscodingProfile(string container, string audioCodec)
+        {
+            container = StringHelper.TrimStart(container ?? string.Empty, '.');
+
+            foreach (var i in TranscodingProfiles)
+            {
+                if (i.Type != MediaBrowser.Model.Dlna.DlnaProfileType.Audio)
+                {
+                    continue;
+                }
+
+                if (!StringHelper.EqualsIgnoreCase(container, i.Container))
+                {
+                    continue;
+                }
+
+                if (!ListHelper.ContainsIgnoreCase(i.GetAudioCodecs(), audioCodec ?? string.Empty))
+                {
+                    continue;
+                }
+
+                return i;
+            }
+            return null;
+        }
+
+        public TranscodingProfile GetVideoTranscodingProfile(string container, string audioCodec, string videoCodec)
+        {
+            container = StringHelper.TrimStart(container ?? string.Empty, '.');
+
+            foreach (var i in TranscodingProfiles)
+            {
+                if (i.Type != MediaBrowser.Model.Dlna.DlnaProfileType.Video)
+                {
+                    continue;
+                }
+
+                if (!StringHelper.EqualsIgnoreCase(container, i.Container))
+                {
+                    continue;
+                }
+
+                if (!ListHelper.ContainsIgnoreCase(i.GetAudioCodecs(), audioCodec ?? string.Empty))
+                {
+                    continue;
+                }
+
+                if (!StringHelper.EqualsIgnoreCase(videoCodec, i.VideoCodec ?? string.Empty))
+                {
+                    continue;
+                }
+
+                return i;
+            }
+            return null;
+        }
+
+        public ResponseProfile GetAudioMediaProfile(string container, string audioCodec, int? audioChannels, int? audioBitrate)
+        {
+            container = StringHelper.TrimStart(container ?? string.Empty, '.');
+
+            foreach (var i in ResponseProfiles)
+            {
+                if (i.Type != MediaBrowser.Model.Dlna.DlnaProfileType.Audio)
+                {
+                    continue;
+                }
+
+                List<string> containers = i.GetContainers();
+                if (containers.Count > 0 && !ListHelper.ContainsIgnoreCase(containers, container))
+                {
+                    continue;
+                }
+
+                List<string> audioCodecs = i.GetAudioCodecs();
+                if (audioCodecs.Count > 0 && !ListHelper.ContainsIgnoreCase(audioCodecs, audioCodec ?? string.Empty))
+                {
+                    continue;
+                }
+
+                var conditionProcessor = new MediaBrowser.Model.Dlna.ConditionProcessor();
+
+                var anyOff = false;
+                foreach (ProfileCondition c in i.Conditions)
+                {
+                    if (!conditionProcessor.IsAudioConditionSatisfied(GetModelProfileCondition(c), audioChannels, audioBitrate))
+                    {
+                        anyOff = true;
+                        break;
+                    }
+                }
+
+                if (anyOff)
+                {
+                    continue;
+                }
+
+                return i;
+            }
+            return null;
+        }
+
+        private MediaBrowser.Model.Dlna.ProfileCondition GetModelProfileCondition(ProfileCondition c)
+        {
+            return new Model.Dlna.ProfileCondition
+            {
+                Condition = c.Condition,
+                IsRequired = c.IsRequired,
+                Property = c.Property,
+                Value = c.Value
+            };
+        }
+
+        public ResponseProfile GetImageMediaProfile(string container, int? width, int? height)
+        {
+            container = StringHelper.TrimStart(container ?? string.Empty, '.');
+
+            foreach (var i in ResponseProfiles)
+            {
+                if (i.Type != MediaBrowser.Model.Dlna.DlnaProfileType.Photo)
+                {
+                    continue;
+                }
+
+                List<string> containers = i.GetContainers();
+                if (containers.Count > 0 && !ListHelper.ContainsIgnoreCase(containers, container))
+                {
+                    continue;
+                }
+
+                var conditionProcessor = new MediaBrowser.Model.Dlna.ConditionProcessor();
+
+                var anyOff = false;
+                foreach (ProfileCondition c in i.Conditions)
+                {
+                    if (!conditionProcessor.IsImageConditionSatisfied(GetModelProfileCondition(c), width, height))
+                    {
+                        anyOff = true;
+                        break;
+                    }
+                }
+
+                if (anyOff)
+                {
+                    continue;
+                }
+
+                return i;
+            }
+            return null;
+        }
+
+        public ResponseProfile GetVideoMediaProfile(string container,
+            string audioCodec,
+            string videoCodec,
+            int? width,
+            int? height,
+            int? bitDepth,
+            int? videoBitrate,
+            string videoProfile,
+            double? videoLevel,
+            float? videoFramerate,
+            int? packetLength,
+            TransportStreamTimestamp timestamp,
+            bool? isAnamorphic,
+            int? refFrames,
+            int? numVideoStreams,
+            int? numAudioStreams,
+            string videoCodecTag,
+            bool? isAvc)
+        {
+            container = StringHelper.TrimStart(container ?? string.Empty, '.');
+
+            foreach (var i in ResponseProfiles)
+            {
+                if (i.Type != MediaBrowser.Model.Dlna.DlnaProfileType.Video)
+                {
+                    continue;
+                }
+
+                List<string> containers = i.GetContainers();
+                if (containers.Count > 0 && !ListHelper.ContainsIgnoreCase(containers, container ?? string.Empty))
+                {
+                    continue;
+                }
+
+                List<string> audioCodecs = i.GetAudioCodecs();
+                if (audioCodecs.Count > 0 && !ListHelper.ContainsIgnoreCase(audioCodecs, audioCodec ?? string.Empty))
+                {
+                    continue;
+                }
+
+                List<string> videoCodecs = i.GetVideoCodecs();
+                if (videoCodecs.Count > 0 && !ListHelper.ContainsIgnoreCase(videoCodecs, videoCodec ?? string.Empty))
+                {
+                    continue;
+                }
+
+                var conditionProcessor = new MediaBrowser.Model.Dlna.ConditionProcessor();
+
+                var anyOff = false;
+                foreach (ProfileCondition c in i.Conditions)
+                {
+                    if (!conditionProcessor.IsVideoConditionSatisfied(GetModelProfileCondition(c), width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc))
+                    {
+                        anyOff = true;
+                        break;
+                    }
+                }
+
+                if (anyOff)
+                {
+                    continue;
+                }
+
+                return i;
+            }
+            return null;
+        }
+    }
+}

+ 51 - 0
MediaBrowser.Dlna/ProfileSerialization/DirectPlayProfile.cs

@@ -0,0 +1,51 @@
+using System.Collections.Generic;
+using System.Xml.Serialization;
+using MediaBrowser.Model.Dlna;
+
+namespace MediaBrowser.Dlna.ProfileSerialization
+{
+    public class DirectPlayProfile
+    {
+        [XmlAttribute("container")]
+        public string Container { get; set; }
+
+        [XmlAttribute("audioCodec")]
+        public string AudioCodec { get; set; }
+
+        [XmlAttribute("videoCodec")]
+        public string VideoCodec { get; set; }
+
+        [XmlAttribute("type")]
+        public DlnaProfileType Type { get; set; }
+
+        public List<string> GetContainers()
+        {
+            List<string> list = new List<string>();
+            foreach (string i in (Container ?? string.Empty).Split(','))
+            {
+                if (!string.IsNullOrEmpty(i)) list.Add(i);
+            }
+            return list;
+        }
+
+        public List<string> GetAudioCodecs()
+        {
+            List<string> list = new List<string>();
+            foreach (string i in (AudioCodec ?? string.Empty).Split(','))
+            {
+                if (!string.IsNullOrEmpty(i)) list.Add(i);
+            }
+            return list;
+        }
+
+        public List<string> GetVideoCodecs()
+        {
+            List<string> list = new List<string>();
+            foreach (string i in (VideoCodec ?? string.Empty).Split(','))
+            {
+                if (!string.IsNullOrEmpty(i)) list.Add(i);
+            }
+            return list;
+        }
+    }
+}

+ 17 - 0
MediaBrowser.Dlna/ProfileSerialization/HttpHeaderInfo.cs

@@ -0,0 +1,17 @@
+using System.Xml.Serialization;
+using MediaBrowser.Model.Dlna;
+
+namespace MediaBrowser.Dlna.ProfileSerialization
+{
+    public class HttpHeaderInfo
+    {
+        [XmlAttribute("name")]
+        public string Name { get; set; }
+
+        [XmlAttribute("value")]
+        public string Value { get; set; }
+
+        [XmlAttribute("match")]
+        public HeaderMatchType Match { get; set; }
+    }
+}

+ 39 - 0
MediaBrowser.Dlna/ProfileSerialization/ProfileCondition.cs

@@ -0,0 +1,39 @@
+using System.Xml.Serialization;
+using MediaBrowser.Model.Dlna;
+
+namespace MediaBrowser.Dlna.ProfileSerialization
+{
+    public class ProfileCondition
+    {
+        [XmlAttribute("condition")]
+        public ProfileConditionType Condition { get; set; }
+
+        [XmlAttribute("property")]
+        public ProfileConditionValue Property { get; set; }
+
+        [XmlAttribute("value")]
+        public string Value { get; set; }
+
+        [XmlAttribute("isRequired")]
+        public bool IsRequired { get; set; }
+
+        public ProfileCondition()
+        {
+            IsRequired = true;
+        }
+
+        public ProfileCondition(ProfileConditionType condition, ProfileConditionValue property, string value)
+            : this(condition, property, value, false)
+        {
+            
+        }
+
+        public ProfileCondition(ProfileConditionType condition, ProfileConditionValue property, string value, bool isRequired)
+        {
+            Condition = condition;
+            Property = property;
+            Value = value;
+            IsRequired = isRequired;
+        }
+    }
+}

+ 64 - 0
MediaBrowser.Dlna/ProfileSerialization/ResponseProfile.cs

@@ -0,0 +1,64 @@
+using System.Collections.Generic;
+using System.Xml.Serialization;
+using MediaBrowser.Model.Dlna;
+
+namespace MediaBrowser.Dlna.ProfileSerialization
+{
+    public class ResponseProfile
+    {
+        [XmlAttribute("container")]
+        public string Container { get; set; }
+
+        [XmlAttribute("audioCodec")]
+        public string AudioCodec { get; set; }
+
+        [XmlAttribute("videoCodec")]
+        public string VideoCodec { get; set; }
+
+        [XmlAttribute("type")]
+        public DlnaProfileType Type { get; set; }
+
+        [XmlAttribute("orgPn")]
+        public string OrgPn { get; set; }
+
+        [XmlAttribute("mimeType")]
+        public string MimeType { get; set; }
+
+        public ProfileCondition[] Conditions { get; set; }
+
+        public ResponseProfile()
+        {
+            Conditions = new ProfileCondition[] {};
+        }
+
+        public List<string> GetContainers()
+        {
+            List<string> list = new List<string>();
+            foreach (string i in (Container ?? string.Empty).Split(','))
+            {
+                if (!string.IsNullOrEmpty(i)) list.Add(i);
+            }
+            return list;
+        }
+
+        public List<string> GetAudioCodecs()
+        {
+            List<string> list = new List<string>();
+            foreach (string i in (AudioCodec ?? string.Empty).Split(','))
+            {
+                if (!string.IsNullOrEmpty(i)) list.Add(i);
+            }
+            return list;
+        }
+
+        public List<string> GetVideoCodecs()
+        {
+            List<string> list = new List<string>();
+            foreach (string i in (VideoCodec ?? string.Empty).Split(','))
+            {
+                if (!string.IsNullOrEmpty(i)) list.Add(i);
+            }
+            return list;
+        }
+    }
+}

+ 48 - 0
MediaBrowser.Dlna/ProfileSerialization/SubtitleProfile.cs

@@ -0,0 +1,48 @@
+using MediaBrowser.Model.Extensions;
+using System.Collections.Generic;
+using System.Xml.Serialization;
+using MediaBrowser.Model.Dlna;
+
+namespace MediaBrowser.Dlna.ProfileSerialization
+{
+    public class SubtitleProfile
+    {
+        [XmlAttribute("format")]
+        public string Format { get; set; }
+
+        [XmlAttribute("method")]
+        public SubtitleDeliveryMethod Method { get; set; }
+
+        [XmlAttribute("didlMode")]
+        public string DidlMode { get; set; }
+
+        [XmlAttribute("language")]
+        public string Language { get; set; }
+
+        public List<string> GetLanguages()
+        {
+            List<string> list = new List<string>();
+            foreach (string i in (Language ?? string.Empty).Split(','))
+            {
+                if (!string.IsNullOrEmpty(i)) list.Add(i);
+            }
+            return list;
+        }
+
+        public bool SupportsLanguage(string subLanguage)
+        {
+            if (string.IsNullOrEmpty(Language))
+            {
+                return true;
+            }
+
+            if (string.IsNullOrEmpty(subLanguage))
+            {
+                subLanguage = "und";
+            }
+
+            List<string> languages = GetLanguages();
+            return languages.Count == 0 || ListHelper.ContainsIgnoreCase(languages, subLanguage);
+        }
+    }
+}

+ 58 - 0
MediaBrowser.Dlna/ProfileSerialization/TranscodingProfile.cs

@@ -0,0 +1,58 @@
+using System.Collections.Generic;
+using System.Xml.Serialization;
+using MediaBrowser.Model.Dlna;
+
+namespace MediaBrowser.Dlna.ProfileSerialization
+{
+    public class TranscodingProfile
+    {
+        [XmlAttribute("container")]
+        public string Container { get; set; }
+
+        [XmlAttribute("type")]
+        public DlnaProfileType Type { get; set; }
+
+        [XmlAttribute("videoCodec")]
+        public string VideoCodec { get; set; }
+
+        [XmlAttribute("audioCodec")]
+        public string AudioCodec { get; set; }
+
+        [XmlAttribute("protocol")]
+        public string Protocol { get; set; }
+
+        [XmlAttribute("estimateContentLength")]
+        public bool EstimateContentLength { get; set; }
+
+        [XmlAttribute("enableMpegtsM2TsMode")]
+        public bool EnableMpegtsM2TsMode { get; set; }
+
+        [XmlAttribute("transcodeSeekInfo")]
+        public TranscodeSeekInfo TranscodeSeekInfo { get; set; }
+
+        [XmlAttribute("copyTimestamps")]
+        public bool CopyTimestamps { get; set; }
+
+        [XmlAttribute("context")]
+        public EncodingContext Context { get; set; }
+
+        [XmlAttribute("enableSubtitlesInManifest")]
+        public bool EnableSubtitlesInManifest { get; set; }
+
+        [XmlAttribute("enableSplittingOnNonKeyFrames")]
+        public bool EnableSplittingOnNonKeyFrames { get; set; }
+
+        [XmlAttribute("maxAudioChannels")]
+        public string MaxAudioChannels { get; set; }
+
+        public List<string> GetAudioCodecs()
+        {
+            List<string> list = new List<string>();
+            foreach (string i in (AudioCodec ?? string.Empty).Split(','))
+            {
+                if (!string.IsNullOrEmpty(i)) list.Add(i);
+            }
+            return list;
+        }
+    }
+}

+ 13 - 0
MediaBrowser.Dlna/ProfileSerialization/XmlAttribute.cs

@@ -0,0 +1,13 @@
+using System.Xml.Serialization;
+
+namespace MediaBrowser.Dlna.ProfileSerialization
+{
+    public class XmlAttribute
+    {
+        [XmlAttribute("name")]
+        public string Name { get; set; }
+
+        [XmlAttribute("value")]
+        public string Value { get; set; }
+    }
+}

File diff suppressed because it is too large
+ 0 - 0
MediaBrowser.Dlna/Profiles/Json/BubbleUPnp.json


File diff suppressed because it is too large
+ 0 - 0
MediaBrowser.Dlna/Profiles/Json/Default.json


File diff suppressed because it is too large
+ 0 - 0
MediaBrowser.Dlna/Profiles/Json/Denon AVR.json


File diff suppressed because it is too large
+ 0 - 0
MediaBrowser.Dlna/Profiles/Json/DirecTV HD-DVR.json


File diff suppressed because it is too large
+ 0 - 0
MediaBrowser.Dlna/Profiles/Json/Dish Hopper-Joey.json


File diff suppressed because it is too large
+ 0 - 0
MediaBrowser.Dlna/Profiles/Json/Kodi.json


File diff suppressed because it is too large
+ 0 - 0
MediaBrowser.Dlna/Profiles/Json/LG Smart TV.json


File diff suppressed because it is too large
+ 0 - 0
MediaBrowser.Dlna/Profiles/Json/Linksys DMA2100.json


File diff suppressed because it is too large
+ 0 - 0
MediaBrowser.Dlna/Profiles/Json/MediaMonkey.json


File diff suppressed because it is too large
+ 0 - 0
MediaBrowser.Dlna/Profiles/Json/Panasonic Viera.json


File diff suppressed because it is too large
+ 0 - 0
MediaBrowser.Dlna/Profiles/Json/Popcorn Hour.json


File diff suppressed because it is too large
+ 0 - 0
MediaBrowser.Dlna/Profiles/Json/Samsung Smart TV.json


File diff suppressed because it is too large
+ 0 - 0
MediaBrowser.Dlna/Profiles/Json/Sony Blu-ray Player 2013.json


File diff suppressed because it is too large
+ 0 - 0
MediaBrowser.Dlna/Profiles/Json/Sony Blu-ray Player 2014.json


File diff suppressed because it is too large
+ 0 - 0
MediaBrowser.Dlna/Profiles/Json/Sony Blu-ray Player 2015.json


File diff suppressed because it is too large
+ 0 - 0
MediaBrowser.Dlna/Profiles/Json/Sony Blu-ray Player 2016.json


File diff suppressed because it is too large
+ 0 - 0
MediaBrowser.Dlna/Profiles/Json/Sony Blu-ray Player.json


File diff suppressed because it is too large
+ 0 - 0
MediaBrowser.Dlna/Profiles/Json/Sony Bravia (2010).json


File diff suppressed because it is too large
+ 0 - 0
MediaBrowser.Dlna/Profiles/Json/Sony Bravia (2011).json


File diff suppressed because it is too large
+ 0 - 0
MediaBrowser.Dlna/Profiles/Json/Sony Bravia (2012).json


File diff suppressed because it is too large
+ 0 - 0
MediaBrowser.Dlna/Profiles/Json/Sony Bravia (2013).json


File diff suppressed because it is too large
+ 0 - 0
MediaBrowser.Dlna/Profiles/Json/Sony Bravia (2014).json


File diff suppressed because it is too large
+ 0 - 0
MediaBrowser.Dlna/Profiles/Json/Sony PlayStation 3.json


File diff suppressed because it is too large
+ 0 - 0
MediaBrowser.Dlna/Profiles/Json/Sony PlayStation 4.json


File diff suppressed because it is too large
+ 0 - 0
MediaBrowser.Dlna/Profiles/Json/Vlc.json


File diff suppressed because it is too large
+ 0 - 0
MediaBrowser.Dlna/Profiles/Json/WDTV Live.json


File diff suppressed because it is too large
+ 0 - 0
MediaBrowser.Dlna/Profiles/Json/Xbox 360.json


File diff suppressed because it is too large
+ 0 - 0
MediaBrowser.Dlna/Profiles/Json/Xbox One.json


File diff suppressed because it is too large
+ 0 - 0
MediaBrowser.Dlna/Profiles/Json/foobar2000.json


File diff suppressed because it is too large
+ 0 - 29
MediaBrowser.Dlna/Profiles/Xml/BubbleUPnp.xml


File diff suppressed because it is too large
+ 0 - 23
MediaBrowser.Dlna/Profiles/Xml/Default.xml


File diff suppressed because it is too large
+ 0 - 28
MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml


File diff suppressed because it is too large
+ 0 - 29
MediaBrowser.Dlna/Profiles/Xml/DirecTV HD-DVR.xml


+ 0 - 92
MediaBrowser.Dlna/Profiles/Xml/Dish Hopper-Joey.xml

@@ -1,92 +0,0 @@
-<?xml version="1.0"?>
-<Profile xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-  <Name>Dish Hopper-Joey</Name>
-  <Identification>
-    <Manufacturer>Echostar Technologies LLC</Manufacturer>
-    <ManufacturerUrl>http://www.echostar.com</ManufacturerUrl>
-    <Headers>
-      <HttpHeaderInfo name="User-Agent" value="XiP" match="Substring" />
-    </Headers>
-  </Identification>
-  <Manufacturer>Emby</Manufacturer>
-  <ManufacturerUrl>http://emby.media/</ManufacturerUrl>
-  <ModelName>Emby Server</ModelName>
-  <ModelDescription>Emby</ModelDescription>
-  <ModelNumber>Emby</ModelNumber>
-  <ModelUrl>http://emby.media/</ModelUrl>
-  <EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
-  <EnableSingleAlbumArtLimit>false</EnableSingleAlbumArtLimit>
-  <EnableSingleSubtitleLimit>false</EnableSingleSubtitleLimit>
-  <SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
-  <AlbumArtPn>JPEG_SM</AlbumArtPn>
-  <MaxAlbumArtWidth>480</MaxAlbumArtWidth>
-  <MaxAlbumArtHeight>480</MaxAlbumArtHeight>
-  <MaxIconWidth>48</MaxIconWidth>
-  <MaxIconHeight>48</MaxIconHeight>
-  <MaxStreamingBitrate>20000000</MaxStreamingBitrate>
-  <MaxStaticBitrate>20000000</MaxStaticBitrate>
-  <MusicStreamingTranscodingBitrate>192000</MusicStreamingTranscodingBitrate>
-  <MaxStaticMusicBitrate xsi:nil="true" />
-  <XDlnaDoc>DMS-1.50</XDlnaDoc>
-  <ProtocolInfo>http-get:*:video/mp2t:*,http-get:*:video/MP1S:*,http-get:*:video/mpeg2:*,http-get:*:video/mp4:*,http-get:*:video/x-matroska:*,http-get:*:audio/mpeg:*,http-get:*:audio/mpeg3:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/mp4a-latm:*,http-get:*:image/jpeg:*</ProtocolInfo>
-  <TimelineOffsetSeconds>0</TimelineOffsetSeconds>
-  <RequiresPlainVideoItems>false</RequiresPlainVideoItems>
-  <RequiresPlainFolders>false</RequiresPlainFolders>
-  <EnableMSMediaReceiverRegistrar>false</EnableMSMediaReceiverRegistrar>
-  <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
-  <XmlRootAttributes />
-  <DirectPlayProfiles>
-    <DirectPlayProfile container="mp4,mkv,mpeg,ts" audioCodec="mp3,ac3,aac,he-aac,pcm" videoCodec="h264,mpeg2video" type="Video" />
-    <DirectPlayProfile container="mp3" audioCodec="mp3" type="Audio" />
-    <DirectPlayProfile container="alac" audioCodec="alac" type="Audio" />
-    <DirectPlayProfile container="flac" audioCodec="flac" type="Audio" />
-    <DirectPlayProfile container="jpeg" type="Photo" />
-  </DirectPlayProfiles>
-  <TranscodingProfiles>
-    <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" enableSubtitlesInManifest="false" />
-    <TranscodingProfile container="mp4" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" enableSubtitlesInManifest="false" />
-    <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" enableSubtitlesInManifest="false" />
-  </TranscodingProfiles>
-  <ContainerProfiles />
-  <CodecProfiles>
-    <CodecProfile type="Video" codec="h264">
-      <Conditions>
-        <ProfileCondition condition="LessThanEqual" property="Width" value="1920" isRequired="true" />
-        <ProfileCondition condition="LessThanEqual" property="Height" value="1080" isRequired="true" />
-        <ProfileCondition condition="LessThanEqual" property="VideoFramerate" value="30" isRequired="true" />
-        <ProfileCondition condition="LessThanEqual" property="VideoBitrate" value="20000000" isRequired="true" />
-        <ProfileCondition condition="LessThanEqual" property="VideoLevel" value="41" isRequired="true" />
-      </Conditions>
-      <ApplyConditions />
-    </CodecProfile>
-    <CodecProfile type="Video">
-      <Conditions>
-        <ProfileCondition condition="LessThanEqual" property="Width" value="1920" isRequired="true" />
-        <ProfileCondition condition="LessThanEqual" property="Height" value="1080" isRequired="true" />
-        <ProfileCondition condition="LessThanEqual" property="VideoFramerate" value="30" isRequired="true" />
-        <ProfileCondition condition="LessThanEqual" property="VideoBitrate" value="20000000" isRequired="true" />
-      </Conditions>
-      <ApplyConditions />
-    </CodecProfile>
-    <CodecProfile type="VideoAudio" codec="ac3,he-aac">
-      <Conditions>
-        <ProfileCondition condition="LessThanEqual" property="AudioChannels" value="6" isRequired="true" />
-      </Conditions>
-      <ApplyConditions />
-    </CodecProfile>
-    <CodecProfile type="VideoAudio" codec="aac">
-      <Conditions>
-        <ProfileCondition condition="LessThanEqual" property="AudioChannels" value="2" isRequired="true" />
-      </Conditions>
-      <ApplyConditions />
-    </CodecProfile>
-  </CodecProfiles>
-  <ResponseProfiles>
-    <ResponseProfile container="mkv,ts" type="Video" mimeType="video/mp4">
-      <Conditions />
-    </ResponseProfile>
-  </ResponseProfiles>
-  <SubtitleProfiles>
-    <SubtitleProfile format="srt" method="Embed" />
-  </SubtitleProfiles>
-</Profile>

File diff suppressed because it is too large
+ 0 - 29
MediaBrowser.Dlna/Profiles/Xml/Kodi.xml


File diff suppressed because it is too large
+ 0 - 29
MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml


File diff suppressed because it is too large
+ 0 - 27
MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml


File diff suppressed because it is too large
+ 0 - 29
MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml


File diff suppressed because it is too large
+ 0 - 30
MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml


File diff suppressed because it is too large
+ 0 - 23
MediaBrowser.Dlna/Profiles/Xml/Popcorn Hour.xml


File diff suppressed because it is too large
+ 0 - 29
MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml


File diff suppressed because it is too large
+ 0 - 33
MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml


File diff suppressed because it is too large
+ 0 - 33
MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2014.xml


File diff suppressed because it is too large
+ 0 - 31
MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2015.xml


File diff suppressed because it is too large
+ 0 - 31
MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2016.xml


File diff suppressed because it is too large
+ 0 - 31
MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml


+ 0 - 133
MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml

@@ -1,133 +0,0 @@
-<?xml version="1.0"?>
-<Profile xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-  <Name>Sony Bravia (2010)</Name>
-  <Identification>
-    <FriendlyName>KDL-\d{2}[EHLNPB]X\d[01]\d.*</FriendlyName>
-    <Manufacturer>Sony</Manufacturer>
-    <Headers>
-      <HttpHeaderInfo name="X-AV-Client-Info" value=".*KDL-\d{2}[EHLNPB]X\d[01]\d.*" match="Regex" />
-    </Headers>
-  </Identification>
-  <Manufacturer>Microsoft Corporation</Manufacturer>
-  <ManufacturerUrl>http://www.microsoft.com/</ManufacturerUrl>
-  <ModelName>Windows Media Player Sharing</ModelName>
-  <ModelDescription>Emby</ModelDescription>
-  <ModelNumber>3.0</ModelNumber>
-  <ModelUrl>http://www.microsoft.com/</ModelUrl>
-  <EnableAlbumArtInDidl>true</EnableAlbumArtInDidl>
-  <EnableSingleAlbumArtLimit>true</EnableSingleAlbumArtLimit>
-  <EnableSingleSubtitleLimit>false</EnableSingleSubtitleLimit>
-  <SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
-  <AlbumArtPn>JPEG_TN</AlbumArtPn>
-  <MaxAlbumArtWidth>480</MaxAlbumArtWidth>
-  <MaxAlbumArtHeight>480</MaxAlbumArtHeight>
-  <MaxIconWidth>48</MaxIconWidth>
-  <MaxIconHeight>48</MaxIconHeight>
-  <MaxStreamingBitrate>20000000</MaxStreamingBitrate>
-  <MaxStaticBitrate>20000000</MaxStaticBitrate>
-  <MusicStreamingTranscodingBitrate>192000</MusicStreamingTranscodingBitrate>
-  <MaxStaticMusicBitrate xsi:nil="true" />
-  <XDlnaDoc>DMS-1.50</XDlnaDoc>
-  <SonyAggregationFlags>10</SonyAggregationFlags>
-  <ProtocolInfo>http-get:*:audio/mpeg:DLNA.ORG_PN=MP3;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_SM;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_PAL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000</ProtocolInfo>
-  <TimelineOffsetSeconds>0</TimelineOffsetSeconds>
-  <RequiresPlainVideoItems>false</RequiresPlainVideoItems>
-  <RequiresPlainFolders>false</RequiresPlainFolders>
-  <EnableMSMediaReceiverRegistrar>false</EnableMSMediaReceiverRegistrar>
-  <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
-  <XmlRootAttributes>
-    <XmlAttribute name="xmlns:av" value="urn:schemas-sony-com:av" />
-  </XmlRootAttributes>
-  <DirectPlayProfiles>
-    <DirectPlayProfile container="ts" audioCodec="ac3,aac,mp3" videoCodec="h264" type="Video" />
-    <DirectPlayProfile container="ts" audioCodec="mp3,mp2" videoCodec="mpeg1video,mpeg2video" type="Video" />
-    <DirectPlayProfile container="mpeg" audioCodec="mp3,mp2" videoCodec="mpeg2video,mpeg1video" type="Video" />
-    <DirectPlayProfile container="mp3" audioCodec="mp3" type="Audio" />
-  </DirectPlayProfiles>
-  <TranscodingProfiles>
-    <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" enableSubtitlesInManifest="false" />
-    <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="true" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" enableSubtitlesInManifest="false" />
-    <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" copyTimestamps="false" context="Streaming" enableSubtitlesInManifest="false" />
-  </TranscodingProfiles>
-  <ContainerProfiles>
-    <ContainerProfile type="Photo">
-      <Conditions>
-        <ProfileCondition condition="LessThanEqual" property="Width" value="1920" isRequired="true" />
-        <ProfileCondition condition="LessThanEqual" property="Height" value="1080" isRequired="true" />
-      </Conditions>
-    </ContainerProfile>
-  </ContainerProfiles>
-  <CodecProfiles>
-    <CodecProfile type="Video" codec="h264">
-      <Conditions>
-        <ProfileCondition condition="LessThanEqual" property="Width" value="1920" isRequired="true" />
-        <ProfileCondition condition="LessThanEqual" property="Height" value="1080" isRequired="true" />
-        <ProfileCondition condition="LessThanEqual" property="VideoFramerate" value="30" isRequired="true" />
-        <ProfileCondition condition="LessThanEqual" property="VideoBitrate" value="20000000" isRequired="true" />
-        <ProfileCondition condition="LessThanEqual" property="VideoLevel" value="41" isRequired="true" />
-      </Conditions>
-      <ApplyConditions />
-    </CodecProfile>
-    <CodecProfile type="Video" codec="mpeg2video">
-      <Conditions>
-        <ProfileCondition condition="LessThanEqual" property="Width" value="1920" isRequired="true" />
-        <ProfileCondition condition="LessThanEqual" property="Height" value="1080" isRequired="true" />
-        <ProfileCondition condition="LessThanEqual" property="VideoFramerate" value="30" isRequired="true" />
-        <ProfileCondition condition="LessThanEqual" property="VideoBitrate" value="20000000" isRequired="true" />
-      </Conditions>
-      <ApplyConditions />
-    </CodecProfile>
-    <CodecProfile type="Video">
-      <Conditions>
-        <ProfileCondition condition="LessThanEqual" property="Width" value="1920" isRequired="true" />
-        <ProfileCondition condition="LessThanEqual" property="Height" value="1080" isRequired="true" />
-        <ProfileCondition condition="LessThanEqual" property="VideoFramerate" value="30" isRequired="true" />
-      </Conditions>
-      <ApplyConditions />
-    </CodecProfile>
-    <CodecProfile type="VideoAudio" codec="ac3">
-      <Conditions>
-        <ProfileCondition condition="LessThanEqual" property="AudioChannels" value="6" isRequired="true" />
-      </Conditions>
-      <ApplyConditions />
-    </CodecProfile>
-    <CodecProfile type="VideoAudio" codec="aac">
-      <Conditions>
-        <ProfileCondition condition="LessThanEqual" property="AudioChannels" value="2" isRequired="true" />
-        <ProfileCondition condition="NotEquals" property="AudioProfile" value="he-aac" isRequired="true" />
-      </Conditions>
-      <ApplyConditions />
-    </CodecProfile>
-    <CodecProfile type="VideoAudio" codec="mp3,mp2">
-      <Conditions>
-        <ProfileCondition condition="LessThanEqual" property="AudioChannels" value="2" isRequired="true" />
-      </Conditions>
-      <ApplyConditions />
-    </CodecProfile>
-  </CodecProfiles>
-  <ResponseProfiles>
-    <ResponseProfile container="ts" audioCodec="ac3,aac,mp3" videoCodec="h264" type="Video" orgPn="AVC_TS_HD_24_AC3_T,AVC_TS_HD_50_AC3_T,AVC_TS_HD_60_AC3_T,AVC_TS_HD_EU_T" mimeType="video/vnd.dlna.mpeg-tts">
-      <Conditions>
-        <ProfileCondition condition="Equals" property="PacketLength" value="192" isRequired="true" />
-        <ProfileCondition condition="Equals" property="VideoTimestamp" value="Valid" isRequired="true" />
-      </Conditions>
-    </ResponseProfile>
-    <ResponseProfile container="ts" audioCodec="ac3,aac,mp3" videoCodec="h264" type="Video" orgPn="AVC_TS_HD_24_AC3_ISO,AVC_TS_HD_50_AC3_ISO,AVC_TS_HD_60_AC3_ISO,AVC_TS_HD_EU_ISO" mimeType="video/mpeg">
-      <Conditions>
-        <ProfileCondition condition="Equals" property="PacketLength" value="188" isRequired="true" />
-      </Conditions>
-    </ResponseProfile>
-    <ResponseProfile container="ts" audioCodec="ac3,aac,mp3" videoCodec="h264" type="Video" orgPn="AVC_TS_HD_24_AC3,AVC_TS_HD_50_AC3,AVC_TS_HD_60_AC3,AVC_TS_HD_EU" mimeType="video/vnd.dlna.mpeg-tts">
-      <Conditions />
-    </ResponseProfile>
-    <ResponseProfile container="ts" videoCodec="mpeg2video" type="Video" orgPn="MPEG_TS_SD_EU,MPEG_TS_SD_NA,MPEG_TS_SD_KO" mimeType="video/vnd.dlna.mpeg-tts">
-      <Conditions />
-    </ResponseProfile>
-    <ResponseProfile container="mpeg" videoCodec="mpeg1video,mpeg2video" type="Video" orgPn="MPEG_PS_NTSC,MPEG_PS_PAL" mimeType="video/mpeg">
-      <Conditions />
-    </ResponseProfile>
-  </ResponseProfiles>
-  <SubtitleProfiles>
-    <SubtitleProfile format="srt" method="Embed" />
-  </SubtitleProfiles>
-</Profile>

File diff suppressed because it is too large
+ 0 - 31
MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml


File diff suppressed because it is too large
+ 0 - 31
MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml


File diff suppressed because it is too large
+ 0 - 31
MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml


File diff suppressed because it is too large
+ 0 - 31
MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2014).xml


File diff suppressed because it is too large
+ 0 - 31
MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml


File diff suppressed because it is too large
+ 0 - 31
MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 4.xml


File diff suppressed because it is too large
+ 0 - 29
MediaBrowser.Dlna/Profiles/Xml/Vlc.xml


File diff suppressed because it is too large
+ 0 - 30
MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml


File diff suppressed because it is too large
+ 0 - 31
MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml


File diff suppressed because it is too large
+ 0 - 30
MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml


File diff suppressed because it is too large
+ 0 - 29
MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml


+ 0 - 1
MediaBrowser.Dlna/packages.config

@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
   <package id="CommonIO" version="1.0.0.9" targetFramework="net45" />
-  <package id="morelinq" version="1.4.0" targetFramework="net45" />
   <package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
 </packages>

+ 3 - 2
MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -9,9 +9,10 @@
     <AppDesignerFolder>Properties</AppDesignerFolder>
     <RootNamespace>MediaBrowser.LocalMetadata</RootNamespace>
     <AssemblyName>MediaBrowser.LocalMetadata</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
     <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
+    <TargetFrameworkProfile />
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugSymbols>true</DebugSymbols>

+ 9 - 6
MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -9,9 +9,10 @@
     <AppDesignerFolder>Properties</AppDesignerFolder>
     <RootNamespace>MediaBrowser.MediaEncoding</RootNamespace>
     <AssemblyName>MediaBrowser.MediaEncoding</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
     <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
+    <TargetFrameworkProfile />
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugSymbols>true</DebugSymbols>
@@ -36,15 +37,17 @@
     <WarningLevel>4</WarningLevel>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="BDInfo">
-      <HintPath>..\packages\MediaBrowser.BdInfo.1.0.0.10\lib\net35\BDInfo.dll</HintPath>
+    <Reference Include="BDInfo, Version=1.0.1.0, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\packages\MediaBrowser.BdInfo.1.0.1\lib\portable-net46+win10\BDInfo.dll</HintPath>
+      <Private>True</Private>
     </Reference>
     <Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\packages\CommonIO.1.0.0.9\lib\net45\CommonIO.dll</HintPath>
     </Reference>
-    <Reference Include="DvdLib">
-      <HintPath>..\packages\MediaBrowser.BdInfo.1.0.0.10\lib\net35\DvdLib.dll</HintPath>
+    <Reference Include="DvdLib, Version=1.0.1.0, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\packages\MediaBrowser.BdInfo.1.0.1\lib\portable-net46+win10\DvdLib.dll</HintPath>
+      <Private>True</Private>
     </Reference>
     <Reference Include="Patterns.Logging">
       <HintPath>..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll</HintPath>

Some files were not shown because too many files changed in this diff