aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MediaBrowser.Api/ItemLookupService.cs27
-rw-r--r--MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs10
-rw-r--r--MediaBrowser.Common/Net/HttpRequestOptions.cs4
-rw-r--r--MediaBrowser.Controller/Dlna/DirectPlayProfile.cs25
-rw-r--r--MediaBrowser.Controller/Dlna/DlnaProfile.cs54
-rw-r--r--MediaBrowser.Controller/Dlna/IDlnaManager.cs28
-rw-r--r--MediaBrowser.Controller/Dlna/TranscodingProfile.cs16
-rw-r--r--MediaBrowser.Controller/Entities/BaseItem.cs5
-rw-r--r--MediaBrowser.Controller/MediaBrowser.Controller.csproj4
-rw-r--r--MediaBrowser.Dlna/DlnaManager.cs376
-rw-r--r--MediaBrowser.Dlna/MediaBrowser.Dlna.csproj11
-rw-r--r--MediaBrowser.Dlna/PlayTo/Configuration/DlnaProfile.cs53
-rw-r--r--MediaBrowser.Dlna/PlayTo/Configuration/PlayToConfiguration.cs134
-rw-r--r--MediaBrowser.Dlna/PlayTo/Configuration/TranscodeSetting.cs85
-rw-r--r--MediaBrowser.Dlna/PlayTo/Device.cs71
-rw-r--r--MediaBrowser.Dlna/PlayTo/DeviceInfo.cs66
-rw-r--r--MediaBrowser.Dlna/PlayTo/DeviceProperties.cs176
-rw-r--r--MediaBrowser.Dlna/PlayTo/DeviceService.cs30
-rw-r--r--MediaBrowser.Dlna/PlayTo/DlnaController.cs16
-rw-r--r--MediaBrowser.Dlna/PlayTo/PlayToManager.cs47
-rw-r--r--MediaBrowser.Dlna/PlayTo/PlayToServerEntryPoint.cs14
-rw-r--r--MediaBrowser.Dlna/PlayTo/PlaylistItem.cs110
-rw-r--r--MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs18
-rw-r--r--MediaBrowser.Dlna/PlayTo/StreamHelper.cs10
-rw-r--r--MediaBrowser.Dlna/PlayTo/uService.cs42
-rw-r--r--MediaBrowser.Model/Configuration/DlnaOptions.cs1
-rw-r--r--MediaBrowser.Model/Configuration/UserConfiguration.cs2
-rw-r--r--MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs80
-rw-r--r--MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs130
-rw-r--r--MediaBrowser.ServerApplication/ApplicationHost.cs5
-rw-r--r--Nuget/MediaBrowser.Common.Internal.nuspec4
-rw-r--r--Nuget/MediaBrowser.Common.nuspec2
-rw-r--r--Nuget/MediaBrowser.Server.Core.nuspec4
33 files changed, 980 insertions, 680 deletions
diff --git a/MediaBrowser.Api/ItemLookupService.cs b/MediaBrowser.Api/ItemLookupService.cs
index a32a1ad03..62596287e 100644
--- a/MediaBrowser.Api/ItemLookupService.cs
+++ b/MediaBrowser.Api/ItemLookupService.cs
@@ -3,6 +3,7 @@ using MediaBrowser.Common.IO;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
@@ -67,6 +68,18 @@ namespace MediaBrowser.Api
{
}
+ [Route("/Items/RemoteSearch/MusicArtist", "POST")]
+ [Api(Description = "Gets external id infos for an item")]
+ public class GetMusicArtistRemoteSearchResults : RemoteSearchQuery<ArtistInfo>, IReturn<List<RemoteSearchResult>>
+ {
+ }
+
+ [Route("/Items/RemoteSearch/MusicAlbum", "POST")]
+ [Api(Description = "Gets external id infos for an item")]
+ public class GetMusicAlbumRemoteSearchResults : RemoteSearchQuery<AlbumInfo>, IReturn<List<RemoteSearchResult>>
+ {
+ }
+
[Route("/Items/RemoteSearch/Person", "POST")]
[Api(Description = "Gets external id infos for an item")]
public class GetPersonRemoteSearchResults : RemoteSearchQuery<PersonLookupInfo>, IReturn<List<RemoteSearchResult>>
@@ -167,6 +180,20 @@ namespace MediaBrowser.Api
return ToOptimizedResult(result);
}
+ public object Post(GetMusicAlbumRemoteSearchResults request)
+ {
+ var result = _providerManager.GetRemoteSearchResults<MusicAlbum, AlbumInfo>(request, CancellationToken.None).Result;
+
+ return ToOptimizedResult(result);
+ }
+
+ public object Post(GetMusicArtistRemoteSearchResults request)
+ {
+ var result = _providerManager.GetRemoteSearchResults<MusicArtist, ArtistInfo>(request, CancellationToken.None).Result;
+
+ return ToOptimizedResult(result);
+ }
+
public object Get(GetRemoteSearchImage request)
{
var result = GetRemoteImage(request).Result;
diff --git a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
index ca9214b54..ac9a51ea1 100644
--- a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
+++ b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
@@ -259,7 +259,10 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
throw new HttpException(string.Format("Connection to {0} timed out", options.Url)) { IsTimedOut = true };
}
- _logger.Info("HttpClientManager {0}: {1}", httpMethod.ToUpper(), options.Url);
+ if (options.LogRequest)
+ {
+ _logger.Info("HttpClientManager {0}: {1}", httpMethod.ToUpper(), options.Url);
+ }
try
{
@@ -456,7 +459,10 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
options.Progress.Report(0);
- _logger.Info("HttpClientManager.GetTempFileResponse url: {0}", options.Url);
+ if (options.LogRequest)
+ {
+ _logger.Info("HttpClientManager.GetTempFileResponse url: {0}", options.Url);
+ }
try
{
diff --git a/MediaBrowser.Common/Net/HttpRequestOptions.cs b/MediaBrowser.Common/Net/HttpRequestOptions.cs
index 659d230cf..da0449ae7 100644
--- a/MediaBrowser.Common/Net/HttpRequestOptions.cs
+++ b/MediaBrowser.Common/Net/HttpRequestOptions.cs
@@ -72,6 +72,8 @@ namespace MediaBrowser.Common.Net
public bool BufferContent { get; set; }
+ public bool LogRequest { get; set; }
+
public HttpRequestCachePolicy CachePolicy { get; set; }
private string GetHeaderValue(string name)
@@ -94,6 +96,8 @@ namespace MediaBrowser.Common.Net
CachePolicy = HttpRequestCachePolicy.None;
RequestHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
+
+ LogRequest = true;
}
}
diff --git a/MediaBrowser.Controller/Dlna/DirectPlayProfile.cs b/MediaBrowser.Controller/Dlna/DirectPlayProfile.cs
new file mode 100644
index 000000000..f1922dd32
--- /dev/null
+++ b/MediaBrowser.Controller/Dlna/DirectPlayProfile.cs
@@ -0,0 +1,25 @@
+
+namespace MediaBrowser.Controller.Dlna
+{
+ public class DirectPlayProfile
+ {
+ public string[] Containers { get; set; }
+ public string[] AudioCodecs { get; set; }
+ public string[] VideoCodecs { get; set; }
+ public string MimeType { get; set; }
+ public DlnaProfileType Type { get; set; }
+
+ public DirectPlayProfile()
+ {
+ Containers = new string[] { };
+ AudioCodecs = new string[] { };
+ VideoCodecs = new string[] { };
+ }
+ }
+
+ public enum DlnaProfileType
+ {
+ Audio = 0,
+ Video = 1
+ }
+}
diff --git a/MediaBrowser.Controller/Dlna/DlnaProfile.cs b/MediaBrowser.Controller/Dlna/DlnaProfile.cs
new file mode 100644
index 000000000..33f95b794
--- /dev/null
+++ b/MediaBrowser.Controller/Dlna/DlnaProfile.cs
@@ -0,0 +1,54 @@
+
+namespace MediaBrowser.Controller.Dlna
+{
+ public class DlnaProfile
+ {
+ /// <summary>
+ /// Gets or sets the name.
+ /// </summary>
+ /// <value>The name.</value>
+ public string Name { get; set; }
+
+ /// <summary>
+ /// Gets or sets the type of the client.
+ /// </summary>
+ /// <value>The type of the client.</value>
+ public string ClientType { get; set; }
+
+ /// <summary>
+ /// Gets or sets the name of the friendly.
+ /// </summary>
+ /// <value>The name of the friendly.</value>
+ public string FriendlyName { get; set; }
+
+ /// <summary>
+ /// Gets or sets the model number.
+ /// </summary>
+ /// <value>The model number.</value>
+ public string ModelNumber { get; set; }
+
+ /// <summary>
+ /// Gets or sets the name of the model.
+ /// </summary>
+ /// <value>The name of the model.</value>
+ public string ModelName { get; set; }
+
+ /// <summary>
+ /// Gets or sets the transcoding profiles.
+ /// </summary>
+ /// <value>The transcoding profiles.</value>
+ public TranscodingProfile[] TranscodingProfiles { get; set; }
+
+ /// <summary>
+ /// Gets or sets the direct play profiles.
+ /// </summary>
+ /// <value>The direct play profiles.</value>
+ public DirectPlayProfile[] DirectPlayProfiles { get; set; }
+
+ public DlnaProfile()
+ {
+ DirectPlayProfiles = new DirectPlayProfile[] { };
+ TranscodingProfiles = new TranscodingProfile[] { };
+ }
+ }
+}
diff --git a/MediaBrowser.Controller/Dlna/IDlnaManager.cs b/MediaBrowser.Controller/Dlna/IDlnaManager.cs
new file mode 100644
index 000000000..017dbc874
--- /dev/null
+++ b/MediaBrowser.Controller/Dlna/IDlnaManager.cs
@@ -0,0 +1,28 @@
+using System.Collections.Generic;
+
+namespace MediaBrowser.Controller.Dlna
+{
+ public interface IDlnaManager
+ {
+ /// <summary>
+ /// Gets the dlna profiles.
+ /// </summary>
+ /// <returns>IEnumerable{DlnaProfile}.</returns>
+ IEnumerable<DlnaProfile> GetProfiles();
+
+ /// <summary>
+ /// Gets the default profile.
+ /// </summary>
+ /// <returns>DlnaProfile.</returns>
+ DlnaProfile GetDefaultProfile();
+
+ /// <summary>
+ /// Gets the profile.
+ /// </summary>
+ /// <param name="friendlyName">Name of the friendly.</param>
+ /// <param name="modelName">Name of the model.</param>
+ /// <param name="modelNumber">The model number.</param>
+ /// <returns>DlnaProfile.</returns>
+ DlnaProfile GetProfile(string friendlyName, string modelName, string modelNumber);
+ }
+}
diff --git a/MediaBrowser.Controller/Dlna/TranscodingProfile.cs b/MediaBrowser.Controller/Dlna/TranscodingProfile.cs
new file mode 100644
index 000000000..abc8868fb
--- /dev/null
+++ b/MediaBrowser.Controller/Dlna/TranscodingProfile.cs
@@ -0,0 +1,16 @@
+
+namespace MediaBrowser.Controller.Dlna
+{
+ public class TranscodingProfile
+ {
+ public string Container { get; set; }
+
+ public DlnaProfileType Type { get; set; }
+
+ public string MimeType { get; set; }
+
+ public string VideoCodec { get; set; }
+
+ public string AudioCodec { get; set; }
+ }
+}
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index 23f8ac31a..e0c792307 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -1332,6 +1332,11 @@ namespace MediaBrowser.Controller.Entities
return ImageInfos.Where(i => i.Type == imageType);
}
+ public bool AddImages(ImageType imageType, IEnumerable<FileInfo> images)
+ {
+ return AddImages(imageType, images.Cast<FileSystemInfo>());
+ }
+
/// <summary>
/// Adds the images.
/// </summary>
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index 16c54861e..21a501b08 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -73,6 +73,10 @@
<Compile Include="Channels\IChannelManager.cs" />
<Compile Include="Collections\CollectionCreationOptions.cs" />
<Compile Include="Collections\ICollectionManager.cs" />
+ <Compile Include="Dlna\DirectPlayProfile.cs" />
+ <Compile Include="Dlna\IDlnaManager.cs" />
+ <Compile Include="Dlna\DlnaProfile.cs" />
+ <Compile Include="Dlna\TranscodingProfile.cs" />
<Compile Include="Drawing\IImageProcessor.cs" />
<Compile Include="Drawing\ImageFormat.cs" />
<Compile Include="Drawing\ImageProcessingOptions.cs" />
diff --git a/MediaBrowser.Dlna/DlnaManager.cs b/MediaBrowser.Dlna/DlnaManager.cs
new file mode 100644
index 000000000..1c9cba2be
--- /dev/null
+++ b/MediaBrowser.Dlna/DlnaManager.cs
@@ -0,0 +1,376 @@
+using MediaBrowser.Controller.Dlna;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+
+namespace MediaBrowser.Dlna
+{
+ public class DlnaManager : IDlnaManager
+ {
+ public IEnumerable<DlnaProfile> GetProfiles()
+ {
+ var list = new List<DlnaProfile>();
+
+ list.Add(new DlnaProfile
+ {
+ Name = "Samsung TV (B Series)",
+ ClientType = "DLNA",
+ FriendlyName = "^TV$",
+ ModelNumber = @"1\.0",
+ ModelName = "Samsung DTV DMR",
+
+ TranscodingProfiles = new[]
+ {
+ new TranscodingProfile
+ {
+ Container = "mp3",
+ Type = DlnaProfileType.Audio
+ },
+ new TranscodingProfile
+ {
+ Container = "ts",
+ Type = DlnaProfileType.Video
+ }
+ },
+
+ DirectPlayProfiles = new[]
+ {
+ new DirectPlayProfile
+ {
+ Containers = new[]{"mp3"},
+ Type = DlnaProfileType.Audio
+ },
+ new DirectPlayProfile
+ {
+ Containers = new[]{"mkv"},
+ MimeType = "x-mkv",
+ Type = DlnaProfileType.Video
+ },
+ new DirectPlayProfile
+ {
+ Containers = new[]{"avi"},
+ MimeType = "x-msvideo",
+ Type = DlnaProfileType.Video
+ },
+ new DirectPlayProfile
+ {
+ Containers = new[]{"mp4"},
+ Type = DlnaProfileType.Video
+ }
+ }
+ });
+
+ list.Add(new DlnaProfile
+ {
+ Name = "Samsung TV (E/F-series)",
+ ClientType = "DLNA",
+ FriendlyName = @"(^\[TV\][A-Z]{2}\d{2}(E|F)[A-Z]?\d{3,4}.*)|^\[TV\] Samsung",
+ ModelNumber = @"(1\.0)|(AllShare1\.0)",
+
+ TranscodingProfiles = new[]
+ {
+ new TranscodingProfile
+ {
+ Container = "mp3",
+ Type = DlnaProfileType.Audio
+ },
+ new TranscodingProfile
+ {
+ Container = "ts",
+ Type = DlnaProfileType.Video
+ }
+ },
+
+ DirectPlayProfiles = new[]
+ {
+ new DirectPlayProfile
+ {
+ Containers = new[]{"mp3"},
+ Type = DlnaProfileType.Audio
+ },
+ new DirectPlayProfile
+ {
+ Containers = new[]{"mkv"},
+ MimeType = "x-mkv",
+ Type = DlnaProfileType.Video
+ },
+ new DirectPlayProfile
+ {
+ Containers = new[]{"avi"},
+ MimeType = "x-msvideo",
+ Type = DlnaProfileType.Video
+ },
+ new DirectPlayProfile
+ {
+ Containers = new[]{"mp4"},
+ Type = DlnaProfileType.Video
+ }
+ }
+ });
+
+ list.Add(new DlnaProfile
+ {
+ Name = "Samsung TV (C/D-series)",
+ ClientType = "DLNA",
+ FriendlyName = @"(^TV-\d{2}C\d{3}.*)|(^\[TV\][A-Z]{2}\d{2}(D)[A-Z]?\d{3,4}.*)|^\[TV\] Samsung",
+ ModelNumber = @"(1\.0)|(AllShare1\.0)",
+ TranscodingProfiles = new[]
+ {
+ new TranscodingProfile
+ {
+ Container = "mp3",
+ Type = DlnaProfileType.Audio
+ },
+ new TranscodingProfile
+ {
+ Container = "ts",
+ Type = DlnaProfileType.Video
+ }
+ },
+
+ DirectPlayProfiles = new[]
+ {
+ new DirectPlayProfile
+ {
+ Containers = new[]{"mp3"},
+ Type = DlnaProfileType.Audio
+ },
+ new DirectPlayProfile
+ {
+ Containers = new[]{"mkv"},
+ MimeType = "x-mkv",
+ Type = DlnaProfileType.Video
+ },
+ new DirectPlayProfile
+ {
+ Containers = new[]{"avi"},
+ MimeType = "x-msvideo",
+ Type = DlnaProfileType.Video
+ },
+ new DirectPlayProfile
+ {
+ Containers = new[]{"mp4"},
+ Type = DlnaProfileType.Video
+ }
+ }
+ });
+
+ list.Add(new DlnaProfile
+ {
+ Name = "Xbox 360",
+ ClientType = "DLNA",
+ ModelName = "Xbox 360",
+ TranscodingProfiles = new[]
+ {
+ new TranscodingProfile
+ {
+ Container = "mp3",
+ Type = DlnaProfileType.Audio
+ },
+ new TranscodingProfile
+ {
+ Container = "ts",
+ Type = DlnaProfileType.Video
+ }
+ },
+
+ DirectPlayProfiles = new[]
+ {
+ new DirectPlayProfile
+ {
+ Containers = new[]{"mp3"},
+ Type = DlnaProfileType.Audio
+ },
+ new DirectPlayProfile
+ {
+ Containers = new[]{"avi"},
+ MimeType = "x-msvideo",
+ Type = DlnaProfileType.Video
+ }
+ }
+ });
+
+ list.Add(new DlnaProfile
+ {
+ Name = "Xbox One",
+ ModelName = "Xbox One",
+ ClientType = "DLNA",
+ FriendlyName = "Xbox-SystemOS",
+ TranscodingProfiles = new[]
+ {
+ new TranscodingProfile
+ {
+ Container = "mp3",
+ Type = DlnaProfileType.Audio
+ },
+ new TranscodingProfile
+ {
+ Container = "ts",
+ Type = DlnaProfileType.Video
+ }
+ },
+
+ DirectPlayProfiles = new[]
+ {
+ new DirectPlayProfile
+ {
+ Containers = new[]{"mp3"},
+ Type = DlnaProfileType.Audio
+ },
+ new DirectPlayProfile
+ {
+ Containers = new[]{"avi"},
+ MimeType = "x-msvideo",
+ Type = DlnaProfileType.Video
+ }
+ }
+ });
+
+ list.Add(new DlnaProfile
+ {
+ Name = "Sony Bravia (2012)",
+ ClientType = "DLNA",
+ FriendlyName = @"BRAVIA KDL-\d{2}[A-Z]X\d5(\d|G).*",
+
+ TranscodingProfiles = new[]
+ {
+ new TranscodingProfile
+ {
+ Container = "mp3",
+ Type = DlnaProfileType.Audio
+ },
+ new TranscodingProfile
+ {
+ Container = "ts",
+ Type = DlnaProfileType.Video
+ }
+ },
+
+ DirectPlayProfiles = new[]
+ {
+ new DirectPlayProfile
+ {
+ Containers = new[]{"mp3"},
+ Type = DlnaProfileType.Audio
+ },
+ new DirectPlayProfile
+ {
+ Containers = new[]{"avi"},
+ Type = DlnaProfileType.Video,
+ MimeType = "avi"
+ }
+ }
+ });
+
+ //WDTV does not need any transcoding of the formats we support statically
+ list.Add(new DlnaProfile
+ {
+ Name = "WDTV Live",
+ ClientType = "DLNA",
+ ModelName = "WD TV HD Live",
+
+ DirectPlayProfiles = new[]
+ {
+ new DirectPlayProfile
+ {
+ Containers = new[]{"mp3", "flac", "m4a", "wma"},
+ Type = DlnaProfileType.Audio
+ },
+
+ new DirectPlayProfile
+ {
+ Containers = new[]{"avi", "mp4", "mkv", "ts"},
+ Type = DlnaProfileType.Video
+ }
+ }
+ });
+
+ list.Add(new DlnaProfile
+ {
+ //Linksys DMA2100us does not need any transcoding of the formats we support statically
+ Name = "Linksys DMA2100",
+ ClientType = "DLNA",
+ ModelName = "DMA2100us",
+
+ DirectPlayProfiles = new[]
+ {
+ new DirectPlayProfile
+ {
+ Containers = new[]{"mp3", "flac", "m4a", "wma"},
+ Type = DlnaProfileType.Audio
+ },
+
+ new DirectPlayProfile
+ {
+ Containers = new[]{"avi", "mp4", "mkv", "ts"},
+ Type = DlnaProfileType.Video
+ }
+ }
+ });
+
+ return list;
+ }
+
+ public DlnaProfile GetDefaultProfile()
+ {
+ return new DlnaProfile
+ {
+ TranscodingProfiles = new[]
+ {
+ new TranscodingProfile
+ {
+ Container = "mp3",
+ Type = DlnaProfileType.Audio
+ },
+ new TranscodingProfile
+ {
+ Container = "ts",
+ Type = DlnaProfileType.Video
+ }
+ },
+
+ DirectPlayProfiles = new[]
+ {
+ new DirectPlayProfile
+ {
+ Containers = new[]{"mp3", "wma"},
+ Type = DlnaProfileType.Audio
+ },
+
+ new DirectPlayProfile
+ {
+ Containers = new[]{"avi", "mp4"},
+ Type = DlnaProfileType.Video
+ }
+ }
+ };
+ }
+
+ public DlnaProfile GetProfile(string friendlyName, string modelName, string modelNumber)
+ {
+ foreach (var profile in GetProfiles())
+ {
+ if (!string.IsNullOrEmpty(profile.FriendlyName))
+ {
+ if (!Regex.IsMatch(friendlyName, profile.FriendlyName))
+ continue;
+ }
+
+ if (!string.IsNullOrEmpty(profile.ModelNumber))
+ {
+ if (!Regex.IsMatch(modelNumber, profile.ModelNumber))
+ continue;
+ }
+
+ if (!string.IsNullOrEmpty(profile.ModelName))
+ {
+ if (!Regex.IsMatch(modelName, profile.ModelName))
+ continue;
+ }
+
+ return profile;
+
+ }
+ return GetDefaultProfile();
+ }
+ }
+} \ No newline at end of file
diff --git a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj
index 622ccefbc..a7ee05cf3 100644
--- a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj
+++ b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj
@@ -51,15 +51,14 @@
<Compile Include="..\SharedVersion.cs">
<Link>Properties\SharedVersion.cs</Link>
</Compile>
+ <Compile Include="DlnaManager.cs" />
<Compile Include="PlayTo\Argument.cs" />
- <Compile Include="PlayTo\Configuration\DlnaProfile.cs" />
- <Compile Include="PlayTo\Configuration\PlayToConfiguration.cs" />
- <Compile Include="PlayTo\Configuration\TranscodeSetting.cs" />
<Compile Include="PlayTo\CurrentIdEventArgs.cs" />
<Compile Include="PlayTo\Device.cs">
<SubType>Code</SubType>
</Compile>
- <Compile Include="PlayTo\DeviceProperties.cs" />
+ <Compile Include="PlayTo\DeviceInfo.cs" />
+ <Compile Include="PlayTo\DeviceService.cs" />
<Compile Include="PlayTo\DidlBuilder.cs" />
<Compile Include="PlayTo\DlnaController.cs" />
<Compile Include="PlayTo\DlnaControllerFactory.cs" />
@@ -81,7 +80,6 @@
<Compile Include="PlayTo\uIcon.cs" />
<Compile Include="PlayTo\uParser.cs" />
<Compile Include="PlayTo\uPnpNamespaces.cs" />
- <Compile Include="PlayTo\uService.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
@@ -98,6 +96,9 @@
<Name>MediaBrowser.Model</Name>
</ProjectReference>
</ItemGroup>
+ <ItemGroup>
+ <Folder Include="Server\" />
+ </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.
diff --git a/MediaBrowser.Dlna/PlayTo/Configuration/DlnaProfile.cs b/MediaBrowser.Dlna/PlayTo/Configuration/DlnaProfile.cs
deleted file mode 100644
index e75cea5a9..000000000
--- a/MediaBrowser.Dlna/PlayTo/Configuration/DlnaProfile.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-namespace MediaBrowser.Dlna.PlayTo.Configuration
-{
- public class DlnaProfile
- {
- /// <summary>
- /// Gets or sets the name to be displayed.
- /// </summary>
- /// <value>
- /// The name.
- /// </value>
- public string Name { get; set; }
-
- /// <summary>
- /// Gets or sets the type of the client.
- /// </summary>
- /// <value>
- /// The type of the client.
- /// </value>
- public string ClientType { get; set; }
-
- /// <summary>
- /// Gets or sets the name of the friendly.
- /// </summary>
- /// <value>
- /// The name of the friendly.
- /// </value>
- public string FriendlyName { get; set; }
-
- /// <summary>
- /// Gets or sets the model number.
- /// </summary>
- /// <value>
- /// The model number.
- /// </value>
- public string ModelNumber { get; set; }
-
- /// <summary>
- /// Gets or sets the name of the model.
- /// </summary>
- /// <value>
- /// The name of the model.
- /// </value>
- public string ModelName { get; set; }
-
- /// <summary>
- /// Gets or sets the transcode settings.
- /// </summary>
- /// <value>
- /// The transcode settings.
- /// </value>
- public TranscodeSettings[] TranscodeSettings { get; set; }
- }
-}
diff --git a/MediaBrowser.Dlna/PlayTo/Configuration/PlayToConfiguration.cs b/MediaBrowser.Dlna/PlayTo/Configuration/PlayToConfiguration.cs
deleted file mode 100644
index d3fcb24ad..000000000
--- a/MediaBrowser.Dlna/PlayTo/Configuration/PlayToConfiguration.cs
+++ /dev/null
@@ -1,134 +0,0 @@
-namespace MediaBrowser.Dlna.PlayTo.Configuration
-{
- public class PlayToConfiguration
- {
- private static readonly string[] _supportedStaticFormats = { "mp3", "flac", "m4a", "wma", "avi", "mp4", "mkv", "ts" };
- public static string[] SupportedStaticFormats
- {
- get
- {
- return _supportedStaticFormats;
- }
- }
-
- private static readonly DlnaProfile[] _profiles = GetDefaultProfiles();
- public static DlnaProfile[] Profiles
- {
- get
- {
- return _profiles;
- }
- }
-
- private static DlnaProfile[] GetDefaultProfiles()
- {
- var profile0 = new DlnaProfile
- {
- Name = "Samsung TV (B Series) [Profile]",
- ClientType = "DLNA",
- FriendlyName = "^TV$",
- ModelNumber = @"1\.0",
- ModelName = "Samsung DTV DMR",
- TranscodeSettings = new[]
- {
- new TranscodeSettings {Container = "mkv", MimeType = "x-mkv"},
- new TranscodeSettings {Container = "flac", TargetContainer = "mp3"},
- new TranscodeSettings {Container = "m4a", TargetContainer = "mp3"}
- }
- };
-
- var profile1 = new DlnaProfile
- {
- Name = "Samsung TV (E/F-series) [Profile]",
- ClientType = "DLNA",
- FriendlyName = @"(^\[TV\][A-Z]{2}\d{2}(E|F)[A-Z]?\d{3,4}.*)|^\[TV\] Samsung",
- ModelNumber = @"(1\.0)|(AllShare1\.0)",
- TranscodeSettings = new[]
- {
- new TranscodeSettings {Container = "mkv", MimeType = "x-mkv"},
- new TranscodeSettings {Container = "flac", TargetContainer = "mp3"},
- new TranscodeSettings {Container = "m4a", TargetContainer = "mp3"}
- }
- };
-
- var profile2 = new DlnaProfile
- {
- Name = "Samsung TV (C/D-series) [Profile]",
- ClientType = "DLNA",
- FriendlyName = @"(^TV-\d{2}C\d{3}.*)|(^\[TV\][A-Z]{2}\d{2}(D)[A-Z]?\d{3,4}.*)|^\[TV\] Samsung",
- ModelNumber = @"(1\.0)|(AllShare1\.0)",
- TranscodeSettings = new[]
- {
- new TranscodeSettings {Container = "mkv", MimeType = "x-mkv"},
- new TranscodeSettings {Container = "flac", TargetContainer = "mp3"},
- new TranscodeSettings {Container = "m4a", TargetContainer = "mp3"}
- }
- };
-
- var profile3 = new DlnaProfile
- {
- Name = "Xbox 360 [Profile]",
- ClientType = "DLNA",
- ModelName = "Xbox 360",
- TranscodeSettings = new[]
- {
- new TranscodeSettings {Container = "mkv", TargetContainer = "ts"},
- new TranscodeSettings {Container = "flac", TargetContainer = "mp3"},
- new TranscodeSettings {Container = "m4a", TargetContainer = "mp3"}
- }
- };
-
- var profile4 = new DlnaProfile
- {
- Name = "Xbox One [Profile]",
- ModelName = "Xbox One",
- ClientType = "DLNA",
- FriendlyName = "Xbox-SystemOS",
- TranscodeSettings = new[]
- {
- new TranscodeSettings {Container = "mkv", TargetContainer = "ts"},
- new TranscodeSettings {Container = "flac", TargetContainer = "mp3"},
- new TranscodeSettings {Container = "m4a", TargetContainer = "mp3"}
- }
- };
-
- var profile5 = new DlnaProfile
- {
- Name = "Sony Bravia TV (2012)",
- ClientType = "TV",
- FriendlyName = @"BRAVIA KDL-\d{2}[A-Z]X\d5(\d|G).*",
- TranscodeSettings = TranscodeSettings.GetDefaultTranscodingSettings()
- };
-
- //WDTV does not need any transcoding of the formats we support statically
- var profile6 = new DlnaProfile
- {
- Name = "WDTV Live [Profile]",
- ClientType = "DLNA",
- ModelName = "WD TV HD Live",
- TranscodeSettings = new TranscodeSettings[] { }
- };
-
- var profile7 = new DlnaProfile
- {
- //Linksys DMA2100us does not need any transcoding of the formats we support statically
- Name = "Linksys DMA2100 [Profile]",
- ClientType = "DLNA",
- ModelName = "DMA2100us",
- TranscodeSettings = new TranscodeSettings[] { }
- };
-
- return new[]
- {
- profile0,
- profile1,
- profile2,
- profile3,
- profile4,
- profile5,
- profile6,
- profile7
- };
- }
- }
-}
diff --git a/MediaBrowser.Dlna/PlayTo/Configuration/TranscodeSetting.cs b/MediaBrowser.Dlna/PlayTo/Configuration/TranscodeSetting.cs
deleted file mode 100644
index 4713dc385..000000000
--- a/MediaBrowser.Dlna/PlayTo/Configuration/TranscodeSetting.cs
+++ /dev/null
@@ -1,85 +0,0 @@
-using System;
-using System.Text.RegularExpressions;
-
-namespace MediaBrowser.Dlna.PlayTo.Configuration
-{
- public class TranscodeSettings
- {
- /// <summary>
- /// Gets or sets the container.
- /// </summary>
- /// <value>
- /// The container.
- /// </value>
- public string Container { get; set; }
-
- /// <summary>
- /// Gets or sets the target container.
- /// </summary>
- /// <value>
- /// The target container.
- /// </value>
- public string TargetContainer { get; set; }
-
- /// <summary>
- /// Gets or sets the Mimetype to enforce
- /// </summary>
- /// <value>
- /// The MimeType.
- /// </value>
- public string MimeType { get; set; }
-
- /// <summary>
- /// The default transcoding settings
- /// </summary>
- private static readonly TranscodeSettings[] DefaultTranscodingSettings =
- {
- new TranscodeSettings { Container = "mkv", TargetContainer = "ts" },
- new TranscodeSettings { Container = "flac", TargetContainer = "mp3" },
- new TranscodeSettings { Container = "m4a", TargetContainer = "mp3" }
- };
-
- public static TranscodeSettings[] GetDefaultTranscodingSettings()
- {
- return DefaultTranscodingSettings;
- }
-
- /// <summary>
- /// Gets the profile settings.
- /// </summary>
- /// <param name="deviceProperties">The device properties.</param>
- /// <returns>The TranscodeSettings for the device</returns>
- public static TranscodeSettings[] GetProfileSettings(DeviceProperties deviceProperties)
- {
- foreach (var profile in PlayToConfiguration.Profiles)
- {
- if (!string.IsNullOrEmpty(profile.FriendlyName))
- {
- if (!Regex.IsMatch(deviceProperties.Name, profile.FriendlyName))
- continue;
- }
-
- if (!string.IsNullOrEmpty(profile.ModelNumber))
- {
- if (!Regex.IsMatch(deviceProperties.ModelNumber, profile.ModelNumber))
- continue;
- }
-
- if (!string.IsNullOrEmpty(profile.ModelName))
- {
- if (!Regex.IsMatch(deviceProperties.ModelName, profile.ModelName))
- continue;
- }
-
- deviceProperties.DisplayName = profile.Name;
- deviceProperties.ClientType = profile.ClientType;
- return profile.TranscodeSettings;
-
- }
-
- // Since we don't have alot of info about different devices we go down the safe
- // route abd use the default transcoding settings if no profile exist
- return GetDefaultTranscodingSettings();
- }
- }
-}
diff --git a/MediaBrowser.Dlna/PlayTo/Device.cs b/MediaBrowser.Dlna/PlayTo/Device.cs
index 690f7525b..4120c1a7f 100644
--- a/MediaBrowser.Dlna/PlayTo/Device.cs
+++ b/MediaBrowser.Dlna/PlayTo/Device.cs
@@ -1,4 +1,5 @@
using MediaBrowser.Common.Net;
+using MediaBrowser.Controller.Configuration;
using MediaBrowser.Model.Logging;
using System;
using System.Collections.Generic;
@@ -9,7 +10,7 @@ using System.Xml.Linq;
namespace MediaBrowser.Dlna.PlayTo
{
- public sealed class Device : IDisposable
+ public class Device : IDisposable
{
const string ServiceAvtransportId = "urn:upnp-org:serviceId:AVTransport";
const string ServiceRenderingId = "urn:upnp-org:serviceId:RenderingControl";
@@ -18,7 +19,7 @@ namespace MediaBrowser.Dlna.PlayTo
private Timer _timer;
- public DeviceProperties Properties { get; set; }
+ public DeviceInfo Properties { get; set; }
private int _muteVol;
public bool IsMuted
@@ -119,12 +120,14 @@ namespace MediaBrowser.Dlna.PlayTo
private readonly IHttpClient _httpClient;
private readonly ILogger _logger;
+ private readonly IServerConfigurationManager _config;
- public Device(DeviceProperties deviceProperties, IHttpClient httpClient, ILogger logger)
+ public Device(DeviceInfo deviceProperties, IHttpClient httpClient, ILogger logger, IServerConfigurationManager config)
{
Properties = deviceProperties;
_httpClient = httpClient;
_logger = logger;
+ _config = config;
}
private int GetPlaybackTimerIntervalMs()
@@ -217,7 +220,7 @@ namespace MediaBrowser.Dlna.PlayTo
throw new InvalidOperationException("Unable to find service");
}
- var result = await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, RendererCommands.BuildPost(command, service.ServiceType, value))
+ var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, RendererCommands.BuildPost(command, service.ServiceType, value))
.ConfigureAwait(false);
Volume = value;
return true;
@@ -236,7 +239,7 @@ namespace MediaBrowser.Dlna.PlayTo
throw new InvalidOperationException("Unable to find service");
}
- var result = await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, AvCommands.BuildPost(command, service.ServiceType, String.Format("{0:hh}:{0:mm}:{0:ss}", value), "REL_TIME"))
+ var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, AvCommands.BuildPost(command, service.ServiceType, String.Format("{0:hh}:{0:mm}:{0:ss}", value), "REL_TIME"))
.ConfigureAwait(false);
return value;
@@ -266,14 +269,13 @@ namespace MediaBrowser.Dlna.PlayTo
throw new InvalidOperationException("Unable to find service");
}
- var result = await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, AvCommands.BuildPost(command, service.ServiceType, url, dictionary), header)
+ var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, AvCommands.BuildPost(command, service.ServiceType, url, dictionary), header)
.ConfigureAwait(false);
- if (!IsPlaying)
- {
- await Task.Delay(50).ConfigureAwait(false);
- await SetPlay().ConfigureAwait(false);
- }
+
+ await Task.Delay(50).ConfigureAwait(false);
+ await SetPlay().ConfigureAwait(false);
+
_lapsCount = GetLapsCount();
RestartTimer();
@@ -312,7 +314,7 @@ namespace MediaBrowser.Dlna.PlayTo
throw new InvalidOperationException("Unable to find service");
}
- var result = await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, AvCommands.BuildPost(command, service.ServiceType, value, dictionary), header)
+ var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, AvCommands.BuildPost(command, service.ServiceType, value, dictionary), header)
.ConfigureAwait(false);
await Task.Delay(100).ConfigureAwait(false);
@@ -333,7 +335,7 @@ namespace MediaBrowser.Dlna.PlayTo
throw new InvalidOperationException("Unable to find service");
}
- var result = await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, RendererCommands.BuildPost(command, service.ServiceType, 1))
+ var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, RendererCommands.BuildPost(command, service.ServiceType, 1))
.ConfigureAwait(false);
_lapsCount = GetLapsCount();
@@ -348,9 +350,8 @@ namespace MediaBrowser.Dlna.PlayTo
var service = Properties.Services.FirstOrDefault(s => s.ServiceId == ServiceAvtransportId);
- var result = await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, RendererCommands.BuildPost(command, service.ServiceType, 1))
+ var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, RendererCommands.BuildPost(command, service.ServiceType, 1))
.ConfigureAwait(false);
-
await Task.Delay(50).ConfigureAwait(false);
return true;
}
@@ -363,7 +364,7 @@ namespace MediaBrowser.Dlna.PlayTo
var service = Properties.Services.FirstOrDefault(s => s.ServiceId == ServiceAvtransportId);
- var result = await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, RendererCommands.BuildPost(command, service.ServiceType, 0))
+ var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, RendererCommands.BuildPost(command, service.ServiceType, 0))
.ConfigureAwait(false);
await Task.Delay(50).ConfigureAwait(false);
@@ -442,7 +443,7 @@ namespace MediaBrowser.Dlna.PlayTo
throw new InvalidOperationException("Unable to find service");
}
- var result = await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, RendererCommands.BuildPost(command, service.ServiceType))
+ var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, RendererCommands.BuildPost(command, service.ServiceType))
.ConfigureAwait(false);
if (result == null || result.Document == null)
@@ -473,7 +474,7 @@ namespace MediaBrowser.Dlna.PlayTo
if (service == null)
return;
- var result = await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, RendererCommands.BuildPost(command, service.ServiceType))
+ var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, RendererCommands.BuildPost(command, service.ServiceType))
.ConfigureAwait(false);
if (result == null || result.Document == null)
@@ -503,7 +504,7 @@ namespace MediaBrowser.Dlna.PlayTo
throw new InvalidOperationException("Unable to find service");
}
- var result = await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, RendererCommands.BuildPost(command, service.ServiceType))
+ var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, RendererCommands.BuildPost(command, service.ServiceType))
.ConfigureAwait(false);
if (result == null || result.Document == null)
@@ -544,7 +545,7 @@ namespace MediaBrowser.Dlna.PlayTo
throw new InvalidOperationException("Unable to find service");
}
- var result = await new SsdpHttpClient(_httpClient).SendCommandAsync(Properties.BaseUrl, service, command.Name, RendererCommands.BuildPost(command, service.ServiceType))
+ var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, RendererCommands.BuildPost(command, service.ServiceType))
.ConfigureAwait(false);
if (result == null || result.Document == null)
@@ -599,13 +600,13 @@ namespace MediaBrowser.Dlna.PlayTo
if (avService == null)
return;
- var url = avService.SCPDURL;
+ var url = avService.ScpdUrl;
if (!url.Contains("/"))
url = "/dmr/" + url;
if (!url.StartsWith("/"))
url = "/" + url;
- var httpClient = new SsdpHttpClient(_httpClient);
+ var httpClient = new SsdpHttpClient(_httpClient, _config);
var document = await httpClient.GetDataAsync(new Uri(Properties.BaseUrl + url));
AvCommands = TransportCommands.Create(document);
@@ -617,13 +618,13 @@ namespace MediaBrowser.Dlna.PlayTo
if (avService == null)
return;
- string url = avService.SCPDURL;
+ string url = avService.ScpdUrl;
if (!url.Contains("/"))
url = "/dmr/" + url;
if (!url.StartsWith("/"))
url = "/" + url;
- var httpClient = new SsdpHttpClient(_httpClient);
+ var httpClient = new SsdpHttpClient(_httpClient, _config);
var document = await httpClient.GetDataAsync(new Uri(Properties.BaseUrl + url));
RendererCommands = TransportCommands.Create(document);
@@ -641,13 +642,13 @@ namespace MediaBrowser.Dlna.PlayTo
set;
}
- public static async Task<Device> CreateuPnpDeviceAsync(Uri url, IHttpClient httpClient, ILogger logger)
+ public static async Task<Device> CreateuPnpDeviceAsync(Uri url, IHttpClient httpClient, IServerConfigurationManager config, ILogger logger)
{
- var ssdpHttpClient = new SsdpHttpClient(httpClient);
+ var ssdpHttpClient = new SsdpHttpClient(httpClient, config);
var document = await ssdpHttpClient.GetDataAsync(url).ConfigureAwait(false);
- var deviceProperties = new DeviceProperties();
+ var deviceProperties = new DeviceInfo();
var name = document.Descendants(uPnpNamespaces.ud.GetName("friendlyName")).FirstOrDefault();
if (name != null)
@@ -705,7 +706,7 @@ namespace MediaBrowser.Dlna.PlayTo
foreach (var element in servicesList)
{
- var service = uService.Create(element);
+ var service = Create(element);
if (service != null)
{
@@ -721,7 +722,7 @@ namespace MediaBrowser.Dlna.PlayTo
if (isRenderer)
{
- var device = new Device(deviceProperties, httpClient, logger);
+ var device = new Device(deviceProperties, httpClient, logger, config);
await device.GetRenderingProtocolAsync().ConfigureAwait(false);
await device.GetAVProtocolAsync().ConfigureAwait(false);
@@ -734,6 +735,17 @@ namespace MediaBrowser.Dlna.PlayTo
#endregion
+ private static DeviceService Create(XElement element)
+ {
+ var type = element.GetDescendantValue(uPnpNamespaces.ud.GetName("serviceType"));
+ var id = element.GetDescendantValue(uPnpNamespaces.ud.GetName("serviceId"));
+ var scpdUrl = element.GetDescendantValue(uPnpNamespaces.ud.GetName("SCPDURL"));
+ var controlURL = element.GetDescendantValue(uPnpNamespaces.ud.GetName("controlURL"));
+ var eventSubURL = element.GetDescendantValue(uPnpNamespaces.ud.GetName("eventSubURL"));
+
+ return new DeviceService(type, id, scpdUrl, controlURL, eventSubURL);
+ }
+
#region Events
public event EventHandler<TransportStateEventArgs> PlaybackChanged;
@@ -788,4 +800,3 @@ namespace MediaBrowser.Dlna.PlayTo
}
}
-
diff --git a/MediaBrowser.Dlna/PlayTo/DeviceInfo.cs b/MediaBrowser.Dlna/PlayTo/DeviceInfo.cs
new file mode 100644
index 000000000..f952b725e
--- /dev/null
+++ b/MediaBrowser.Dlna/PlayTo/DeviceInfo.cs
@@ -0,0 +1,66 @@
+using System.Collections.Generic;
+
+namespace MediaBrowser.Dlna.PlayTo
+{
+ public class DeviceInfo
+ {
+ public DeviceInfo()
+ {
+ ClientType = "DLNA";
+ Name = "Generic Device";
+ }
+
+ public string UUID { get; set; }
+
+ public string Name { get; set; }
+
+ public string ClientType { get; set; }
+
+ private string _displayName = string.Empty;
+ public string DisplayName
+ {
+ get
+ {
+ return string.IsNullOrEmpty(_displayName) ? Name : _displayName;
+ }
+ set
+ {
+ _displayName = value;
+ }
+ }
+
+ public string ModelName { get; set; }
+
+ public string ModelNumber { get; set; }
+
+ public string Manufacturer { get; set; }
+
+ public string ManufacturerUrl { get; set; }
+
+ public string PresentationUrl { get; set; }
+
+ private string _baseUrl = string.Empty;
+ public string BaseUrl
+ {
+ get
+ {
+ return _baseUrl;
+ }
+ set
+ {
+ _baseUrl = value;
+ }
+ }
+
+ public uIcon Icon { get; set; }
+
+ private readonly List<DeviceService> _services = new List<DeviceService>();
+ public List<DeviceService> Services
+ {
+ get
+ {
+ return _services;
+ }
+ }
+ }
+}
diff --git a/MediaBrowser.Dlna/PlayTo/DeviceProperties.cs b/MediaBrowser.Dlna/PlayTo/DeviceProperties.cs
deleted file mode 100644
index 395689575..000000000
--- a/MediaBrowser.Dlna/PlayTo/DeviceProperties.cs
+++ /dev/null
@@ -1,176 +0,0 @@
-using System.Collections.Generic;
-
-namespace MediaBrowser.Dlna.PlayTo
-{
- public class DeviceProperties
- {
- private string _uuid = string.Empty;
- public string UUID
- {
- get
- {
- return _uuid;
- }
- set
- {
- _uuid = value;
- }
- }
-
- private string _name = "PlayTo 1.0.0.0";
- public string Name
- {
- get
- {
- return _name;
- }
- set
- {
- _name = value;
- }
- }
-
- private string _clientType = "DLNA";
- public string ClientType
- {
- get
- {
- return _clientType;
- }
- set
- {
- _clientType = value;
- }
- }
-
- private string _displayName = string.Empty;
- public string DisplayName
- {
- get
- {
- return string.IsNullOrEmpty(_displayName) ? _name : _displayName;
- }
- set
- {
- _displayName = value;
- }
- }
-
- private string _modelName = string.Empty;
- public string ModelName
- {
- get
- {
- return _modelName;
- }
- set
- {
- _modelName = value;
- }
- }
-
- private string _modelNumber = string.Empty;
- public string ModelNumber
- {
- get
- {
- return _modelNumber;
- }
- set
- {
- _modelNumber = value;
- }
- }
-
- private string _manufacturer = string.Empty;
- public string Manufacturer
- {
- get
- {
- return _manufacturer;
- }
- set
- {
- _manufacturer = value;
- }
- }
-
- private string _manufacturerUrl = string.Empty;
- public string ManufacturerUrl
- {
- get
- {
- return _manufacturerUrl;
- }
- set
- {
- _manufacturerUrl = value;
- }
- }
-
- private string _presentationUrl = string.Empty;
- public string PresentationUrl
- {
- get
- {
- return _presentationUrl;
- }
- set
- {
- _presentationUrl = value;
- }
- }
-
- private string _baseUrl = string.Empty;
- public string BaseUrl
- {
- get
- {
- return _baseUrl;
- }
- set
- {
- _baseUrl = value;
- }
- }
-
- private uIcon _icon;
- public uIcon Icon
- {
- get
- {
- return _icon;
- }
- set
- {
- _icon = value;
- }
- }
-
- private string _iconUrl;
- public string IconUrl
- {
- get
- {
- if (string.IsNullOrWhiteSpace(_iconUrl) && _icon != null)
- {
- if (!_icon.Url.StartsWith("/"))
- _iconUrl = _baseUrl + "/" + _icon.Url;
- else
- _iconUrl = _baseUrl + _icon.Url;
- }
-
- return _iconUrl;
- }
- }
-
- private readonly List<uService> _services = new List<uService>();
- public List<uService> Services
- {
- get
- {
- return _services;
- }
- }
- }
-}
diff --git a/MediaBrowser.Dlna/PlayTo/DeviceService.cs b/MediaBrowser.Dlna/PlayTo/DeviceService.cs
new file mode 100644
index 000000000..082128b22
--- /dev/null
+++ b/MediaBrowser.Dlna/PlayTo/DeviceService.cs
@@ -0,0 +1,30 @@
+
+namespace MediaBrowser.Dlna.PlayTo
+{
+ public class DeviceService
+ {
+ public string ServiceType { get; set; }
+
+ public string ServiceId { get; set; }
+
+ public string ScpdUrl { get; set; }
+
+ public string ControlUrl { get; set; }
+
+ public string EventSubUrl { get; set; }
+
+ public DeviceService(string serviceType, string serviceId, string scpdUrl, string controlUrl, string eventSubUrl)
+ {
+ ServiceType = serviceType;
+ ServiceId = serviceId;
+ ScpdUrl = scpdUrl;
+ ControlUrl = controlUrl;
+ EventSubUrl = eventSubUrl;
+ }
+
+ public override string ToString()
+ {
+ return string.Format("{0}", ServiceId);
+ }
+ }
+}
diff --git a/MediaBrowser.Dlna/PlayTo/DlnaController.cs b/MediaBrowser.Dlna/PlayTo/DlnaController.cs
index 2be82b985..5836a1639 100644
--- a/MediaBrowser.Dlna/PlayTo/DlnaController.cs
+++ b/MediaBrowser.Dlna/PlayTo/DlnaController.cs
@@ -1,9 +1,9 @@
using MediaBrowser.Common.Net;
+using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Session;
-using MediaBrowser.Dlna.PlayTo.Configuration;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Session;
@@ -21,13 +21,13 @@ namespace MediaBrowser.Dlna.PlayTo
{
private Device _device;
private BaseItem _currentItem = null;
- private TranscodeSettings[] _transcodeSettings;
private readonly SessionInfo _session;
private readonly ISessionManager _sessionManager;
private readonly IItemRepository _itemRepository;
private readonly ILibraryManager _libraryManager;
private readonly INetworkManager _networkManager;
private readonly ILogger _logger;
+ private readonly IDlnaManager _dlnaManager;
private bool _playbackStarted = false;
public bool SupportsMediaRemoteControl
@@ -46,19 +46,19 @@ namespace MediaBrowser.Dlna.PlayTo
}
}
- public PlayToController(SessionInfo session, ISessionManager sessionManager, IItemRepository itemRepository, ILibraryManager libraryManager, ILogger logger, INetworkManager networkManager)
+ public PlayToController(SessionInfo session, ISessionManager sessionManager, IItemRepository itemRepository, ILibraryManager libraryManager, ILogger logger, INetworkManager networkManager, IDlnaManager dlnaManager)
{
_session = session;
_itemRepository = itemRepository;
_sessionManager = sessionManager;
_libraryManager = libraryManager;
_networkManager = networkManager;
+ _dlnaManager = dlnaManager;
_logger = logger;
}
- public void Init(Device device, TranscodeSettings[] transcodeSettings)
+ public void Init(Device device)
{
- _transcodeSettings = transcodeSettings;
_device = device;
_device.PlaybackChanged += Device_PlaybackChanged;
_device.CurrentIdChanged += Device_CurrentIdChanged;
@@ -384,7 +384,9 @@ namespace MediaBrowser.Dlna.PlayTo
{
var streams = _itemRepository.GetMediaStreams(new MediaStreamQuery { ItemId = item.Id }).ToList();
- var playlistItem = PlaylistItem.GetBasicConfig(item, _transcodeSettings);
+ var deviceInfo = _device.Properties;
+
+ var playlistItem = PlaylistItem.Create(item, _dlnaManager.GetProfile(deviceInfo.Name, deviceInfo.ModelName, deviceInfo.ModelNumber));
playlistItem.StartPositionTicks = startPostionTicks;
if (playlistItem.IsAudio)
@@ -444,6 +446,7 @@ namespace MediaBrowser.Dlna.PlayTo
return true;
}
nextTrack.PlayState = 1;
+ _logger.Debug("{0} - SetAvTransport Uri: {1} DlnaHeaders: {2}", _device.Properties.Name, nextTrack.StreamUrl, nextTrack.DlnaHeaders);
await _device.SetAvTransport(nextTrack.StreamUrl, nextTrack.DlnaHeaders, nextTrack.Didl);
if (nextTrack.StartPositionTicks > 0 && !nextTrack.Transcode)
await _device.Seek(TimeSpan.FromTicks(nextTrack.StartPositionTicks));
@@ -487,4 +490,3 @@ namespace MediaBrowser.Dlna.PlayTo
}
}
}
-
diff --git a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs
index 59827b810..d1fdc9626 100644
--- a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs
+++ b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs
@@ -1,9 +1,9 @@
using MediaBrowser.Common.Net;
-using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Session;
-using MediaBrowser.Dlna.PlayTo.Configuration;
using MediaBrowser.Model.Logging;
using System;
using System.Collections.Concurrent;
@@ -29,9 +29,11 @@ namespace MediaBrowser.Dlna.PlayTo
private readonly IItemRepository _itemRepository;
private readonly ILibraryManager _libraryManager;
private readonly INetworkManager _networkManager;
- private readonly IUserManager _userManager;
+ private readonly IUserManager _userManager;
+ private readonly IDlnaManager _dlnaManager;
+ private readonly IServerConfigurationManager _config;
- public PlayToManager(ILogger logger, ISessionManager sessionManager, IHttpClient httpClient, IItemRepository itemRepository, ILibraryManager libraryManager, INetworkManager networkManager, IUserManager userManager)
+ public PlayToManager(ILogger logger, IServerConfigurationManager config, ISessionManager sessionManager, IHttpClient httpClient, IItemRepository itemRepository, ILibraryManager libraryManager, INetworkManager networkManager, IUserManager userManager, IDlnaManager dlnaManager)
{
_locations = new ConcurrentDictionary<string, DateTime>();
_tokenSource = new CancellationTokenSource();
@@ -43,6 +45,8 @@ namespace MediaBrowser.Dlna.PlayTo
_libraryManager = libraryManager;
_networkManager = networkManager;
_userManager = userManager;
+ _dlnaManager = dlnaManager;
+ _config = config;
}
public async void Start()
@@ -210,11 +214,11 @@ namespace MediaBrowser.Dlna.PlayTo
if (!IsUriValid(uri))
return;
- var device = await Device.CreateuPnpDeviceAsync(uri, _httpClient, _logger).ConfigureAwait(false);
+ var device = await Device.CreateuPnpDeviceAsync(uri, _httpClient, _config, _logger).ConfigureAwait(false);
if (device != null && device.RendererCommands != null && !_sessionManager.Sessions.Any(s => string.Equals(s.DeviceId, device.Properties.UUID) && s.IsActive))
{
- var transcodeProfiles = TranscodeSettings.GetProfileSettings(device.Properties);
+ GetProfileSettings(device.Properties);
var sessionInfo = await _sessionManager.LogSessionActivity(device.Properties.ClientType, device.Properties.Name, device.Properties.UUID, device.Properties.DisplayName, uri.OriginalString, null)
.ConfigureAwait(false);
@@ -223,30 +227,33 @@ namespace MediaBrowser.Dlna.PlayTo
if (controller == null)
{
- sessionInfo.SessionController = controller = new PlayToController(sessionInfo, _sessionManager, _itemRepository, _libraryManager, _logger, _networkManager);
+ sessionInfo.SessionController = controller = new PlayToController(sessionInfo, _sessionManager, _itemRepository, _libraryManager, _logger, _networkManager, _dlnaManager);
}
- controller.Init(device, transcodeProfiles);
-
+ controller.Init(device);
+
_logger.Info("DLNA Session created for {0} - {1}", device.Properties.Name, device.Properties.ModelName);
}
}
- const string DefaultUser = "Play To";
- private async Task<User> GetPlayToUser()
+ /// <summary>
+ /// Gets the profile settings.
+ /// </summary>
+ /// <param name="deviceProperties">The device properties.</param>
+ /// <returns>The TranscodeSettings for the device</returns>
+ private void GetProfileSettings(DeviceInfo deviceProperties)
{
- var user = _userManager.Users.FirstOrDefault(u => string.Equals(DefaultUser, u.Name, StringComparison.OrdinalIgnoreCase));
+ var profile = _dlnaManager.GetProfile(deviceProperties.DisplayName, deviceProperties.ModelName,
+ deviceProperties.ModelNumber);
- if (user == null)
+ if (!string.IsNullOrWhiteSpace(profile.Name))
{
- user = await _userManager.CreateUser(DefaultUser);
-
- user.Configuration.IsHidden = true;
- user.Configuration.IsAdministrator = false;
- user.SaveConfiguration();
+ deviceProperties.DisplayName = profile.Name;
+ }
+ if (!string.IsNullOrWhiteSpace(profile.ClientType))
+ {
+ deviceProperties.ClientType = profile.ClientType;
}
-
- return user;
}
/// <summary>
diff --git a/MediaBrowser.Dlna/PlayTo/PlayToServerEntryPoint.cs b/MediaBrowser.Dlna/PlayTo/PlayToServerEntryPoint.cs
index a6746cfc5..a7afeab3c 100644
--- a/MediaBrowser.Dlna/PlayTo/PlayToServerEntryPoint.cs
+++ b/MediaBrowser.Dlna/PlayTo/PlayToServerEntryPoint.cs
@@ -1,5 +1,6 @@
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Plugins;
@@ -11,7 +12,7 @@ namespace MediaBrowser.Dlna.PlayTo
{
public class PlayToServerEntryPoint : IServerEntryPoint
{
- private PlayToManager _manager;
+ private PlayToManager _manager;
private readonly IServerConfigurationManager _config;
private readonly ILogger _logger;
private readonly ISessionManager _sessionManager;
@@ -20,8 +21,9 @@ namespace MediaBrowser.Dlna.PlayTo
private readonly ILibraryManager _libraryManager;
private readonly INetworkManager _networkManager;
private readonly IUserManager _userManager;
+ private readonly IDlnaManager _dlnaManager;
- public PlayToServerEntryPoint(ILogManager logManager, IServerConfigurationManager config, ISessionManager sessionManager, IHttpClient httpClient, IItemRepository itemRepo, ILibraryManager libraryManager, INetworkManager networkManager, IUserManager userManager)
+ public PlayToServerEntryPoint(ILogManager logManager, IServerConfigurationManager config, ISessionManager sessionManager, IHttpClient httpClient, IItemRepository itemRepo, ILibraryManager libraryManager, INetworkManager networkManager, IUserManager userManager, IDlnaManager dlnaManager)
{
_config = config;
_sessionManager = sessionManager;
@@ -30,12 +32,14 @@ namespace MediaBrowser.Dlna.PlayTo
_libraryManager = libraryManager;
_networkManager = networkManager;
_userManager = userManager;
+ _dlnaManager = dlnaManager;
_logger = logManager.GetLogger("PlayTo");
}
public void Run()
{
_config.ConfigurationUpdated += ConfigurationUpdated;
+
ReloadPlayToManager();
}
@@ -65,7 +69,7 @@ namespace MediaBrowser.Dlna.PlayTo
{
try
{
- _manager = new PlayToManager(_logger, _sessionManager, _httpClient, _itemRepo, _libraryManager, _networkManager, _userManager);
+ _manager = new PlayToManager(_logger, _config, _sessionManager, _httpClient, _itemRepo, _libraryManager, _networkManager, _userManager, _dlnaManager);
_manager.Start();
}
catch (Exception ex)
@@ -95,13 +99,9 @@ namespace MediaBrowser.Dlna.PlayTo
}
}
- #region Dispose
-
public void Dispose()
{
DisposePlayToManager();
}
-
- #endregion
}
}
diff --git a/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs b/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs
index 6523eb9f5..cfb2c7d1c 100644
--- a/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs
+++ b/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs
@@ -1,6 +1,9 @@
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Dlna.PlayTo.Configuration;
+using MediaBrowser.Controller.Dlna;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Model.Entities;
using System;
+using System.IO;
+using System.Linq;
namespace MediaBrowser.Dlna.PlayTo
{
@@ -28,84 +31,71 @@ namespace MediaBrowser.Dlna.PlayTo
public long StartPositionTicks { get; set; }
- public static PlaylistItem GetBasicConfig(BaseItem item, TranscodeSettings[] profileTranscodings)
+ public static PlaylistItem Create(BaseItem item, DlnaProfile profile)
{
+ var playlistItem = new PlaylistItem
+ {
+ ItemId = item.Id.ToString()
+ };
- var playlistItem = new PlaylistItem();
- playlistItem.ItemId = item.Id.ToString();
-
- if (string.Equals(item.MediaType, Model.Entities.MediaType.Video, StringComparison.OrdinalIgnoreCase))
+ DlnaProfileType profileType;
+ if (string.Equals(item.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase))
{
playlistItem.IsVideo = true;
+ profileType = DlnaProfileType.Video;
}
else
{
playlistItem.IsAudio = true;
+ profileType = DlnaProfileType.Audio;
}
+ var path = item.Path;
- var path = item.Path.ToLower();
+ var directPlay = profile.DirectPlayProfiles.FirstOrDefault(i => i.Type == profileType && IsSupported(i, path));
- //Check the DlnaProfile associated with the renderer
- if (profileTranscodings != null)
+ if (directPlay != null)
{
- foreach (TranscodeSettings transcodeSetting in profileTranscodings)
- {
- if (string.IsNullOrWhiteSpace(transcodeSetting.Container))
- continue;
- if (path.EndsWith(transcodeSetting.Container) && !string.IsNullOrWhiteSpace(transcodeSetting.TargetContainer))
- {
- playlistItem.Transcode = true;
- playlistItem.FileFormat = transcodeSetting.TargetContainer;
-
- if (string.IsNullOrWhiteSpace(transcodeSetting.MimeType))
- playlistItem.MimeType = transcodeSetting.MimeType;
-
- return playlistItem;
- }
- if (path.EndsWith(transcodeSetting.Container) && !string.IsNullOrWhiteSpace(transcodeSetting.MimeType))
- {
- playlistItem.Transcode = false;
- playlistItem.FileFormat = transcodeSetting.Container;
- playlistItem.MimeType = transcodeSetting.MimeType;
- return playlistItem;
- }
- }
+ playlistItem.Transcode = false;
+ playlistItem.FileFormat = Path.GetExtension(path);
+ playlistItem.MimeType = directPlay.MimeType;
+ return playlistItem;
}
- if (playlistItem.IsVideo)
- {
- //Check to see if we support serving the format statically
- foreach (string supported in PlayToConfiguration.SupportedStaticFormats)
- {
- if (path.EndsWith(supported))
- {
- playlistItem.Transcode = false;
- playlistItem.FileFormat = supported;
- return playlistItem;
- }
- }
+ var transcodingProfile = profile.TranscodingProfiles.FirstOrDefault(i => i.Type == profileType && IsSupported(profile, i, path));
- playlistItem.Transcode = true;
- playlistItem.FileFormat = "ts";
- }
- else
+ if (transcodingProfile != null)
{
- foreach (string supported in PlayToConfiguration.SupportedStaticFormats)
- {
- if (path.EndsWith(supported))
- {
- playlistItem.Transcode = false;
- playlistItem.FileFormat = supported;
- return playlistItem;
- }
- }
-
playlistItem.Transcode = true;
- playlistItem.FileFormat = "mp3";
+ //Just to make sure we have a "." for the url, remove it in case a user adds it or not
+ playlistItem.FileFormat = "." + transcodingProfile.Container.TrimStart('.');
+
+ playlistItem.MimeType = transcodingProfile.MimeType;
}
return playlistItem;
}
+
+ private static bool IsSupported(DirectPlayProfile profile, string path)
+ {
+ var mediaContainer = Path.GetExtension(path);
+
+ if (!profile.Containers.Any(i => string.Equals("." + i.TrimStart('.'), mediaContainer, StringComparison.OrdinalIgnoreCase)))
+ {
+ return false;
+ }
+
+ // Placeholder for future conditions
+
+ // TODO: Support codec list as additional restriction
+
+ return true;
+ }
+
+ private static bool IsSupported(DlnaProfile profile, TranscodingProfile transcodingProfile, string path)
+ {
+ // Placeholder for future conditions
+ return true;
+ }
}
-}
+} \ No newline at end of file
diff --git a/MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs b/MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs
index 7179ef762..7a4928e5c 100644
--- a/MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs
+++ b/MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs
@@ -1,4 +1,5 @@
using MediaBrowser.Common.Net;
+using MediaBrowser.Controller.Configuration;
using System;
using System.IO;
using System.Net;
@@ -16,15 +17,17 @@ namespace MediaBrowser.Dlna.PlayTo
private static readonly CookieContainer Container = new CookieContainer();
private readonly IHttpClient _httpClient;
+ private readonly IServerConfigurationManager _config;
- public SsdpHttpClient(IHttpClient httpClient)
+ public SsdpHttpClient(IHttpClient httpClient, IServerConfigurationManager config)
{
_httpClient = httpClient;
+ _config = config;
}
- public async Task<XDocument> SendCommandAsync(string baseUrl, uService service, string command, string postData, string header = null)
+ public async Task<XDocument> SendCommandAsync(string baseUrl, DeviceService service, string command, string postData, string header = null)
{
- var serviceUrl = service.ControlURL;
+ var serviceUrl = service.ControlUrl;
if (!serviceUrl.StartsWith("/"))
serviceUrl = "/" + serviceUrl;
@@ -45,7 +48,8 @@ namespace MediaBrowser.Dlna.PlayTo
var options = new HttpRequestOptions
{
Url = url.ToString(),
- UserAgent = USERAGENT
+ UserAgent = USERAGENT,
+ LogRequest = _config.Configuration.DlnaOptions.EnablePlayToDebugLogging
};
options.RequestHeaders["HOST"] = ip + ":" + port;
@@ -83,7 +87,8 @@ namespace MediaBrowser.Dlna.PlayTo
var options = new HttpRequestOptions
{
Url = url.ToString(),
- UserAgent = USERAGENT
+ UserAgent = USERAGENT,
+ LogRequest = _config.Configuration.DlnaOptions.EnablePlayToDebugLogging
};
options.RequestHeaders["FriendlyName.DLNA.ORG"] = FriendlyName;
@@ -106,7 +111,8 @@ namespace MediaBrowser.Dlna.PlayTo
var options = new HttpRequestOptions
{
Url = url.ToString(),
- UserAgent = USERAGENT
+ UserAgent = USERAGENT,
+ LogRequest = _config.Configuration.DlnaOptions.EnablePlayToDebugLogging
};
options.RequestHeaders["SOAPAction"] = soapAction;
diff --git a/MediaBrowser.Dlna/PlayTo/StreamHelper.cs b/MediaBrowser.Dlna/PlayTo/StreamHelper.cs
index 3492ed182..ea95ea8e6 100644
--- a/MediaBrowser.Dlna/PlayTo/StreamHelper.cs
+++ b/MediaBrowser.Dlna/PlayTo/StreamHelper.cs
@@ -77,7 +77,7 @@ namespace MediaBrowser.Dlna.PlayTo
internal static string GetAudioUrl(PlaylistItem item, string serverAddress)
{
if (!item.Transcode)
- return string.Format("{0}/audio/{1}/stream.{2}?Static=True", serverAddress, item.ItemId, item.FileFormat);
+ return string.Format("{0}/audio/{1}/stream{2}?Static=True", serverAddress, item.ItemId, item.FileFormat);
return string.Format("{0}/audio/{1}/stream.mp3?AudioCodec=Mp3", serverAddress, item.ItemId);
}
@@ -94,13 +94,13 @@ namespace MediaBrowser.Dlna.PlayTo
/// <param name="streams">The streams.</param>
/// <param name="serverAddress">The server address.</param>
/// <returns>The url to send to the device</returns>
- internal static string GetVideoUrl(DeviceProperties deviceProperties, PlaylistItem item, List<MediaStream> streams, string serverAddress)
+ internal static string GetVideoUrl(DeviceInfo deviceProperties, PlaylistItem item, List<MediaStream> streams, string serverAddress)
{
string dlnaCommand = string.Empty;
if (!item.Transcode)
{
dlnaCommand = BuildDlnaUrl(deviceProperties.UUID, !item.Transcode, null, null, null, null, null, null, null, null, null, null, item.MimeType);
- return string.Format("{0}/Videos/{1}/stream.{2}?{3}", serverAddress, item.ItemId, item.FileFormat, dlnaCommand);
+ return string.Format("{0}/Videos/{1}/stream{2}?{3}", serverAddress, item.ItemId, item.FileFormat, dlnaCommand);
}
var videostream = streams.Where(m => m.Type == MediaStreamType.Video).OrderBy(m => m.IsDefault).FirstOrDefault();
var audiostream = streams.Where(m => m.Type == MediaStreamType.Audio).OrderBy(m => m.IsDefault).FirstOrDefault();
@@ -121,7 +121,7 @@ namespace MediaBrowser.Dlna.PlayTo
}
dlnaCommand = BuildDlnaUrl(deviceProperties.UUID, !item.Transcode, videoCodec, audioCodec, null, null, videoBitrate, audioChannels, audioBitrate, item.StartPositionTicks, "baseline", "3", item.MimeType);
- return string.Format("{0}/Videos/{1}/stream.{2}?{3}", serverAddress, item.ItemId, item.FileFormat, dlnaCommand);
+ return string.Format("{0}/Videos/{1}/stream{2}?{3}", serverAddress, item.ItemId, item.FileFormat, dlnaCommand);
}
/// <summary>
@@ -189,4 +189,4 @@ namespace MediaBrowser.Dlna.PlayTo
#endregion
}
-}
+} \ No newline at end of file
diff --git a/MediaBrowser.Dlna/PlayTo/uService.cs b/MediaBrowser.Dlna/PlayTo/uService.cs
deleted file mode 100644
index 08bdf18fc..000000000
--- a/MediaBrowser.Dlna/PlayTo/uService.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-using System.Xml.Linq;
-
-namespace MediaBrowser.Dlna.PlayTo
-{
- public class uService
- {
- public string ServiceType { get; set; }
-
- public string ServiceId { get; set; }
-
- public string SCPDURL { get; set; }
-
- public string ControlURL { get; set; }
-
- public string EventSubURL { get; set; }
-
- public uService(string serviceType, string serviceId, string scpdUrl, string controlUrl, string eventSubUrl)
- {
- ServiceType = serviceType;
- ServiceId = serviceId;
- SCPDURL = scpdUrl;
- ControlURL = controlUrl;
- EventSubURL = eventSubUrl;
- }
-
- public static uService Create(XElement element)
- {
- var type = element.GetDescendantValue(uPnpNamespaces.ud.GetName("serviceType"));
- var id = element.GetDescendantValue(uPnpNamespaces.ud.GetName("serviceId"));
- var scpdUrl = element.GetDescendantValue(uPnpNamespaces.ud.GetName("SCPDURL"));
- var controlURL = element.GetDescendantValue(uPnpNamespaces.ud.GetName("controlURL"));
- var eventSubURL = element.GetDescendantValue(uPnpNamespaces.ud.GetName("eventSubURL"));
-
- return new uService(type, id, scpdUrl, controlURL, eventSubURL);
- }
-
- public override string ToString()
- {
- return string.Format("{0}", ServiceId);
- }
- }
-}
diff --git a/MediaBrowser.Model/Configuration/DlnaOptions.cs b/MediaBrowser.Model/Configuration/DlnaOptions.cs
index e6c24fdfb..67145e664 100644
--- a/MediaBrowser.Model/Configuration/DlnaOptions.cs
+++ b/MediaBrowser.Model/Configuration/DlnaOptions.cs
@@ -4,5 +4,6 @@ namespace MediaBrowser.Model.Configuration
public class DlnaOptions
{
public bool EnablePlayTo { get; set; }
+ public bool EnablePlayToDebugLogging { get; set; }
}
}
diff --git a/MediaBrowser.Model/Configuration/UserConfiguration.cs b/MediaBrowser.Model/Configuration/UserConfiguration.cs
index 3df25425d..2145860c7 100644
--- a/MediaBrowser.Model/Configuration/UserConfiguration.cs
+++ b/MediaBrowser.Model/Configuration/UserConfiguration.cs
@@ -57,8 +57,6 @@ namespace MediaBrowser.Model.Configuration
public UnratedItem[] BlockUnratedItems { get; set; }
- public bool DisplayMovieFormatRibbons { get; set; }
-
/// <summary>
/// Initializes a new instance of the <see cref="UserConfiguration" /> class.
/// </summary>
diff --git a/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs b/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs
index 43ee7bdbc..e36d8a320 100644
--- a/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs
+++ b/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs
@@ -7,6 +7,7 @@ using MediaBrowser.Model.Providers;
using System;
using System.Collections.Generic;
using System.IO;
+using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
@@ -31,9 +32,86 @@ namespace MediaBrowser.Providers.Music
public async Task<IEnumerable<RemoteSearchResult>> GetSearchResults(AlbumInfo searchInfo, CancellationToken cancellationToken)
{
+ var releaseId = searchInfo.GetReleaseId();
+
+ string url = null;
+
+ if (!string.IsNullOrEmpty(releaseId))
+ {
+ url = string.Format("http://www.musicbrainz.org/ws/2/release/?query=reid:{0}", releaseId);
+ }
+ else
+ {
+ var artistMusicBrainzId = searchInfo.GetMusicBrainzArtistId();
+
+ if (!string.IsNullOrWhiteSpace(artistMusicBrainzId))
+ {
+ url = string.Format("http://www.musicbrainz.org/ws/2/release/?query=\"{0}\" AND arid:{1}",
+ WebUtility.UrlEncode(searchInfo.Name),
+ artistMusicBrainzId);
+ }
+ else
+ {
+ url = string.Format("http://www.musicbrainz.org/ws/2/release/?query=\"{0}\" AND artist:\"{1}\"",
+ WebUtility.UrlEncode(searchInfo.Name),
+ WebUtility.UrlEncode(searchInfo.GetAlbumArtist()));
+ }
+ }
+
+ if (!string.IsNullOrWhiteSpace(url))
+ {
+ var doc = await GetMusicBrainzResponse(url, cancellationToken).ConfigureAwait(false);
+
+ return GetResultsFromResponse(doc);
+ }
+
return new List<RemoteSearchResult>();
}
+ private IEnumerable<RemoteSearchResult> GetResultsFromResponse(XmlDocument doc)
+ {
+ var ns = new XmlNamespaceManager(doc.NameTable);
+ ns.AddNamespace("mb", "http://musicbrainz.org/ns/mmd-2.0#");
+
+ var list = new List<RemoteSearchResult>();
+
+ var nodes = doc.SelectNodes("//mb:release-list/mb:release", ns);
+
+ if (nodes != null)
+ {
+ foreach (var node in nodes.Cast<XmlNode>())
+ {
+ if (node.Attributes != null)
+ {
+ string name = null;
+
+ string mbzId = node.Attributes["id"].Value;
+
+ var nameNode = node.SelectSingleNode("//mb:title", ns);
+
+ if (nameNode != null)
+ {
+ name = nameNode.InnerText;
+ }
+
+ if (!string.IsNullOrWhiteSpace(mbzId) && !string.IsNullOrWhiteSpace(name))
+ {
+ var result = new RemoteSearchResult
+ {
+ Name = name
+ };
+
+ result.SetProviderId(MetadataProviders.MusicBrainzAlbum, mbzId);
+
+ list.Add(result);
+ }
+ }
+ }
+ }
+
+ return list;
+ }
+
public async Task<MetadataResult<MusicAlbum>> GetMetadata(AlbumInfo id, CancellationToken cancellationToken)
{
var releaseId = id.GetReleaseId();
@@ -146,7 +224,7 @@ namespace MediaBrowser.Providers.Music
{
result.ReleaseGroupId = releaseGroupIdNode.Value;
}
-
+
return result;
}
diff --git a/MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs b/MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs
index 7c0233d3e..12a1bdd35 100644
--- a/MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs
+++ b/MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs
@@ -19,70 +19,120 @@ namespace MediaBrowser.Providers.Music
{
public async Task<IEnumerable<RemoteSearchResult>> GetSearchResults(ArtistInfo searchInfo, CancellationToken cancellationToken)
{
- return new List<RemoteSearchResult>();
- }
-
- public async Task<MetadataResult<MusicArtist>> GetMetadata(ArtistInfo id, CancellationToken cancellationToken)
- {
- var result = new MetadataResult<MusicArtist>();
-
- var musicBrainzId = id.GetMusicBrainzArtistId() ?? await FindId(id, cancellationToken).ConfigureAwait(false);
+ var musicBrainzId = searchInfo.GetMusicBrainzArtistId();
if (!string.IsNullOrWhiteSpace(musicBrainzId))
{
- cancellationToken.ThrowIfCancellationRequested();
+ var url = string.Format("http://www.musicbrainz.org/ws/2/artist/?query=arid:{0}", musicBrainzId);
- result.Item = new MusicArtist();
- result.HasMetadata = true;
+ var doc = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, cancellationToken)
+ .ConfigureAwait(false);
- result.Item.SetProviderId(MetadataProviders.MusicBrainzArtist, musicBrainzId);
+ return GetResultsFromResponse(doc);
}
+ else
+ {
+ // They seem to throw bad request failures on any term with a slash
+ var nameToSearch = searchInfo.Name.Replace('/', ' ');
- return result;
- }
-
- /// <summary>
- /// Finds the id from music brainz.
- /// </summary>
- /// <param name="item">The item.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>Task{System.String}.</returns>
- private async Task<string> FindId(ItemLookupInfo item, CancellationToken cancellationToken)
- {
- // They seem to throw bad request failures on any term with a slash
- var nameToSearch = item.Name.Replace('/', ' ');
+ var url = String.Format("http://www.musicbrainz.org/ws/2/artist/?query=artist:\"{0}\"", UrlEncode(nameToSearch));
+
+ var doc = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, cancellationToken).ConfigureAwait(false);
+
+ var results = GetResultsFromResponse(doc).ToList();
+
+ if (results.Count > 0)
+ {
+ return results;
+ }
- var url = String.Format("http://www.musicbrainz.org/ws/2/artist/?query=artist:\"{0}\"", UrlEncode(nameToSearch));
+ if (HasDiacritics(searchInfo.Name))
+ {
+ // Try again using the search with accent characters url
+ url = String.Format("http://www.musicbrainz.org/ws/2/artist/?query=artistaccent:\"{0}\"", UrlEncode(nameToSearch));
+
+ doc = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, cancellationToken).ConfigureAwait(false);
+
+ return GetResultsFromResponse(doc);
+ }
+ }
- var doc = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, cancellationToken).ConfigureAwait(false);
+ return new List<RemoteSearchResult>();
+ }
+ private IEnumerable<RemoteSearchResult> GetResultsFromResponse(XmlDocument doc)
+ {
var ns = new XmlNamespaceManager(doc.NameTable);
ns.AddNamespace("mb", "http://musicbrainz.org/ns/mmd-2.0#");
- var node = doc.SelectSingleNode("//mb:artist-list/mb:artist/@id", ns);
- if (node != null && node.Value != null)
+ var list = new List<RemoteSearchResult>();
+
+ var nodes = doc.SelectNodes("//mb:artist-list/mb:artist", ns);
+
+ if (nodes != null)
{
- return node.Value;
+ foreach (var node in nodes.Cast<XmlNode>())
+ {
+ if (node.Attributes != null)
+ {
+ string name = null;
+
+ string mbzId = node.Attributes["id"].Value;
+
+ var nameNode = node.SelectSingleNode("//mb:name", ns);
+
+ if (nameNode != null)
+ {
+ name = nameNode.InnerText;
+ }
+
+ if (!string.IsNullOrWhiteSpace(mbzId) && !string.IsNullOrWhiteSpace(name))
+ {
+ var result = new RemoteSearchResult
+ {
+ Name = name
+ };
+
+ result.SetProviderId(MetadataProviders.MusicBrainzArtist, mbzId);
+
+ list.Add(result);
+ }
+ }
+ }
}
- if (HasDiacritics(item.Name))
+ return list;
+ }
+
+ public async Task<MetadataResult<MusicArtist>> GetMetadata(ArtistInfo id, CancellationToken cancellationToken)
+ {
+ var result = new MetadataResult<MusicArtist>
{
- // Try again using the search with accent characters url
- url = String.Format("http://www.musicbrainz.org/ws/2/artist/?query=artistaccent:\"{0}\"", UrlEncode(nameToSearch));
+ Item = new MusicArtist()
+ };
- doc = await MusicBrainzAlbumProvider.Current.GetMusicBrainzResponse(url, cancellationToken).ConfigureAwait(false);
+ var musicBrainzId = id.GetMusicBrainzArtistId();
- ns = new XmlNamespaceManager(doc.NameTable);
- ns.AddNamespace("mb", "http://musicbrainz.org/ns/mmd-2.0#");
- node = doc.SelectSingleNode("//mb:artist-list/mb:artist/@id", ns);
+ if (string.IsNullOrWhiteSpace(musicBrainzId))
+ {
+ var searchResults = await GetSearchResults(id, cancellationToken).ConfigureAwait(false);
+
+ var singleResult = searchResults.FirstOrDefault();
- if (node != null && node.Value != null)
+ if (singleResult != null)
{
- return node.Value;
+ musicBrainzId = singleResult.GetProviderId(MetadataProviders.MusicBrainzArtist);
+ result.Item.Name = singleResult.Name;
}
}
- return null;
+ if (!string.IsNullOrWhiteSpace(musicBrainzId))
+ {
+ result.HasMetadata = true;
+ result.Item.SetProviderId(MetadataProviders.MusicBrainzArtist, musicBrainzId);
+ }
+
+ return result;
}
/// <summary>
diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs
index e9aebb6d2..32932fe0b 100644
--- a/MediaBrowser.ServerApplication/ApplicationHost.cs
+++ b/MediaBrowser.ServerApplication/ApplicationHost.cs
@@ -11,6 +11,7 @@ using MediaBrowser.Common.Progress;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Collections;
using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
@@ -29,6 +30,7 @@ using MediaBrowser.Controller.Resolvers;
using MediaBrowser.Controller.Session;
using MediaBrowser.Controller.Sorting;
using MediaBrowser.Controller.Themes;
+using MediaBrowser.Dlna;
using MediaBrowser.Dlna.PlayTo;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.MediaInfo;
@@ -490,6 +492,9 @@ namespace MediaBrowser.ServerApplication
var appThemeManager = new AppThemeManager(ApplicationPaths, FileSystemManager, JsonSerializer, Logger);
RegisterSingleInstance<IAppThemeManager>(appThemeManager);
+ var dlnaManager = new DlnaManager();
+ RegisterSingleInstance<IDlnaManager>(dlnaManager);
+
var collectionManager = new CollectionManager(LibraryManager, FileSystemManager, LibraryMonitor);
RegisterSingleInstance<ICollectionManager>(collectionManager);
diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec
index 3e548e625..9ffd2c3e2 100644
--- a/Nuget/MediaBrowser.Common.Internal.nuspec
+++ b/Nuget/MediaBrowser.Common.Internal.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common.Internal</id>
- <version>3.0.339</version>
+ <version>3.0.340</version>
<title>MediaBrowser.Common.Internal</title>
<authors>Luke</authors>
<owners>ebr,Luke,scottisafool</owners>
@@ -12,7 +12,7 @@
<description>Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption.</description>
<copyright>Copyright © Media Browser 2013</copyright>
<dependencies>
- <dependency id="MediaBrowser.Common" version="3.0.339" />
+ <dependency id="MediaBrowser.Common" version="3.0.340" />
<dependency id="NLog" version="2.1.0" />
<dependency id="SimpleInjector" version="2.4.1" />
<dependency id="sharpcompress" version="0.10.2" />
diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec
index 5b81a046e..49d410c57 100644
--- a/Nuget/MediaBrowser.Common.nuspec
+++ b/Nuget/MediaBrowser.Common.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common</id>
- <version>3.0.339</version>
+ <version>3.0.340</version>
<title>MediaBrowser.Common</title>
<authors>Media Browser Team</authors>
<owners>ebr,Luke,scottisafool</owners>
diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec
index bf8bfd157..acbce81ae 100644
--- a/Nuget/MediaBrowser.Server.Core.nuspec
+++ b/Nuget/MediaBrowser.Server.Core.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>MediaBrowser.Server.Core</id>
- <version>3.0.339</version>
+ <version>3.0.340</version>
<title>Media Browser.Server.Core</title>
<authors>Media Browser Team</authors>
<owners>ebr,Luke,scottisafool</owners>
@@ -12,7 +12,7 @@
<description>Contains core components required to build plugins for Media Browser Server.</description>
<copyright>Copyright © Media Browser 2013</copyright>
<dependencies>
- <dependency id="MediaBrowser.Common" version="3.0.339" />
+ <dependency id="MediaBrowser.Common" version="3.0.340" />
</dependencies>
</metadata>
<files>