aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MediaBrowser.Api/AppThemeService.cs14
-rw-r--r--MediaBrowser.Api/BaseApiService.cs15
-rw-r--r--MediaBrowser.Api/ChannelService.cs6
-rw-r--r--MediaBrowser.Api/ConfigurationService.cs15
-rw-r--r--MediaBrowser.Api/DlnaService.cs90
-rw-r--r--MediaBrowser.Api/Images/ImageService.cs10
-rw-r--r--MediaBrowser.Api/Library/LibraryService.cs12
-rw-r--r--MediaBrowser.Api/LiveTv/LiveTvService.cs72
-rw-r--r--MediaBrowser.Api/MediaBrowser.Api.csproj2
-rw-r--r--MediaBrowser.Api/Movies/MoviesService.cs6
-rw-r--r--MediaBrowser.Api/Movies/TrailersService.cs3
-rw-r--r--MediaBrowser.Api/Music/InstantMixService.cs12
-rw-r--r--MediaBrowser.Api/Playback/BaseStreamingService.cs43
-rw-r--r--MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs44
-rw-r--r--MediaBrowser.Api/Playback/Progressive/VideoService.cs5
-rw-r--r--MediaBrowser.Api/Playback/StreamRequest.cs3
-rw-r--r--MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs17
-rw-r--r--MediaBrowser.Api/UserLibrary/StudiosService.cs7
-rw-r--r--MediaBrowser.Api/UserLibrary/UserLibraryService.cs19
-rw-r--r--MediaBrowser.Api/WebSocket/SessionInfoWebSocketListener.cs2
-rw-r--r--MediaBrowser.Controller/Dlna/CodecProfile.cs16
-rw-r--r--MediaBrowser.Controller/Dlna/ContainerProfile.cs4
-rw-r--r--MediaBrowser.Controller/Dlna/DeviceIdentification.cs7
-rw-r--r--MediaBrowser.Controller/Dlna/DeviceProfile.cs55
-rw-r--r--MediaBrowser.Controller/Dlna/DirectPlayProfile.cs7
-rw-r--r--MediaBrowser.Controller/Dlna/IDlnaManager.cs42
-rw-r--r--MediaBrowser.Controller/Dlna/MediaProfile.cs11
-rw-r--r--MediaBrowser.Controller/Dlna/TranscodingProfile.cs14
-rw-r--r--MediaBrowser.Controller/Entities/Trailer.cs19
-rw-r--r--MediaBrowser.Controller/Entities/User.cs5
-rw-r--r--MediaBrowser.Controller/MediaEncoding/InternalMediaInfoResult.cs16
-rw-r--r--MediaBrowser.Controller/MediaEncoding/MediaEncoderHelpers.cs32
-rw-r--r--MediaBrowser.Dlna/DlnaManager.cs259
-rw-r--r--MediaBrowser.Dlna/MediaBrowser.Dlna.csproj22
-rw-r--r--MediaBrowser.Dlna/PlayTo/CurrentIdEventArgs.cs14
-rw-r--r--MediaBrowser.Dlna/PlayTo/Device.cs7
-rw-r--r--MediaBrowser.Dlna/PlayTo/DlnaController.cs39
-rw-r--r--MediaBrowser.Dlna/PlayTo/PlayToManager.cs6
-rw-r--r--MediaBrowser.Dlna/PlayTo/PlaylistItem.cs2
-rw-r--r--MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs8
-rw-r--r--MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs24
-rw-r--r--MediaBrowser.Dlna/PlayTo/StreamHelper.cs5
-rw-r--r--MediaBrowser.Dlna/Profiles/DefaultProfile.cs3
-rw-r--r--MediaBrowser.Dlna/Profiles/DenonAvrProfile.cs4
-rw-r--r--MediaBrowser.Dlna/Profiles/Foobar2000Profile.cs4
-rw-r--r--MediaBrowser.Dlna/Profiles/LgTvProfile.cs4
-rw-r--r--MediaBrowser.Dlna/Profiles/LinksysDMA2100Profile.cs4
-rw-r--r--MediaBrowser.Dlna/Profiles/PanasonicVieraProfile.cs36
-rw-r--r--MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs6
-rw-r--r--MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2013Profile.cs4
-rw-r--r--MediaBrowser.Dlna/Profiles/SonyBlurayPlayerProfile.cs4
-rw-r--r--MediaBrowser.Dlna/Profiles/SonyBravia2010Profile.cs19
-rw-r--r--MediaBrowser.Dlna/Profiles/SonyBravia2011Profile.cs19
-rw-r--r--MediaBrowser.Dlna/Profiles/SonyBravia2012Profile.cs19
-rw-r--r--MediaBrowser.Dlna/Profiles/SonyBravia2013Profile.cs19
-rw-r--r--MediaBrowser.Dlna/Profiles/SonyPs3Profile.cs4
-rw-r--r--MediaBrowser.Dlna/Profiles/WdtvLiveProfile.cs2
-rw-r--r--MediaBrowser.Dlna/Profiles/Xbox360Profile.cs4
-rw-r--r--MediaBrowser.Dlna/Profiles/XboxOneProfile.cs4
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Default.xml41
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml45
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml73
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml45
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml66
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml102
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml69
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml97
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml100
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml103
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml86
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml86
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml94
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml80
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml105
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml47
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml47
-rw-r--r--MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj3
-rw-r--r--MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj3
-rw-r--r--MediaBrowser.Model/Configuration/ServerConfiguration.cs6
-rw-r--r--MediaBrowser.Model/Configuration/UserConfiguration.cs4
-rw-r--r--MediaBrowser.Model/Dlna/DeviceProfileInfo.cs30
-rw-r--r--MediaBrowser.Model/Entities/MediaStream.cs6
-rw-r--r--MediaBrowser.Model/MediaBrowser.Model.csproj1
-rw-r--r--MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs19
-rw-r--r--MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs27
-rw-r--r--MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs32
-rw-r--r--MediaBrowser.Server.Implementations/Library/UserManager.cs58
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs7
-rw-r--r--MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs90
-rw-r--r--MediaBrowser.Server.Implementations/ServerApplicationPaths.cs12
-rw-r--r--MediaBrowser.ServerApplication/ApplicationHost.cs12
-rw-r--r--MediaBrowser.WebDashboard/Api/DashboardInfo.cs39
-rw-r--r--MediaBrowser.WebDashboard/Api/DashboardInfoWebSocketListener.cs62
-rw-r--r--MediaBrowser.WebDashboard/Api/DashboardService.cs72
-rw-r--r--MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj28
95 files changed, 2321 insertions, 646 deletions
diff --git a/MediaBrowser.Api/AppThemeService.cs b/MediaBrowser.Api/AppThemeService.cs
index 54141b3e2..4d8eed7dd 100644
--- a/MediaBrowser.Api/AppThemeService.cs
+++ b/MediaBrowser.Api/AppThemeService.cs
@@ -9,16 +9,14 @@ using System.Linq;
namespace MediaBrowser.Api
{
- [Route("/Themes", "GET")]
- [Api(Description = "Gets a list of available themes for an app")]
+ [Route("/Themes", "GET", Summary = "Gets a list of available themes for an app")]
public class GetAppThemes : IReturn<List<AppThemeInfo>>
{
[ApiMember(Name = "App", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
public string App { get; set; }
}
- [Route("/Themes/Info", "GET")]
- [Api(Description = "Gets an app theme")]
+ [Route("/Themes/Info", "GET", Summary = "Gets an app theme")]
public class GetAppTheme : IReturn<AppTheme>
{
[ApiMember(Name = "App", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
@@ -28,8 +26,7 @@ namespace MediaBrowser.Api
public string Name { get; set; }
}
- [Route("/Themes/Images", "GET")]
- [Api(Description = "Gets an app theme")]
+ [Route("/Themes/Images", "GET", Summary = "Gets an app theme")]
public class GetAppThemeImage
{
[ApiMember(Name = "App", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
@@ -45,12 +42,11 @@ namespace MediaBrowser.Api
public string CacheTag { get; set; }
}
- [Route("/Themes", "POST")]
- [Api(Description = "Saves a theme")]
+ [Route("/Themes", "POST", Summary = "Saves a theme")]
public class SaveTheme : AppTheme, IReturnVoid
{
}
-
+
public class AppThemeService : BaseApiService
{
private readonly IAppThemeManager _themeManager;
diff --git a/MediaBrowser.Api/BaseApiService.cs b/MediaBrowser.Api/BaseApiService.cs
index 08686b43a..707cfb457 100644
--- a/MediaBrowser.Api/BaseApiService.cs
+++ b/MediaBrowser.Api/BaseApiService.cs
@@ -2,6 +2,7 @@
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Net;
+using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Logging;
using ServiceStack.Web;
using System;
@@ -79,6 +80,20 @@ namespace MediaBrowser.Api
}
/// <summary>
+ /// Gets the session.
+ /// </summary>
+ /// <param name="sessionManager">The session manager.</param>
+ /// <returns>SessionInfo.</returns>
+ protected SessionInfo GetSession(ISessionManager sessionManager)
+ {
+ var auth = AuthorizationRequestFilterAttribute.GetAuthorization(Request);
+
+ return sessionManager.Sessions.First(i => string.Equals(i.DeviceId, auth.DeviceId) &&
+ string.Equals(i.Client, auth.Client) &&
+ string.Equals(i.ApplicationVersion, auth.Version));
+ }
+
+ /// <summary>
/// To the cached result.
/// </summary>
/// <typeparam name="T"></typeparam>
diff --git a/MediaBrowser.Api/ChannelService.cs b/MediaBrowser.Api/ChannelService.cs
index c1724571a..ed203a0f4 100644
--- a/MediaBrowser.Api/ChannelService.cs
+++ b/MediaBrowser.Api/ChannelService.cs
@@ -7,8 +7,7 @@ using System.Threading;
namespace MediaBrowser.Api
{
- [Route("/Channels", "GET")]
- [Api(("Gets available channels"))]
+ [Route("/Channels", "GET", Summary = "Gets available channels")]
public class GetChannels : IReturn<QueryResult<BaseItemDto>>
{
public string UserId { get; set; }
@@ -18,8 +17,7 @@ namespace MediaBrowser.Api
public int? Limit { get; set; }
}
- [Route("/Channels/{Id}/Items", "GET")]
- [Api(("Gets channel items"))]
+ [Route("/Channels/{Id}/Items", "GET", Summary = "Gets channel items")]
public class GetChannelItems : IReturn<QueryResult<BaseItemDto>>
{
public string Id { get; set; }
diff --git a/MediaBrowser.Api/ConfigurationService.cs b/MediaBrowser.Api/ConfigurationService.cs
index 600704350..b3191cd4b 100644
--- a/MediaBrowser.Api/ConfigurationService.cs
+++ b/MediaBrowser.Api/ConfigurationService.cs
@@ -17,8 +17,7 @@ namespace MediaBrowser.Api
/// <summary>
/// Class GetConfiguration
/// </summary>
- [Route("/System/Configuration", "GET")]
- [Api(("Gets application configuration"))]
+ [Route("/System/Configuration", "GET", Summary = "Gets application configuration")]
public class GetConfiguration : IReturn<ServerConfiguration>
{
@@ -27,28 +26,24 @@ namespace MediaBrowser.Api
/// <summary>
/// Class UpdateConfiguration
/// </summary>
- [Route("/System/Configuration", "POST")]
- [Api(("Updates application configuration"))]
+ [Route("/System/Configuration", "POST", Summary = "Updates application configuration")]
public class UpdateConfiguration : ServerConfiguration, IReturnVoid
{
}
- [Route("/System/Configuration/MetadataOptions/Default", "GET")]
- [Api(("Gets a default MetadataOptions object"))]
+ [Route("/System/Configuration/MetadataOptions/Default", "GET", Summary = "Gets a default MetadataOptions object")]
public class GetDefaultMetadataOptions : IReturn<MetadataOptions>
{
}
- [Route("/System/Configuration/MetadataPlugins", "GET")]
- [Api(("Gets all available metadata plugins"))]
+ [Route("/System/Configuration/MetadataPlugins", "GET", Summary = "Gets all available metadata plugins")]
public class GetMetadataPlugins : IReturn<List<MetadataPluginSummary>>
{
}
- [Route("/System/Configuration/VideoImageExtraction", "POST")]
- [Api(("Updates image extraction for all types"))]
+ [Route("/System/Configuration/VideoImageExtraction", "POST", Summary = "Updates image extraction for all types")]
public class UpdateVideoImageExtraction : IReturnVoid
{
public bool Enabled { get; set; }
diff --git a/MediaBrowser.Api/DlnaService.cs b/MediaBrowser.Api/DlnaService.cs
new file mode 100644
index 000000000..792a7ff43
--- /dev/null
+++ b/MediaBrowser.Api/DlnaService.cs
@@ -0,0 +1,90 @@
+using MediaBrowser.Controller.Dlna;
+using MediaBrowser.Model.Dlna;
+using ServiceStack;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace MediaBrowser.Api
+{
+ [Route("/Dlna/ProfileInfos", "GET", Summary = "Gets a list of profiles")]
+ public class GetProfileInfos : IReturn<List<DeviceProfileInfo>>
+ {
+ }
+
+ [Route("/Dlna/Profiles/{Id}", "DELETE", Summary = "Deletes a profile")]
+ public class DeleteProfile : IReturnVoid
+ {
+ [ApiMember(Name = "Id", Description = "Profile Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
+ public string Id { get; set; }
+ }
+
+ [Route("/Dlna/Profiles/Default", "GET", Summary = "Gets the default profile")]
+ public class GetDefaultProfile : IReturn<DeviceProfile>
+ {
+ }
+
+ [Route("/Dlna/Profiles/{Id}", "GET", Summary = "Gets a single profile")]
+ public class GetProfile : IReturn<DeviceProfile>
+ {
+ [ApiMember(Name = "Id", Description = "Profile Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
+ public string Id { get; set; }
+ }
+
+ [Route("/Dlna/Profiles/{ProfileId}", "POST", Summary = "Updates a profile")]
+ public class UpdateProfile : DeviceProfile, IReturnVoid
+ {
+ [ApiMember(Name = "ProfileId", Description = "Profile Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
+ public string ProfileId { get; set; }
+ }
+
+ [Route("/Dlna/Profiles", "POST", Summary = "Creates a profile")]
+ public class CreateProfile : DeviceProfile, IReturnVoid
+ {
+ }
+
+ public class DlnaService : BaseApiService
+ {
+ private readonly IDlnaManager _dlnaManager;
+
+ public DlnaService(IDlnaManager dlnaManager)
+ {
+ _dlnaManager = dlnaManager;
+ }
+
+ public object Get(GetProfileInfos request)
+ {
+ var result = _dlnaManager.GetProfileInfos().ToList();
+
+ return ToOptimizedResult(result);
+ }
+
+ public object Get(GetProfile request)
+ {
+ var result = _dlnaManager.GetProfile(request.Id);
+
+ return ToOptimizedResult(result);
+ }
+
+ public object Get(GetDefaultProfile request)
+ {
+ var result = _dlnaManager.GetDefaultProfile();
+
+ return ToOptimizedResult(result);
+ }
+
+ public void Delete(DeleteProfile request)
+ {
+ _dlnaManager.DeleteProfile(request.Id);
+ }
+
+ public void Post(UpdateProfile request)
+ {
+ _dlnaManager.UpdateProfile(request);
+ }
+
+ public void Post(CreateProfile request)
+ {
+ _dlnaManager.CreateProfile(request);
+ }
+ }
+}
diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs
index 2cdaef1ed..562da40ee 100644
--- a/MediaBrowser.Api/Images/ImageService.cs
+++ b/MediaBrowser.Api/Images/ImageService.cs
@@ -15,7 +15,6 @@ using ServiceStack.Text.Controller;
using ServiceStack.Web;
using System;
using System.Collections.Generic;
-using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading;
@@ -776,15 +775,6 @@ namespace MediaBrowser.Api.Images
var bytes = Convert.FromBase64String(text);
- // Validate first
- using (var validationStream = new MemoryStream(bytes))
- {
- // This will throw an exception if it's not a valid image
- using (Image.FromStream(validationStream))
- {
- }
- }
-
var memoryStream = new MemoryStream(bytes)
{
Position = 0
diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs
index dba256418..533a92fba 100644
--- a/MediaBrowser.Api/Library/LibraryService.cs
+++ b/MediaBrowser.Api/Library/LibraryService.cs
@@ -7,6 +7,7 @@ using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Persistence;
+using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Channels;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
@@ -245,12 +246,13 @@ namespace MediaBrowser.Api.Library
private readonly IDtoService _dtoService;
private readonly IChannelManager _channelManager;
+ private readonly ISessionManager _sessionManager;
/// <summary>
/// Initializes a new instance of the <see cref="LibraryService" /> class.
/// </summary>
public LibraryService(IItemRepository itemRepo, ILibraryManager libraryManager, IUserManager userManager,
- IDtoService dtoService, IUserDataManager userDataManager, IChannelManager channelManager)
+ IDtoService dtoService, IUserDataManager userDataManager, IChannelManager channelManager, ISessionManager sessionManager)
{
_itemRepo = itemRepo;
_libraryManager = libraryManager;
@@ -258,6 +260,7 @@ namespace MediaBrowser.Api.Library
_dtoService = dtoService;
_userDataManager = userDataManager;
_channelManager = channelManager;
+ _sessionManager = sessionManager;
}
public object Get(GetMediaFolders request)
@@ -504,6 +507,13 @@ namespace MediaBrowser.Api.Library
{
var item = _dtoService.GetItemByDtoId(request.Id);
+ var session = GetSession(_sessionManager);
+
+ if (!session.UserId.HasValue || !_userManager.GetUserById(session.UserId.Value).Configuration.EnableContentDeletion)
+ {
+ throw new UnauthorizedAccessException("This operation requires a logged in user with delete access.");
+ }
+
return _libraryManager.DeleteItem(item);
}
diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs
index 569e4b52b..96fe01ab3 100644
--- a/MediaBrowser.Api/LiveTv/LiveTvService.cs
+++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs
@@ -12,14 +12,12 @@ using System.Threading.Tasks;
namespace MediaBrowser.Api.LiveTv
{
- [Route("/LiveTv/Info", "GET")]
- [Api(Description = "Gets available live tv services.")]
+ [Route("/LiveTv/Info", "GET", Summary = "Gets available live tv services.")]
public class GetLiveTvInfo : IReturn<LiveTvInfo>
{
}
- [Route("/LiveTv/Channels", "GET")]
- [Api(Description = "Gets available live tv channels.")]
+ [Route("/LiveTv/Channels", "GET", Summary = "Gets available live tv channels.")]
public class GetChannels : IReturn<QueryResult<ChannelInfoDto>>
{
[ApiMember(Name = "Type", Description = "Optional filter by channel type.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
@@ -43,8 +41,7 @@ namespace MediaBrowser.Api.LiveTv
public int? Limit { get; set; }
}
- [Route("/LiveTv/Channels/{Id}", "GET")]
- [Api(Description = "Gets a live tv channel")]
+ [Route("/LiveTv/Channels/{Id}", "GET", Summary = "Gets a live tv channel")]
public class GetChannel : IReturn<ChannelInfoDto>
{
/// <summary>
@@ -58,8 +55,7 @@ namespace MediaBrowser.Api.LiveTv
public string UserId { get; set; }
}
- [Route("/LiveTv/Recordings", "GET")]
- [Api(Description = "Gets live tv recordings")]
+ [Route("/LiveTv/Recordings", "GET", Summary = "Gets live tv recordings")]
public class GetRecordings : IReturn<QueryResult<RecordingInfoDto>>
{
[ApiMember(Name = "ChannelId", Description = "Optional filter by channel id.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
@@ -87,16 +83,14 @@ namespace MediaBrowser.Api.LiveTv
public string SeriesTimerId { get; set; }
}
- [Route("/LiveTv/Recordings/Groups", "GET")]
- [Api(Description = "Gets live tv recording groups")]
+ [Route("/LiveTv/Recordings/Groups", "GET", Summary = "Gets live tv recording groups")]
public class GetRecordingGroups : IReturn<QueryResult<RecordingGroupDto>>
{
[ApiMember(Name = "UserId", Description = "Optional filter by user and attach user data.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public string UserId { get; set; }
}
- [Route("/LiveTv/Recordings/{Id}", "GET")]
- [Api(Description = "Gets a live tv recording")]
+ [Route("/LiveTv/Recordings/{Id}", "GET", Summary = "Gets a live tv recording")]
public class GetRecording : IReturn<RecordingInfoDto>
{
[ApiMember(Name = "Id", Description = "Recording Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
@@ -106,32 +100,28 @@ namespace MediaBrowser.Api.LiveTv
public string UserId { get; set; }
}
- [Route("/LiveTv/Tuners/{Id}/Reset", "POST")]
- [Api(Description = "Resets a tv tuner")]
+ [Route("/LiveTv/Tuners/{Id}/Reset", "POST", Summary = "Resets a tv tuner")]
public class ResetTuner : IReturnVoid
{
[ApiMember(Name = "Id", Description = "Tuner Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Id { get; set; }
}
- [Route("/LiveTv/Timers/{Id}", "GET")]
- [Api(Description = "Gets a live tv timer")]
+ [Route("/LiveTv/Timers/{Id}", "GET", Summary = "Gets a live tv timer")]
public class GetTimer : IReturn<TimerInfoDto>
{
[ApiMember(Name = "Id", Description = "Timer Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Id { get; set; }
}
- [Route("/LiveTv/Timers/Defaults", "GET")]
- [Api(Description = "Gets default values for a new timer")]
+ [Route("/LiveTv/Timers/Defaults", "GET", Summary = "Gets default values for a new timer")]
public class GetDefaultTimer : IReturn<SeriesTimerInfoDto>
{
[ApiMember(Name = "ProgramId", Description = "Optional, to attach default values based on a program.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public string ProgramId { get; set; }
}
- [Route("/LiveTv/Timers", "GET")]
- [Api(Description = "Gets live tv timers")]
+ [Route("/LiveTv/Timers", "GET", Summary = "Gets live tv timers")]
public class GetTimers : IReturn<QueryResult<TimerInfoDto>>
{
[ApiMember(Name = "ChannelId", Description = "Optional filter by channel id.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
@@ -141,8 +131,7 @@ namespace MediaBrowser.Api.LiveTv
public string SeriesTimerId { get; set; }
}
- [Route("/LiveTv/Programs", "GET,POST")]
- [Api(Description = "Gets available live tv epgs..")]
+ [Route("/LiveTv/Programs", "GET,POST", Summary = "Gets available live tv epgs..")]
public class GetPrograms : IReturn<QueryResult<ProgramInfoDto>>
{
[ApiMember(Name = "ChannelIds", Description = "The channels to return guide information for.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET,POST")]
@@ -164,8 +153,7 @@ namespace MediaBrowser.Api.LiveTv
public string MaxEndDate { get; set; }
}
- [Route("/LiveTv/Programs/Recommended", "GET")]
- [Api(Description = "Gets available live tv epgs..")]
+ [Route("/LiveTv/Programs/Recommended", "GET", Summary = "Gets available live tv epgs..")]
public class GetRecommendedPrograms : IReturn<QueryResult<ProgramInfoDto>>
{
[ApiMember(Name = "UserId", Description = "Optional filter by user id.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET,POST")]
@@ -181,8 +169,7 @@ namespace MediaBrowser.Api.LiveTv
public bool? HasAired { get; set; }
}
- [Route("/LiveTv/Programs/{Id}", "GET")]
- [Api(Description = "Gets a live tv program")]
+ [Route("/LiveTv/Programs/{Id}", "GET", Summary = "Gets a live tv program")]
public class GetProgram : IReturn<ProgramInfoDto>
{
[ApiMember(Name = "Id", Description = "Program Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
@@ -193,44 +180,38 @@ namespace MediaBrowser.Api.LiveTv
}
- [Route("/LiveTv/Recordings/{Id}", "DELETE")]
- [Api(Description = "Deletes a live tv recording")]
+ [Route("/LiveTv/Recordings/{Id}", "DELETE", Summary = "Deletes a live tv recording")]
public class DeleteRecording : IReturnVoid
{
[ApiMember(Name = "Id", Description = "Recording Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Id { get; set; }
}
- [Route("/LiveTv/Timers/{Id}", "DELETE")]
- [Api(Description = "Cancels a live tv timer")]
+ [Route("/LiveTv/Timers/{Id}", "DELETE", Summary = "Cancels a live tv timer")]
public class CancelTimer : IReturnVoid
{
[ApiMember(Name = "Id", Description = "Timer Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Id { get; set; }
}
- [Route("/LiveTv/Timers/{Id}", "POST")]
- [Api(Description = "Updates a live tv timer")]
+ [Route("/LiveTv/Timers/{Id}", "POST", Summary = "Updates a live tv timer")]
public class UpdateTimer : TimerInfoDto, IReturnVoid
{
}
- [Route("/LiveTv/Timers", "POST")]
- [Api(Description = "Creates a live tv timer")]
+ [Route("/LiveTv/Timers", "POST", Summary = "Creates a live tv timer")]
public class CreateTimer : TimerInfoDto, IReturnVoid
{
}
- [Route("/LiveTv/SeriesTimers/{Id}", "GET")]
- [Api(Description = "Gets a live tv series timer")]
+ [Route("/LiveTv/SeriesTimers/{Id}", "GET", Summary = "Gets a live tv series timer")]
public class GetSeriesTimer : IReturn<TimerInfoDto>
{
[ApiMember(Name = "Id", Description = "Timer Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Id { get; set; }
}
- [Route("/LiveTv/SeriesTimers", "GET")]
- [Api(Description = "Gets live tv series timers")]
+ [Route("/LiveTv/SeriesTimers", "GET", Summary = "Gets live tv series timers")]
public class GetSeriesTimers : IReturn<QueryResult<SeriesTimerInfoDto>>
{
[ApiMember(Name = "SortBy", Description = "Optional. Sort by SortName or Priority", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET,POST")]
@@ -240,36 +221,31 @@ namespace MediaBrowser.Api.LiveTv
public SortOrder SortOrder { get; set; }
}
- [Route("/LiveTv/SeriesTimers/{Id}", "DELETE")]
- [Api(Description = "Cancels a live tv series timer")]
+ [Route("/LiveTv/SeriesTimers/{Id}", "DELETE", Summary = "Cancels a live tv series timer")]
public class CancelSeriesTimer : IReturnVoid
{
[ApiMember(Name = "Id", Description = "Timer Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Id { get; set; }
}
- [Route("/LiveTv/SeriesTimers/{Id}", "POST")]
- [Api(Description = "Updates a live tv series timer")]
+ [Route("/LiveTv/SeriesTimers/{Id}", "POST", Summary = "Updates a live tv series timer")]
public class UpdateSeriesTimer : SeriesTimerInfoDto, IReturnVoid
{
}
- [Route("/LiveTv/SeriesTimers", "POST")]
- [Api(Description = "Creates a live tv series timer")]
+ [Route("/LiveTv/SeriesTimers", "POST", Summary = "Creates a live tv series timer")]
public class CreateSeriesTimer : SeriesTimerInfoDto, IReturnVoid
{
}
- [Route("/LiveTv/Recordings/Groups/{Id}", "GET")]
- [Api(Description = "Gets a recording group")]
+ [Route("/LiveTv/Recordings/Groups/{Id}", "GET", Summary = "Gets a recording group")]
public class GetRecordingGroup : IReturn<RecordingGroupDto>
{
[ApiMember(Name = "Id", Description = "Recording group Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Id { get; set; }
}
- [Route("/LiveTv/GuideInfo", "GET")]
- [Api(Description = "Gets guide info")]
+ [Route("/LiveTv/GuideInfo", "GET", Summary = "Gets guide info")]
public class GetGuideInfo : IReturn<GuideInfo>
{
}
diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj
index 38cf39b54..18559a68d 100644
--- a/MediaBrowser.Api/MediaBrowser.Api.csproj
+++ b/MediaBrowser.Api/MediaBrowser.Api.csproj
@@ -53,7 +53,6 @@
<Reference Include="System.Core" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
- <Reference Include="System.Drawing" />
<Reference Include="System.Xml" />
<Reference Include="ServiceStack.Interfaces">
<HintPath>..\ThirdParty\ServiceStack\ServiceStack.Interfaces.dll</HintPath>
@@ -67,6 +66,7 @@
<Link>Properties\SharedVersion.cs</Link>
</Compile>
<Compile Include="ChannelService.cs" />
+ <Compile Include="DlnaService.cs" />
<Compile Include="Movies\CollectionService.cs" />
<Compile Include="Music\AlbumsService.cs" />
<Compile Include="AppThemeService.cs" />
diff --git a/MediaBrowser.Api/Movies/MoviesService.cs b/MediaBrowser.Api/Movies/MoviesService.cs
index 204a7aab4..228dc378b 100644
--- a/MediaBrowser.Api/Movies/MoviesService.cs
+++ b/MediaBrowser.Api/Movies/MoviesService.cs
@@ -17,8 +17,7 @@ namespace MediaBrowser.Api.Movies
/// <summary>
/// Class GetSimilarMovies
/// </summary>
- [Route("/Movies/{Id}/Similar", "GET")]
- [Api(Description = "Finds movies and trailers similar to a given movie.")]
+ [Route("/Movies/{Id}/Similar", "GET", Summary = "Finds movies and trailers similar to a given movie.")]
public class GetSimilarMovies : BaseGetSimilarItemsFromItem
{
[ApiMember(Name = "IncludeTrailers", Description = "Whether or not to include trailers within the results. Defaults to true.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
@@ -30,8 +29,7 @@ namespace MediaBrowser.Api.Movies
}
}
- [Route("/Movies/Recommendations", "GET")]
- [Api(Description = "Gets movie recommendations")]
+ [Route("/Movies/Recommendations", "GET", Summary = "Gets movie recommendations")]
public class GetMovieRecommendations : IReturn<RecommendationDto[]>, IHasItemFields
{
[ApiMember(Name = "CategoryLimit", Description = "The max number of categories to return", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
diff --git a/MediaBrowser.Api/Movies/TrailersService.cs b/MediaBrowser.Api/Movies/TrailersService.cs
index 057506635..05e6a9577 100644
--- a/MediaBrowser.Api/Movies/TrailersService.cs
+++ b/MediaBrowser.Api/Movies/TrailersService.cs
@@ -10,8 +10,7 @@ namespace MediaBrowser.Api.Movies
/// <summary>
/// Class GetSimilarTrailers
/// </summary>
- [Route("/Trailers/{Id}/Similar", "GET")]
- [Api(Description = "Finds movies and trailers similar to a given trailer.")]
+ [Route("/Trailers/{Id}/Similar", "GET", Summary = "Finds movies and trailers similar to a given trailer.")]
public class GetSimilarTrailers : BaseGetSimilarItemsFromItem
{
}
diff --git a/MediaBrowser.Api/Music/InstantMixService.cs b/MediaBrowser.Api/Music/InstantMixService.cs
index a8446a7ef..9b9df3a92 100644
--- a/MediaBrowser.Api/Music/InstantMixService.cs
+++ b/MediaBrowser.Api/Music/InstantMixService.cs
@@ -9,28 +9,24 @@ using System.Linq;
namespace MediaBrowser.Api.Music
{
- [Route("/Songs/{Id}/InstantMix", "GET")]
- [Api(Description = "Creates an instant playlist based on a given song")]
+ [Route("/Songs/{Id}/InstantMix", "GET", Summary = "Creates an instant playlist based on a given song")]
public class GetInstantMixFromSong : BaseGetSimilarItemsFromItem
{
}
- [Route("/Albums/{Id}/InstantMix", "GET")]
- [Api(Description = "Creates an instant playlist based on a given album")]
+ [Route("/Albums/{Id}/InstantMix", "GET", Summary = "Creates an instant playlist based on a given album")]
public class GetInstantMixFromAlbum : BaseGetSimilarItemsFromItem
{
}
- [Route("/Artists/{Name}/InstantMix", "GET")]
- [Api(Description = "Creates an instant playlist based on a given artist")]
+ [Route("/Artists/{Name}/InstantMix", "GET", Summary = "Creates an instant playlist based on a given artist")]
public class GetInstantMixFromArtist : BaseGetSimilarItems
{
[ApiMember(Name = "Name", Description = "The artist name", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Name { get; set; }
}
- [Route("/MusicGenres/{Name}/InstantMix", "GET")]
- [Api(Description = "Creates an instant playlist based on a music genre")]
+ [Route("/MusicGenres/{Name}/InstantMix", "GET", Summary = "Creates an instant playlist based on a music genre")]
public class GetInstantMixFromMusicGenre : BaseGetSimilarItems
{
[ApiMember(Name = "Name", Description = "The genre name", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs
index f65949ac7..2002e594c 100644
--- a/MediaBrowser.Api/Playback/BaseStreamingService.cs
+++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs
@@ -1210,85 +1210,89 @@ namespace MediaBrowser.Api.Playback
if (i == 0)
{
- request.DeviceId = val;
+ request.DeviceProfileId = val;
}
else if (i == 1)
{
- request.MediaSourceId = val;
+ request.DeviceId = val;
}
else if (i == 2)
{
- request.Static = string.Equals("true", val, StringComparison.OrdinalIgnoreCase);
+ request.MediaSourceId = val;
}
else if (i == 3)
{
+ request.Static = string.Equals("true", val, StringComparison.OrdinalIgnoreCase);
+ }
+ else if (i == 4)
+ {
if (videoRequest != null)
{
videoRequest.VideoCodec = val;
}
}
- else if (i == 4)
+ else if (i == 5)
{
request.AudioCodec = val;
}
- else if (i == 5)
+ else if (i == 6)
{
if (videoRequest != null)
{
videoRequest.AudioStreamIndex = int.Parse(val, UsCulture);
}
}
- else if (i == 6)
+ else if (i == 7)
{
if (videoRequest != null)
{
videoRequest.SubtitleStreamIndex = int.Parse(val, UsCulture);
}
}
- else if (i == 7)
+ else if (i == 8)
{
if (videoRequest != null)
{
videoRequest.VideoBitRate = int.Parse(val, UsCulture);
}
}
- else if (i == 8)
+ else if (i == 9)
{
request.AudioBitRate = int.Parse(val, UsCulture);
}
- else if (i == 9)
+ else if (i == 10)
{
request.MaxAudioChannels = int.Parse(val, UsCulture);
}
- else if (i == 10)
+ else if (i == 11)
{
if (videoRequest != null)
{
videoRequest.MaxWidth = int.Parse(val, UsCulture);
}
}
- else if (i == 11)
+ else if (i == 12)
{
if (videoRequest != null)
{
videoRequest.MaxHeight = int.Parse(val, UsCulture);
}
}
- else if (i == 12)
+ else if (i == 13)
{
if (videoRequest != null)
{
videoRequest.Framerate = int.Parse(val, UsCulture);
}
}
- else if (i == 13)
+ else if (i == 14)
{
if (videoRequest != null)
{
request.StartTimeTicks = long.Parse(val, UsCulture);
}
}
- else if (i == 14)
+ else if (i == 15)
{
if (videoRequest != null)
{
@@ -1488,7 +1492,16 @@ namespace MediaBrowser.Api.Playback
headers[key] = Request.Headers[key];
}
- var profile = DlnaManager.GetProfile(headers);
+ var profile = string.IsNullOrWhiteSpace(state.Request.DeviceProfileId) ?
+ DlnaManager.GetProfile(headers) :
+ DlnaManager.GetProfile(state.Request.DeviceProfileId);
+
+ if (profile == null)
+ {
+ // Don't use settings from the default profile.
+ // Only use a specific profile if it was requested.
+ return;
+ }
var container = Path.GetExtension(state.RequestedUrl);
diff --git a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
index dad8a51bd..78b3f2948 100644
--- a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
+++ b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
@@ -26,7 +26,8 @@ namespace MediaBrowser.Api.Playback.Progressive
protected readonly IImageProcessor ImageProcessor;
protected readonly IHttpClient HttpClient;
- protected BaseProgressiveStreamingService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager, IEncodingManager encodingManager, IDlnaManager dlnaManager, IHttpClient httpClient, IImageProcessor imageProcessor) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository, liveTvManager, encodingManager, dlnaManager)
+ protected BaseProgressiveStreamingService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IDtoService dtoService, IFileSystem fileSystem, IItemRepository itemRepository, ILiveTvManager liveTvManager, IEncodingManager encodingManager, IDlnaManager dlnaManager, IHttpClient httpClient, IImageProcessor imageProcessor)
+ : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, dtoService, fileSystem, itemRepository, liveTvManager, encodingManager, dlnaManager)
{
HttpClient = httpClient;
ImageProcessor = imageProcessor;
@@ -216,18 +217,30 @@ namespace MediaBrowser.Api.Playback.Progressive
var contentType = state.GetMimeType(outputPath);
+ var contentLength = state.EstimateContentLength ? GetEstimatedContentLength(state) : null;
+
+ if (contentLength.HasValue)
+ {
+ responseHeaders["Content-Length"] = contentLength.Value.ToString(UsCulture);
+ }
+
// Headers only
if (isHeadRequest)
{
var streamResult = ResultFactory.GetResult(new byte[] { }, contentType, responseHeaders);
- var hasOptions = streamResult as IHasOptions;
- if (hasOptions != null)
+
+ if (!contentLength.HasValue)
{
- if (hasOptions.Options.ContainsKey("Content-Length"))
+ var hasOptions = streamResult as IHasOptions;
+ if (hasOptions != null)
{
- hasOptions.Options.Remove("Content-Length");
+ if (hasOptions.Options.ContainsKey("Content-Length"))
+ {
+ hasOptions.Options.Remove("Content-Length");
+ }
}
}
+
return streamResult;
}
@@ -252,5 +265,26 @@ namespace MediaBrowser.Api.Playback.Progressive
return result;
}
+
+ private long? GetEstimatedContentLength(StreamState state)
+ {
+ var totalBitrate = 0;
+
+ if (state.Request.AudioBitRate.HasValue)
+ {
+ totalBitrate += state.Request.AudioBitRate.Value;
+ }
+ if (state.VideoRequest != null && state.VideoRequest.VideoBitRate.HasValue)
+ {
+ totalBitrate += state.VideoRequest.VideoBitRate.Value;
+ }
+
+ if (totalBitrate > 0 && state.RunTimeTicks.HasValue)
+ {
+ return Convert.ToInt64(totalBitrate * TimeSpan.FromTicks(state.RunTimeTicks.Value).TotalSeconds);
+ }
+
+ return null;
+ }
}
}
diff --git a/MediaBrowser.Api/Playback/Progressive/VideoService.cs b/MediaBrowser.Api/Playback/Progressive/VideoService.cs
index 0fc78f0e3..855c03691 100644
--- a/MediaBrowser.Api/Playback/Progressive/VideoService.cs
+++ b/MediaBrowser.Api/Playback/Progressive/VideoService.cs
@@ -138,6 +138,11 @@ namespace MediaBrowser.Api.Playback.Progressive
return state.VideoStream != null && IsH264(state.VideoStream) ? args + " -bsf h264_mp4toannexb" : args;
}
+ if (state.EnableMpegtsM2TsMode)
+ {
+ args += " -mpegts_m2ts_mode 1";
+ }
+
const string keyFrameArg = " -force_key_frames expr:if(isnan(prev_forced_t),gte(t,.1),gte(t,prev_forced_t+5))";
args += keyFrameArg;
diff --git a/MediaBrowser.Api/Playback/StreamRequest.cs b/MediaBrowser.Api/Playback/StreamRequest.cs
index 8db5920f6..0eb2984fb 100644
--- a/MediaBrowser.Api/Playback/StreamRequest.cs
+++ b/MediaBrowser.Api/Playback/StreamRequest.cs
@@ -65,6 +65,9 @@ namespace MediaBrowser.Api.Playback
[ApiMember(Name = "Static", Description = "Optional. If true, the original file will be streamed statically without any encoding. Use either no url extension or the original file extension. true/false", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
public bool Static { get; set; }
+ [ApiMember(Name = "DeviceProfileId", Description = "Optional. The dlna device profile id to utilize.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
+ public string DeviceProfileId { get; set; }
+
/// <summary>
/// For testing purposes
/// </summary>
diff --git a/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs b/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs
index daa735fe5..80080fbb3 100644
--- a/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs
+++ b/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs
@@ -2,18 +2,17 @@
using MediaBrowser.Common.ScheduledTasks;
using MediaBrowser.Model.Tasks;
using ServiceStack;
+using ServiceStack.Text.Controller;
using System;
using System.Collections.Generic;
using System.Linq;
-using ServiceStack.Text.Controller;
namespace MediaBrowser.Api.ScheduledTasks
{
/// <summary>
/// Class GetScheduledTask
/// </summary>
- [Route("/ScheduledTasks/{Id}", "GET")]
- [Api(Description = "Gets a scheduled task, by Id")]
+ [Route("/ScheduledTasks/{Id}", "GET", Summary = "Gets a scheduled task, by Id")]
public class GetScheduledTask : IReturn<TaskInfo>
{
/// <summary>
@@ -27,8 +26,7 @@ namespace MediaBrowser.Api.ScheduledTasks
/// <summary>
/// Class GetScheduledTasks
/// </summary>
- [Route("/ScheduledTasks", "GET")]
- [Api(Description = "Gets scheduled tasks")]
+ [Route("/ScheduledTasks", "GET", Summary = "Gets scheduled tasks")]
public class GetScheduledTasks : IReturn<List<TaskInfo>>
{
[ApiMember(Name = "IsHidden", Description = "Optional filter tasks that are hidden, or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
@@ -38,8 +36,7 @@ namespace MediaBrowser.Api.ScheduledTasks
/// <summary>
/// Class StartScheduledTask
/// </summary>
- [Route("/ScheduledTasks/Running/{Id}", "POST")]
- [Api(Description = "Starts a scheduled task")]
+ [Route("/ScheduledTasks/Running/{Id}", "POST", Summary = "Starts a scheduled task")]
public class StartScheduledTask : IReturnVoid
{
/// <summary>
@@ -53,8 +50,7 @@ namespace MediaBrowser.Api.ScheduledTasks
/// <summary>
/// Class StopScheduledTask
/// </summary>
- [Route("/ScheduledTasks/Running/{Id}", "DELETE")]
- [Api(Description = "Stops a scheduled task")]
+ [Route("/ScheduledTasks/Running/{Id}", "DELETE", Summary = "Stops a scheduled task")]
public class StopScheduledTask : IReturnVoid
{
/// <summary>
@@ -68,8 +64,7 @@ namespace MediaBrowser.Api.ScheduledTasks
/// <summary>
/// Class UpdateScheduledTaskTriggers
/// </summary>
- [Route("/ScheduledTasks/{Id}/Triggers", "POST")]
- [Api(Description = "Updates the triggers for a scheduled task")]
+ [Route("/ScheduledTasks/{Id}/Triggers", "POST", Summary = "Updates the triggers for a scheduled task")]
public class UpdateScheduledTaskTriggers : List<TaskTriggerInfo>, IReturnVoid
{
/// <summary>
diff --git a/MediaBrowser.Api/UserLibrary/StudiosService.cs b/MediaBrowser.Api/UserLibrary/StudiosService.cs
index fc7fdd160..7eff5054b 100644
--- a/MediaBrowser.Api/UserLibrary/StudiosService.cs
+++ b/MediaBrowser.Api/UserLibrary/StudiosService.cs
@@ -8,15 +8,13 @@ using ServiceStack;
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Threading.Tasks;
namespace MediaBrowser.Api.UserLibrary
{
/// <summary>
/// Class GetStudios
/// </summary>
- [Route("/Studios", "GET")]
- [Api(Description = "Gets all studios from a given item, folder, or the entire library")]
+ [Route("/Studios", "GET", Summary = "Gets all studios from a given item, folder, or the entire library")]
public class GetStudios : GetItemsByName
{
}
@@ -24,8 +22,7 @@ namespace MediaBrowser.Api.UserLibrary
/// <summary>
/// Class GetStudio
/// </summary>
- [Route("/Studios/{Name}", "GET")]
- [Api(Description = "Gets a studio, by name")]
+ [Route("/Studios/{Name}", "GET", Summary = "Gets a studio, by name")]
public class GetStudio : IReturn<BaseItemDto>
{
/// <summary>
diff --git a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
index c6051c02c..a49f957f6 100644
--- a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
+++ b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
@@ -705,7 +705,7 @@ namespace MediaBrowser.Api.UserLibrary
datePlayed = DateTime.ParseExact(request.DatePlayed, "yyyyMMddHHmmss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
}
- var session = GetSession();
+ var session = GetSession(_sessionManager);
var dto = await UpdatePlayedStatus(user, request.Id, true, datePlayed).ConfigureAwait(false);
@@ -719,15 +719,6 @@ namespace MediaBrowser.Api.UserLibrary
return dto;
}
- private SessionInfo GetSession()
- {
- var auth = AuthorizationRequestFilterAttribute.GetAuthorization(Request);
-
- return _sessionManager.Sessions.First(i => string.Equals(i.DeviceId, auth.DeviceId) &&
- string.Equals(i.Client, auth.Client) &&
- string.Equals(i.ApplicationVersion, auth.Version));
- }
-
/// <summary>
/// Posts the specified request.
/// </summary>
@@ -744,7 +735,7 @@ namespace MediaBrowser.Api.UserLibrary
{
CanSeek = request.CanSeek,
Item = item,
- SessionId = GetSession().Id,
+ SessionId = GetSession(_sessionManager).Id,
QueueableMediaTypes = queueableMediaTypes.Split(',').ToList(),
MediaSourceId = request.MediaSourceId
};
@@ -768,7 +759,7 @@ namespace MediaBrowser.Api.UserLibrary
PositionTicks = request.PositionTicks,
IsMuted = request.IsMuted,
IsPaused = request.IsPaused,
- SessionId = GetSession().Id,
+ SessionId = GetSession(_sessionManager).Id,
MediaSourceId = request.MediaSourceId
};
@@ -787,7 +778,7 @@ namespace MediaBrowser.Api.UserLibrary
var item = _dtoService.GetItemByDtoId(request.Id, user.Id);
- var session = GetSession();
+ var session = GetSession(_sessionManager);
var info = new PlaybackStopInfo
{
@@ -817,7 +808,7 @@ namespace MediaBrowser.Api.UserLibrary
{
var user = _userManager.GetUserById(request.UserId);
- var session = GetSession();
+ var session = GetSession(_sessionManager);
var dto = await UpdatePlayedStatus(user, request.Id, false, null).ConfigureAwait(false);
diff --git a/MediaBrowser.Api/WebSocket/SessionInfoWebSocketListener.cs b/MediaBrowser.Api/WebSocket/SessionInfoWebSocketListener.cs
index 38139645e..25acd613c 100644
--- a/MediaBrowser.Api/WebSocket/SessionInfoWebSocketListener.cs
+++ b/MediaBrowser.Api/WebSocket/SessionInfoWebSocketListener.cs
@@ -49,7 +49,7 @@ namespace MediaBrowser.Api.WebSocket
/// <returns>Task{SystemInfo}.</returns>
protected override Task<IEnumerable<SessionInfoDto>> GetDataToSend(object state)
{
- return Task.FromResult(_sessionManager.Sessions.Select(_dtoService.GetSessionInfoDto));
+ return Task.FromResult(_sessionManager.Sessions.Where(i => i.IsActive).Select(_dtoService.GetSessionInfoDto));
}
}
}
diff --git a/MediaBrowser.Controller/Dlna/CodecProfile.cs b/MediaBrowser.Controller/Dlna/CodecProfile.cs
index 2b9a40ea0..75f80ed3b 100644
--- a/MediaBrowser.Controller/Dlna/CodecProfile.cs
+++ b/MediaBrowser.Controller/Dlna/CodecProfile.cs
@@ -1,13 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Xml.Serialization;
namespace MediaBrowser.Controller.Dlna
{
public class CodecProfile
{
+ [XmlAttribute("type")]
public CodecType Type { get; set; }
+
public ProfileCondition[] Conditions { get; set; }
+
+ [XmlAttribute("codec")]
public string Codec { get; set; }
public CodecProfile()
@@ -37,9 +42,16 @@ namespace MediaBrowser.Controller.Dlna
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()
@@ -69,8 +81,6 @@ namespace MediaBrowser.Controller.Dlna
VideoBitrate,
VideoFramerate,
VideoLevel,
- VideoPacketLength,
- VideoProfile,
- VideoTimestamp
+ VideoProfile
}
}
diff --git a/MediaBrowser.Controller/Dlna/ContainerProfile.cs b/MediaBrowser.Controller/Dlna/ContainerProfile.cs
index 3bd3c9eaf..1029ba72c 100644
--- a/MediaBrowser.Controller/Dlna/ContainerProfile.cs
+++ b/MediaBrowser.Controller/Dlna/ContainerProfile.cs
@@ -1,12 +1,16 @@
using System.Collections.Generic;
using System.Linq;
+using System.Xml.Serialization;
namespace MediaBrowser.Controller.Dlna
{
public class ContainerProfile
{
+ [XmlAttribute("type")]
public DlnaProfileType Type { get; set; }
public ProfileCondition[] Conditions { get; set; }
+
+ [XmlAttribute("container")]
public string Container { get; set; }
public ContainerProfile()
diff --git a/MediaBrowser.Controller/Dlna/DeviceIdentification.cs b/MediaBrowser.Controller/Dlna/DeviceIdentification.cs
index 7b8e3a1e7..c9cd4bc70 100644
--- a/MediaBrowser.Controller/Dlna/DeviceIdentification.cs
+++ b/MediaBrowser.Controller/Dlna/DeviceIdentification.cs
@@ -1,4 +1,6 @@

+using System.Xml.Serialization;
+
namespace MediaBrowser.Controller.Dlna
{
public class DeviceIdentification
@@ -62,8 +64,13 @@ namespace MediaBrowser.Controller.Dlna
public class HttpHeaderInfo
{
+ [XmlAttribute("name")]
public string Name { get; set; }
+
+ [XmlAttribute("value")]
public string Value { get; set; }
+
+ [XmlAttribute("match")]
public HeaderMatchType Match { get; set; }
}
diff --git a/MediaBrowser.Controller/Dlna/DeviceProfile.cs b/MediaBrowser.Controller/Dlna/DeviceProfile.cs
index f34c4bf64..5950698fb 100644
--- a/MediaBrowser.Controller/Dlna/DeviceProfile.cs
+++ b/MediaBrowser.Controller/Dlna/DeviceProfile.cs
@@ -1,9 +1,14 @@
-using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Dlna;
+using MediaBrowser.Model.Entities;
using System;
+using System.Collections.Generic;
using System.Linq;
+using System.Runtime.Serialization;
+using System.Xml.Serialization;
namespace MediaBrowser.Controller.Dlna
{
+ [XmlRoot("Profile")]
public class DeviceProfile
{
/// <summary>
@@ -12,19 +17,11 @@ namespace MediaBrowser.Controller.Dlna
/// <value>The name.</value>
public string Name { get; set; }
- /// <summary>
- /// Gets or sets the transcoding profiles.
- /// </summary>
- /// <value>The transcoding profiles.</value>
- public TranscodingProfile[] TranscodingProfiles { get; set; }
+ [XmlIgnore]
+ public string Id { get; set; }
- /// <summary>
- /// Gets or sets the direct play profiles.
- /// </summary>
- /// <value>The direct play profiles.</value>
- public DirectPlayProfile[] DirectPlayProfiles { get; set; }
-
- public ContainerProfile[] ContainerProfiles { get; set; }
+ [XmlIgnore]
+ public DeviceProfileType ProfileType { get; set; }
/// <summary>
/// Gets or sets the identification.
@@ -40,7 +37,9 @@ namespace MediaBrowser.Controller.Dlna
public string ModelNumber { get; set; }
public string ModelUrl { get; set; }
public bool IgnoreTranscodeByteRangeRequests { get; set; }
- public bool SupportsAlbumArtInDidl { get; set; }
+ public bool EnableAlbumArtInDidl { get; set; }
+
+ public string SupportedMediaTypes { get; set; }
/// <summary>
/// Controls the content of the X_DLNADOC element in the urn:schemas-dlna-org:device-1-0 namespace.
@@ -57,14 +56,27 @@ namespace MediaBrowser.Controller.Dlna
public string ProtocolInfo { get; set; }
- public MediaProfile[] MediaProfiles { get; set; }
- public CodecProfile[] CodecProfiles { get; set; }
-
public int TimelineOffsetSeconds { get; set; }
-
public bool RequiresPlainVideoItems { get; set; }
public bool RequiresPlainFolders { 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 MediaProfile[] MediaProfiles { get; set; }
+
public DeviceProfile()
{
DirectPlayProfiles = new DirectPlayProfile[] { };
@@ -72,6 +84,13 @@ namespace MediaBrowser.Controller.Dlna
MediaProfiles = new MediaProfile[] { };
CodecProfiles = new CodecProfile[] { };
ContainerProfiles = new ContainerProfile[] { };
+
+ SupportedMediaTypes = "Audio,Photo,Video";
+ }
+
+ public List<string> GetSupportedMediaTypes()
+ {
+ return (SupportedMediaTypes ?? string.Empty).Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).ToList();
}
public TranscodingProfile GetAudioTranscodingProfile(string container, string audioCodec)
diff --git a/MediaBrowser.Controller/Dlna/DirectPlayProfile.cs b/MediaBrowser.Controller/Dlna/DirectPlayProfile.cs
index 686b31287..ad70640da 100644
--- a/MediaBrowser.Controller/Dlna/DirectPlayProfile.cs
+++ b/MediaBrowser.Controller/Dlna/DirectPlayProfile.cs
@@ -1,14 +1,21 @@
using System.Collections.Generic;
using System.Linq;
+using System.Xml.Serialization;
namespace MediaBrowser.Controller.Dlna
{
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()
diff --git a/MediaBrowser.Controller/Dlna/IDlnaManager.cs b/MediaBrowser.Controller/Dlna/IDlnaManager.cs
index 22d13fc3a..521d17e01 100644
--- a/MediaBrowser.Controller/Dlna/IDlnaManager.cs
+++ b/MediaBrowser.Controller/Dlna/IDlnaManager.cs
@@ -1,28 +1,54 @@
-using System.Collections.Generic;
+using MediaBrowser.Model.Dlna;
+using System.Collections.Generic;
namespace MediaBrowser.Controller.Dlna
{
public interface IDlnaManager
{
/// <summary>
- /// Gets the dlna profiles.
+ /// Gets the profile infos.
/// </summary>
- /// <returns>IEnumerable{DlnaProfile}.</returns>
- IEnumerable<DeviceProfile> GetProfiles();
+ /// <returns>IEnumerable{DeviceProfileInfo}.</returns>
+ IEnumerable<DeviceProfileInfo> GetProfileInfos();
+
+ /// <summary>
+ /// Gets the profile.
+ /// </summary>
+ /// <param name="headers">The headers.</param>
+ /// <returns>DeviceProfile.</returns>
+ DeviceProfile GetProfile(IDictionary<string,string> headers);
/// <summary>
/// Gets the default profile.
/// </summary>
- /// <returns>DlnaProfile.</returns>
+ /// <returns>DeviceProfile.</returns>
DeviceProfile GetDefaultProfile();
/// <summary>
+ /// Creates the profile.
+ /// </summary>
+ /// <param name="profile">The profile.</param>
+ void CreateProfile(DeviceProfile profile);
+
+ /// <summary>
+ /// Updates the profile.
+ /// </summary>
+ /// <param name="profile">The profile.</param>
+ void UpdateProfile(DeviceProfile profile);
+
+ /// <summary>
+ /// Deletes the profile.
+ /// </summary>
+ /// <param name="id">The identifier.</param>
+ void DeleteProfile(string id);
+
+ /// <summary>
/// Gets the profile.
/// </summary>
- /// <param name="headers">The headers.</param>
+ /// <param name="id">The identifier.</param>
/// <returns>DeviceProfile.</returns>
- DeviceProfile GetProfile(IDictionary<string,string> headers);
-
+ DeviceProfile GetProfile(string id);
+
/// <summary>
/// Gets the profile.
/// </summary>
diff --git a/MediaBrowser.Controller/Dlna/MediaProfile.cs b/MediaBrowser.Controller/Dlna/MediaProfile.cs
index 9a9b56ddd..bf3057294 100644
--- a/MediaBrowser.Controller/Dlna/MediaProfile.cs
+++ b/MediaBrowser.Controller/Dlna/MediaProfile.cs
@@ -1,16 +1,27 @@
using System.Collections.Generic;
using System.Linq;
+using System.Xml.Serialization;
namespace MediaBrowser.Controller.Dlna
{
public class MediaProfile
{
+ [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; }
diff --git a/MediaBrowser.Controller/Dlna/TranscodingProfile.cs b/MediaBrowser.Controller/Dlna/TranscodingProfile.cs
index d4cfae989..289333aa7 100644
--- a/MediaBrowser.Controller/Dlna/TranscodingProfile.cs
+++ b/MediaBrowser.Controller/Dlna/TranscodingProfile.cs
@@ -1,19 +1,30 @@
using System.Collections.Generic;
using System.Linq;
+using System.Xml.Serialization;
namespace MediaBrowser.Controller.Dlna
{
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("estimateContentLength")]
public bool EstimateContentLength { get; set; }
+
+ [XmlAttribute("enableMpegtsM2TsMode")]
public bool EnableMpegtsM2TsMode { get; set; }
+
+ [XmlAttribute("transcodeSeekInfo")]
public TranscodeSeekInfo TranscodeSeekInfo { get; set; }
public TranscodingSetting[] Settings { get; set; }
@@ -32,7 +43,10 @@ namespace MediaBrowser.Controller.Dlna
public class TranscodingSetting
{
+ [XmlAttribute("name")]
public TranscodingSettingType Name { get; set; }
+
+ [XmlAttribute("value")]
public string Value { get; set; }
}
diff --git a/MediaBrowser.Controller/Entities/Trailer.cs b/MediaBrowser.Controller/Entities/Trailer.cs
index b3d73dc34..53ec030a7 100644
--- a/MediaBrowser.Controller/Entities/Trailer.cs
+++ b/MediaBrowser.Controller/Entities/Trailer.cs
@@ -3,8 +3,9 @@ using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
using System;
using System.Collections.Generic;
-using System.Runtime.Serialization;
+using System.Globalization;
using System.Linq;
+using System.Runtime.Serialization;
namespace MediaBrowser.Controller.Entities
{
@@ -22,7 +23,7 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
/// <value>The preferred metadata country code.</value>
public string PreferredMetadataCountryCode { get; set; }
-
+
public Trailer()
{
RemoteTrailers = new List<MediaUrl>();
@@ -33,19 +34,19 @@ namespace MediaBrowser.Controller.Entities
}
public float? Metascore { get; set; }
-
+
public List<Guid> LocalTrailerIds { get; set; }
-
+
public List<MediaUrl> RemoteTrailers { get; set; }
public List<string> Keywords { get; set; }
-
+
/// <summary>
/// Gets or sets the taglines.
/// </summary>
/// <value>The taglines.</value>
public List<string> Taglines { get; set; }
-
+
/// <summary>
/// Gets or sets the budget.
/// </summary>
@@ -92,6 +93,12 @@ namespace MediaBrowser.Controller.Entities
{
key = key + "-trailer";
+ // Make sure different trailers have their own data.
+ if (RunTimeTicks.HasValue)
+ {
+ key += "-" + RunTimeTicks.Value.ToString(CultureInfo.InvariantCulture);
+ }
+
return key;
}
diff --git a/MediaBrowser.Controller/Entities/User.cs b/MediaBrowser.Controller/Entities/User.cs
index e6a62c181..0a34b8016 100644
--- a/MediaBrowser.Controller/Entities/User.cs
+++ b/MediaBrowser.Controller/Entities/User.cs
@@ -121,10 +121,7 @@ namespace MediaBrowser.Controller.Entities
{
_configuration = value;
- if (value == null)
- {
- _configurationInitialized = false;
- }
+ _configurationInitialized = value != null;
}
}
diff --git a/MediaBrowser.Controller/MediaEncoding/InternalMediaInfoResult.cs b/MediaBrowser.Controller/MediaEncoding/InternalMediaInfoResult.cs
index e113521ec..39d1c3220 100644
--- a/MediaBrowser.Controller/MediaEncoding/InternalMediaInfoResult.cs
+++ b/MediaBrowser.Controller/MediaEncoding/InternalMediaInfoResult.cs
@@ -1,5 +1,4 @@
-using MediaBrowser.Model.Entities;
-using System.Collections.Generic;
+using System.Collections.Generic;
namespace MediaBrowser.Controller.MediaEncoding
{
@@ -24,7 +23,18 @@ namespace MediaBrowser.Controller.MediaEncoding
/// Gets or sets the chapters.
/// </summary>
/// <value>The chapters.</value>
- public List<ChapterInfo> Chapters { get; set; }
+ public MediaChapter[] Chapters { get; set; }
+ }
+
+ public class MediaChapter
+ {
+ public int id { get; set; }
+ public string time_base { get; set; }
+ public long start { get; set; }
+ public string start_time { get; set; }
+ public long end { get; set; }
+ public string end_time { get; set; }
+ public Dictionary<string, string> tags { get; set; }
}
/// <summary>
diff --git a/MediaBrowser.Controller/MediaEncoding/MediaEncoderHelpers.cs b/MediaBrowser.Controller/MediaEncoding/MediaEncoderHelpers.cs
index 184033177..fd1f65101 100644
--- a/MediaBrowser.Controller/MediaEncoding/MediaEncoderHelpers.cs
+++ b/MediaBrowser.Controller/MediaEncoding/MediaEncoderHelpers.cs
@@ -154,7 +154,8 @@ namespace MediaBrowser.Controller.MediaEncoding
Codec = streamInfo.codec_name,
Profile = streamInfo.profile,
Level = streamInfo.level,
- Index = streamInfo.index
+ Index = streamInfo.index,
+ PixelFormat = streamInfo.pix_fmt
};
if (streamInfo.tags != null)
@@ -196,24 +197,21 @@ namespace MediaBrowser.Controller.MediaEncoding
}
// Get stream bitrate
- if (stream.Type != MediaStreamType.Subtitle)
- {
- var bitrate = 0;
+ var bitrate = 0;
- if (!string.IsNullOrEmpty(streamInfo.bit_rate))
- {
- bitrate = int.Parse(streamInfo.bit_rate, UsCulture);
- }
- else if (formatInfo != null && !string.IsNullOrEmpty(formatInfo.bit_rate))
- {
- // If the stream info doesn't have a bitrate get the value from the media format info
- bitrate = int.Parse(formatInfo.bit_rate, UsCulture);
- }
+ if (!string.IsNullOrEmpty(streamInfo.bit_rate))
+ {
+ bitrate = int.Parse(streamInfo.bit_rate, UsCulture);
+ }
+ else if (formatInfo != null && !string.IsNullOrEmpty(formatInfo.bit_rate) && stream.Type == MediaStreamType.Video)
+ {
+ // If the stream info doesn't have a bitrate get the value from the media format info
+ bitrate = int.Parse(formatInfo.bit_rate, UsCulture);
+ }
- if (bitrate > 0)
- {
- stream.BitRate = bitrate;
- }
+ if (bitrate > 0)
+ {
+ stream.BitRate = bitrate;
}
if (streamInfo.disposition != null)
diff --git a/MediaBrowser.Dlna/DlnaManager.cs b/MediaBrowser.Dlna/DlnaManager.cs
index 78876d239..edccc71c9 100644
--- a/MediaBrowser.Dlna/DlnaManager.cs
+++ b/MediaBrowser.Dlna/DlnaManager.cs
@@ -1,10 +1,14 @@
using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Dlna;
using MediaBrowser.Dlna.Profiles;
+using MediaBrowser.Model.Dlna;
+using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Serialization;
using System;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
@@ -12,22 +16,37 @@ namespace MediaBrowser.Dlna
{
public class DlnaManager : IDlnaManager
{
- private IApplicationPaths _appPaths;
+ private readonly IApplicationPaths _appPaths;
private readonly IXmlSerializer _xmlSerializer;
private readonly IFileSystem _fileSystem;
- private readonly IJsonSerializer _jsonSerializer;
+ private readonly ILogger _logger;
- public DlnaManager(IXmlSerializer xmlSerializer, IFileSystem fileSystem, IJsonSerializer jsonSerializer)
+ public DlnaManager(IXmlSerializer xmlSerializer, IFileSystem fileSystem, IApplicationPaths appPaths, ILogger logger)
{
_xmlSerializer = xmlSerializer;
_fileSystem = fileSystem;
- _jsonSerializer = jsonSerializer;
+ _appPaths = appPaths;
+ _logger = logger;
- GetProfiles();
+ //DumpProfiles();
}
public IEnumerable<DeviceProfile> GetProfiles()
{
+ ExtractProfilesIfNeeded();
+
+ var list = GetProfiles(UserProfilesPath, DeviceProfileType.User)
+ .OrderBy(i => i.Name)
+ .ToList();
+
+ list.AddRange(GetProfiles(SystemProfilesPath, DeviceProfileType.System)
+ .OrderBy(i => i.Name));
+
+ return list;
+ }
+
+ private void DumpProfiles()
+ {
var list = new List<DeviceProfile>
{
new SamsungSmartTvProfile(),
@@ -45,27 +64,71 @@ namespace MediaBrowser.Dlna
new DenonAvrProfile(),
new LinksysDMA2100Profile(),
new LgTvProfile(),
- new Foobar2000Profile()
+ new Foobar2000Profile(),
+ new DefaultProfile()
};
foreach (var item in list)
{
- //_xmlSerializer.SerializeToFile(item, "d:\\" + _fileSystem.GetValidFilename(item.Name) + ".xml");
- //_jsonSerializer.SerializeToFile(item, "d:\\" + _fileSystem.GetValidFilename(item.Name) + ".json");
+ var path = Path.Combine(_appPaths.ProgramDataPath, _fileSystem.GetValidFilename(item.Name) + ".xml");
+
+ _xmlSerializer.SerializeToFile(item, path);
}
+ }
- return list;
+ private bool _extracted;
+ private readonly object _syncLock = new object();
+ private void ExtractProfilesIfNeeded()
+ {
+ if (!_extracted)
+ {
+ lock (_syncLock)
+ {
+ if (!_extracted)
+ {
+ try
+ {
+ ExtractSystemProfiles();
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error extracting DLNA profiles.", ex);
+ }
+
+ _extracted = true;
+ }
+
+ }
+ }
}
public DeviceProfile GetDefaultProfile()
{
+ ExtractProfilesIfNeeded();
+
return new DefaultProfile();
}
public DeviceProfile GetProfile(DeviceIdentification deviceInfo)
{
- return GetProfiles().FirstOrDefault(i => IsMatch(deviceInfo, i.Identification)) ??
- GetDefaultProfile();
+ if (deviceInfo == null)
+ {
+ throw new ArgumentNullException("deviceInfo");
+ }
+
+ var profile = GetProfiles()
+ .FirstOrDefault(i => i.Identification != null && IsMatch(deviceInfo, i.Identification));
+
+ if (profile != null)
+ {
+ _logger.Debug("Found matching device profile: {0}", profile.Name);
+ }
+ else
+ {
+ _logger.Debug("No matching device profile found. The default will need to be used.");
+ }
+
+ return profile;
}
private bool IsMatch(DeviceIdentification deviceInfo, DeviceIdentification profileInfo)
@@ -129,8 +192,12 @@ namespace MediaBrowser.Dlna
public DeviceProfile GetProfile(IDictionary<string, string> headers)
{
- return GetProfiles().FirstOrDefault(i => IsMatch(headers, i.Identification)) ??
- GetDefaultProfile();
+ if (headers == null)
+ {
+ throw new ArgumentNullException("headers");
+ }
+
+ return GetProfiles().FirstOrDefault(i => IsMatch(headers, i.Identification));
}
private bool IsMatch(IDictionary<string, string> headers, DeviceIdentification profileInfo)
@@ -159,5 +226,171 @@ namespace MediaBrowser.Dlna
return false;
}
+
+ private string UserProfilesPath
+ {
+ get
+ {
+ return Path.Combine(_appPaths.ConfigurationDirectoryPath, "dlna", "user");
+ }
+ }
+
+ private string SystemProfilesPath
+ {
+ get
+ {
+ return Path.Combine(_appPaths.ConfigurationDirectoryPath, "dlna", "system");
+ }
+ }
+
+ private IEnumerable<DeviceProfile> GetProfiles(string path, DeviceProfileType type)
+ {
+ try
+ {
+ return new DirectoryInfo(path)
+ .EnumerateFiles("*", SearchOption.TopDirectoryOnly)
+ .Where(i => string.Equals(i.Extension, ".xml", StringComparison.OrdinalIgnoreCase))
+ .Select(i => ParseProfileXmlFile(i.FullName, type))
+ .Where(i => i != null)
+ .ToList();
+ }
+ catch (DirectoryNotFoundException)
+ {
+ return new List<DeviceProfile>();
+ }
+ }
+
+ private DeviceProfile ParseProfileXmlFile(string path, DeviceProfileType type)
+ {
+ try
+ {
+ var profile = (DeviceProfile)_xmlSerializer.DeserializeFromFile(typeof(DeviceProfile), path);
+
+ profile.Id = path.ToLower().GetMD5().ToString("N");
+ profile.ProfileType = type;
+
+ return profile;
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error parsing profile xml: {0}", ex, path);
+
+ return null;
+ }
+ }
+
+ public DeviceProfile GetProfile(string id)
+ {
+ if (string.IsNullOrWhiteSpace(id))
+ {
+ throw new ArgumentNullException("id");
+ }
+
+ var info = GetProfileInfosInternal().First(i => string.Equals(i.Info.Id, id));
+
+ return ParseProfileXmlFile(info.Path, info.Info.Type);
+ }
+
+ private IEnumerable<InternalProfileInfo> GetProfileInfosInternal()
+ {
+ ExtractProfilesIfNeeded();
+
+ return GetProfileInfos(UserProfilesPath, DeviceProfileType.User)
+ .Concat(GetProfileInfos(SystemProfilesPath, DeviceProfileType.System))
+ .OrderBy(i => i.Info.Type == DeviceProfileType.User ? 0 : 1)
+ .ThenBy(i => i.Info.Name);
+ }
+
+ public IEnumerable<DeviceProfileInfo> GetProfileInfos()
+ {
+ return GetProfileInfosInternal().Select(i => i.Info);
+ }
+
+ private IEnumerable<InternalProfileInfo> GetProfileInfos(string path, DeviceProfileType type)
+ {
+ try
+ {
+ return new DirectoryInfo(path)
+ .EnumerateFiles("*", SearchOption.TopDirectoryOnly)
+ .Where(i => string.Equals(i.Extension, ".xml", StringComparison.OrdinalIgnoreCase))
+ .Select(i => new InternalProfileInfo
+ {
+ Path = i.FullName,
+
+ Info = new DeviceProfileInfo
+ {
+ Id = i.FullName.ToLower().GetMD5().ToString("N"),
+ Name = Path.GetFileNameWithoutExtension(i.FullName),
+ Type = type
+ }
+ })
+ .ToList();
+ }
+ catch (DirectoryNotFoundException)
+ {
+ return new List<InternalProfileInfo>();
+ }
+ }
+
+ private void ExtractSystemProfiles()
+ {
+ var assembly = GetType().Assembly;
+ var namespaceName = GetType().Namespace + ".Profiles.Xml.";
+
+ var systemProfilesPath = SystemProfilesPath;
+
+ foreach (var name in assembly.GetManifestResourceNames()
+ .Where(i => i.StartsWith(namespaceName))
+ .ToList())
+ {
+ var filename = Path.GetFileName(name).Substring(namespaceName.Length);
+
+ var path = Path.Combine(systemProfilesPath, filename);
+
+ using (var stream = assembly.GetManifestResourceStream(name))
+ {
+ var fileInfo = new FileInfo(path);
+
+ if (!fileInfo.Exists || fileInfo.Length != stream.Length)
+ {
+ Directory.CreateDirectory(systemProfilesPath);
+
+ using (var fileStream = _fileSystem.GetFileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read))
+ {
+ stream.CopyTo(fileStream);
+ }
+ }
+ }
+ }
+
+ // Not necessary, but just to make it easy to find
+ Directory.CreateDirectory(UserProfilesPath);
+ }
+
+ public void DeleteProfile(string id)
+ {
+ var info = GetProfileInfosInternal().First(i => string.Equals(id, i.Info.Id));
+
+ if (info.Info.Type == DeviceProfileType.System)
+ {
+ throw new ArgumentException("System profiles cannot be deleted.");
+ }
+
+ File.Delete(info.Path);
+ }
+
+ public void CreateProfile(DeviceProfile profile)
+ {
+ }
+
+ public void UpdateProfile(DeviceProfile profile)
+ {
+ }
+
+ class InternalProfileInfo
+ {
+ internal DeviceProfileInfo Info { get; set; }
+ internal string Path { get; set; }
+ }
}
} \ No newline at end of file
diff --git a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj
index bdfcae39b..df1fed12f 100644
--- a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj
+++ b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj
@@ -117,7 +117,27 @@
<Name>MediaBrowser.Model</Name>
</ProjectReference>
</ItemGroup>
- <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" />
+ <EmbeddedResource Include="Profiles\Xml\Sony PlayStation 3.xml" />
+ <EmbeddedResource Include="Profiles\Xml\WDTV Live.xml" />
+ <EmbeddedResource Include="Profiles\Xml\Xbox 360.xml" />
+ <EmbeddedResource Include="Profiles\Xml\Xbox One.xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="Profiles\Xml\Default.xml" />
+ </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/CurrentIdEventArgs.cs b/MediaBrowser.Dlna/PlayTo/CurrentIdEventArgs.cs
index 24158b890..c34293e52 100644
--- a/MediaBrowser.Dlna/PlayTo/CurrentIdEventArgs.cs
+++ b/MediaBrowser.Dlna/PlayTo/CurrentIdEventArgs.cs
@@ -4,18 +4,6 @@ namespace MediaBrowser.Dlna.PlayTo
{
public class CurrentIdEventArgs : EventArgs
{
- public Guid Id { get; set; }
-
- public CurrentIdEventArgs(string id)
- {
- if (string.IsNullOrWhiteSpace(id) || id == "0")
- {
- Id = Guid.Empty;
- }
- else
- {
- Id = new Guid(id);
- }
- }
+ public string Id { get; set; }
}
}
diff --git a/MediaBrowser.Dlna/PlayTo/Device.cs b/MediaBrowser.Dlna/PlayTo/Device.cs
index a677cf5dd..fa0bfbca8 100644
--- a/MediaBrowser.Dlna/PlayTo/Device.cs
+++ b/MediaBrowser.Dlna/PlayTo/Device.cs
@@ -42,6 +42,7 @@ namespace MediaBrowser.Dlna.PlayTo
if (_currentId == value)
return;
_currentId = value;
+
NotifyCurrentIdChanged(value);
}
}
@@ -250,7 +251,7 @@ namespace MediaBrowser.Dlna.PlayTo
StopTimer();
await SetStop().ConfigureAwait(false);
- CurrentId = "0";
+ CurrentId = null;
var command = AvCommands.ServiceActions.FirstOrDefault(c => c.Name == "SetAVTransportURI");
if (command == null)
@@ -514,7 +515,7 @@ namespace MediaBrowser.Dlna.PlayTo
if (String.IsNullOrEmpty(track))
{
- CurrentId = "0";
+ CurrentId = null;
return;
}
@@ -775,7 +776,7 @@ namespace MediaBrowser.Dlna.PlayTo
private void NotifyCurrentIdChanged(string value)
{
if (CurrentIdChanged != null)
- CurrentIdChanged.Invoke(this, new CurrentIdEventArgs(value));
+ CurrentIdChanged.Invoke(this, new CurrentIdEventArgs { Id = value });
}
#endregion
diff --git a/MediaBrowser.Dlna/PlayTo/DlnaController.cs b/MediaBrowser.Dlna/PlayTo/DlnaController.cs
index 0b0c03fcd..e4bd8819d 100644
--- a/MediaBrowser.Dlna/PlayTo/DlnaController.cs
+++ b/MediaBrowser.Dlna/PlayTo/DlnaController.cs
@@ -20,7 +20,7 @@ namespace MediaBrowser.Dlna.PlayTo
public class PlayToController : ISessionController, IDisposable
{
private Device _device;
- private BaseItem _currentItem = null;
+ private BaseItem _currentItem;
private readonly SessionInfo _session;
private readonly ISessionManager _sessionManager;
private readonly IItemRepository _itemRepository;
@@ -30,7 +30,7 @@ namespace MediaBrowser.Dlna.PlayTo
private readonly IDlnaManager _dlnaManager;
private readonly IUserManager _userManager;
private readonly IServerApplicationHost _appHost;
- private bool _playbackStarted = false;
+ private bool _playbackStarted;
private const int UpdateTimerIntervalMs = 1000;
@@ -103,22 +103,27 @@ namespace MediaBrowser.Dlna.PlayTo
async void Device_CurrentIdChanged(object sender, CurrentIdEventArgs e)
{
- if (e.Id != Guid.Empty)
+ if (!string.IsNullOrWhiteSpace(e.Id))
{
- if (_currentItem != null && _currentItem.Id == e.Id)
+ Guid guid;
+
+ if (Guid.TryParse(e.Id, out guid))
{
- return;
- }
+ if (_currentItem != null && _currentItem.Id == guid)
+ {
+ return;
+ }
- var item = _libraryManager.GetItemById(e.Id);
+ var item = _libraryManager.GetItemById(guid);
- if (item != null)
- {
- _logger.Debug("{0} - CurrentId {1}", _session.DeviceName, item.Id);
- _currentItem = item;
- _playbackStarted = false;
+ if (item != null)
+ {
+ _logger.Debug("{0} - CurrentId {1}", _session.DeviceName, item.Id);
+ _currentItem = item;
+ _playbackStarted = false;
- await ReportProgress().ConfigureAwait(false);
+ await ReportProgress().ConfigureAwait(false);
+ }
}
}
}
@@ -167,8 +172,8 @@ namespace MediaBrowser.Dlna.PlayTo
{
Item = _currentItem,
SessionId = _session.Id,
- CanSeek = true,
- QueueableMediaTypes = new List<string> { "Audio", "Video" }
+ CanSeek = true,
+ QueueableMediaTypes = new List<string> { _currentItem.MediaType }
}).ConfigureAwait(false);
@@ -414,10 +419,12 @@ namespace MediaBrowser.Dlna.PlayTo
var deviceInfo = _device.Properties;
- var profile = _dlnaManager.GetProfile(deviceInfo.ToDeviceIdentification());
+ var profile = _dlnaManager.GetProfile(deviceInfo.ToDeviceIdentification()) ??
+ _dlnaManager.GetDefaultProfile();
var playlistItem = GetPlaylistItem(item, streams, profile);
playlistItem.StartPositionTicks = startPostionTicks;
+ playlistItem.DeviceProfileId = profile.Id;
if (playlistItem.MediaType == DlnaProfileType.Audio)
{
diff --git a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs
index 297f7a696..9e73450cb 100644
--- a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs
+++ b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs
@@ -239,9 +239,13 @@ namespace MediaBrowser.Dlna.PlayTo
controller.Init(device);
+ var profile = _dlnaManager.GetProfile(device.Properties.ToDeviceIdentification()) ??
+ _dlnaManager.GetDefaultProfile();
+
_sessionManager.ReportCapabilities(sessionInfo.Id, new SessionCapabilities
{
- PlayableMediaTypes = new[] { MediaType.Audio, MediaType.Video, MediaType.Photo },
+ PlayableMediaTypes = profile.GetSupportedMediaTypes().ToArray(),
+
SupportsFullscreenToggle = false
});
diff --git a/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs b/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs
index e1eea0824..50605c61f 100644
--- a/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs
+++ b/MediaBrowser.Dlna/PlayTo/PlaylistItem.cs
@@ -46,6 +46,8 @@ namespace MediaBrowser.Dlna.PlayTo
public int? MaxFramerate { get; set; }
+ public string DeviceProfileId { get; set; }
+
public PlaylistItem()
{
TranscodingSettings = new List<TranscodingSetting>();
diff --git a/MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs b/MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs
index 0dec9bbf3..f79dc1e5f 100644
--- a/MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs
+++ b/MediaBrowser.Dlna/PlayTo/PlaylistItemFactory.cs
@@ -191,9 +191,7 @@ namespace MediaBrowser.Dlna.PlayTo
case ProfileConditionValue.AudioProfile:
case ProfileConditionValue.Has64BitOffsets:
case ProfileConditionValue.VideoBitDepth:
- case ProfileConditionValue.VideoPacketLength:
case ProfileConditionValue.VideoProfile:
- case ProfileConditionValue.VideoTimestamp:
{
// Not supported yet
break;
@@ -461,12 +459,6 @@ namespace MediaBrowser.Dlna.PlayTo
return videoStream == null ? null : videoStream.Width;
case ProfileConditionValue.VideoLevel:
return videoStream == null ? null : ConvertToLong(videoStream.Level);
- case ProfileConditionValue.VideoPacketLength:
- // TODO: Determine how to get this
- return null;
- case ProfileConditionValue.VideoTimestamp:
- // TODO: Determine how to get this
- return null;
default:
throw new InvalidOperationException("Unexpected Property");
}
diff --git a/MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs b/MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs
index b1ae21a43..42c788d38 100644
--- a/MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs
+++ b/MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs
@@ -22,7 +22,11 @@ namespace MediaBrowser.Dlna.PlayTo
_config = config;
}
- public async Task<XDocument> SendCommandAsync(string baseUrl, DeviceService 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;
if (!serviceUrl.StartsWith("/"))
@@ -40,7 +44,12 @@ namespace MediaBrowser.Dlna.PlayTo
}
}
- public async Task SubscribeAsync(string url, string ip, int port, string localIp, int eventport, int timeOut = 3600)
+ public async Task SubscribeAsync(string url,
+ string ip,
+ int port,
+ string localIp,
+ int eventport,
+ int timeOut = 3600)
{
var options = new HttpRequestOptions
{
@@ -59,7 +68,11 @@ namespace MediaBrowser.Dlna.PlayTo
}
}
- public async Task RespondAsync(Uri url, string ip, int port, string localIp, int eventport, int timeOut = 20000)
+ public async Task RespondAsync(Uri url,
+ string ip,
+ int port,
+ string localIp,
+ int eventport)
{
var options = new HttpRequestOptions
{
@@ -97,7 +110,10 @@ namespace MediaBrowser.Dlna.PlayTo
}
}
- private Task<HttpResponseInfo> PostSoapDataAsync(string url, string soapAction, string postData, string header = null)
+ private Task<HttpResponseInfo> PostSoapDataAsync(string url,
+ string soapAction,
+ string postData,
+ string header = null)
{
if (!soapAction.StartsWith("\""))
soapAction = "\"" + soapAction + "\"";
diff --git a/MediaBrowser.Dlna/PlayTo/StreamHelper.cs b/MediaBrowser.Dlna/PlayTo/StreamHelper.cs
index a4855c94f..b65e94fd1 100644
--- a/MediaBrowser.Dlna/PlayTo/StreamHelper.cs
+++ b/MediaBrowser.Dlna/PlayTo/StreamHelper.cs
@@ -1,8 +1,6 @@
-using MediaBrowser.Controller.Dlna;
-using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Entities;
using System.Collections.Generic;
using System.Globalization;
-using System.Linq;
namespace MediaBrowser.Dlna.PlayTo
{
@@ -47,6 +45,7 @@ namespace MediaBrowser.Dlna.PlayTo
var list = new List<string>
{
+ item.DeviceProfileId ?? string.Empty,
deviceProperties.UUID ?? string.Empty,
item.MediaSourceId ?? string.Empty,
(!item.Transcode).ToString().ToLower(),
diff --git a/MediaBrowser.Dlna/Profiles/DefaultProfile.cs b/MediaBrowser.Dlna/Profiles/DefaultProfile.cs
index 214b6f814..0efe18755 100644
--- a/MediaBrowser.Dlna/Profiles/DefaultProfile.cs
+++ b/MediaBrowser.Dlna/Profiles/DefaultProfile.cs
@@ -1,7 +1,9 @@
using MediaBrowser.Controller.Dlna;
+using System.Xml.Serialization;
namespace MediaBrowser.Dlna.Profiles
{
+ [XmlRoot("Profile")]
public class DefaultProfile : DeviceProfile
{
public DefaultProfile()
@@ -10,6 +12,7 @@ namespace MediaBrowser.Dlna.Profiles
ProtocolInfo = "DLNA";
+ FriendlyName = "Media Browser";
Manufacturer = "Media Browser";
ModelDescription = "Media Browser";
ModelName = "Media Browser";
diff --git a/MediaBrowser.Dlna/Profiles/DenonAvrProfile.cs b/MediaBrowser.Dlna/Profiles/DenonAvrProfile.cs
index cca6ab6bb..3c5064ad6 100644
--- a/MediaBrowser.Dlna/Profiles/DenonAvrProfile.cs
+++ b/MediaBrowser.Dlna/Profiles/DenonAvrProfile.cs
@@ -1,7 +1,9 @@
-using MediaBrowser.Controller.Dlna;
+using System.Xml.Serialization;
+using MediaBrowser.Controller.Dlna;
namespace MediaBrowser.Dlna.Profiles
{
+ [XmlRoot("Profile")]
public class DenonAvrProfile : DefaultProfile
{
public DenonAvrProfile()
diff --git a/MediaBrowser.Dlna/Profiles/Foobar2000Profile.cs b/MediaBrowser.Dlna/Profiles/Foobar2000Profile.cs
index 877f1a666..198b0a73a 100644
--- a/MediaBrowser.Dlna/Profiles/Foobar2000Profile.cs
+++ b/MediaBrowser.Dlna/Profiles/Foobar2000Profile.cs
@@ -1,13 +1,17 @@
using MediaBrowser.Controller.Dlna;
+using System.Xml.Serialization;
namespace MediaBrowser.Dlna.Profiles
{
+ [XmlRoot("Profile")]
public class Foobar2000Profile : DefaultProfile
{
public Foobar2000Profile()
{
Name = "foobar2000";
+ SupportedMediaTypes = "Audio";
+
Identification = new DeviceIdentification
{
FriendlyName = @"foobar",
diff --git a/MediaBrowser.Dlna/Profiles/LgTvProfile.cs b/MediaBrowser.Dlna/Profiles/LgTvProfile.cs
index ec20c9df8..7ca8069da 100644
--- a/MediaBrowser.Dlna/Profiles/LgTvProfile.cs
+++ b/MediaBrowser.Dlna/Profiles/LgTvProfile.cs
@@ -1,7 +1,9 @@
-using MediaBrowser.Controller.Dlna;
+using System.Xml.Serialization;
+using MediaBrowser.Controller.Dlna;
namespace MediaBrowser.Dlna.Profiles
{
+ [XmlRoot("Profile")]
public class LgTvProfile : DefaultProfile
{
public LgTvProfile()
diff --git a/MediaBrowser.Dlna/Profiles/LinksysDMA2100Profile.cs b/MediaBrowser.Dlna/Profiles/LinksysDMA2100Profile.cs
index e7086c205..a64cd24f3 100644
--- a/MediaBrowser.Dlna/Profiles/LinksysDMA2100Profile.cs
+++ b/MediaBrowser.Dlna/Profiles/LinksysDMA2100Profile.cs
@@ -1,7 +1,9 @@
-using MediaBrowser.Controller.Dlna;
+using System.Xml.Serialization;
+using MediaBrowser.Controller.Dlna;
namespace MediaBrowser.Dlna.Profiles
{
+ [XmlRoot("Profile")]
public class LinksysDMA2100Profile : DefaultProfile
{
public LinksysDMA2100Profile()
diff --git a/MediaBrowser.Dlna/Profiles/PanasonicVieraProfile.cs b/MediaBrowser.Dlna/Profiles/PanasonicVieraProfile.cs
index 6755c0680..64747776c 100644
--- a/MediaBrowser.Dlna/Profiles/PanasonicVieraProfile.cs
+++ b/MediaBrowser.Dlna/Profiles/PanasonicVieraProfile.cs
@@ -1,19 +1,21 @@
-using MediaBrowser.Controller.Dlna;
+using System.Xml.Serialization;
+using MediaBrowser.Controller.Dlna;
namespace MediaBrowser.Dlna.Profiles
{
- public class PanasonicVieraProfile : DefaultProfile
+ [XmlRoot("Profile")]
+ public class PanasonicVieraProfile : DefaultProfile
{
- public PanasonicVieraProfile()
- {
- Name = "Panasonic Viera";
+ public PanasonicVieraProfile()
+ {
+ Name = "Panasonic Viera";
- Identification = new DeviceIdentification
- {
- FriendlyName = @"VIERA",
- Manufacturer = "Panasonic",
+ Identification = new DeviceIdentification
+ {
+ FriendlyName = @"VIERA",
+ Manufacturer = "Panasonic",
- Headers = new[]
+ Headers = new[]
{
new HttpHeaderInfo
{
@@ -22,11 +24,11 @@ namespace MediaBrowser.Dlna.Profiles
Match = HeaderMatchType.Substring
}
}
- };
+ };
- TimelineOffsetSeconds = 10;
+ TimelineOffsetSeconds = 10;
- TranscodingProfiles = new[]
+ TranscodingProfiles = new[]
{
new TranscodingProfile
{
@@ -48,7 +50,7 @@ namespace MediaBrowser.Dlna.Profiles
}
};
- DirectPlayProfiles = new[]
+ DirectPlayProfiles = new[]
{
new DirectPlayProfile
{
@@ -127,7 +129,7 @@ namespace MediaBrowser.Dlna.Profiles
}
};
- ContainerProfiles = new[]
+ ContainerProfiles = new[]
{
new ContainerProfile
{
@@ -151,7 +153,7 @@ namespace MediaBrowser.Dlna.Profiles
}
};
- CodecProfiles = new[]
+ CodecProfiles = new[]
{
new CodecProfile
{
@@ -181,6 +183,6 @@ namespace MediaBrowser.Dlna.Profiles
}
}
};
- }
+ }
}
}
diff --git a/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs b/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs
index fbbb7a594..259d8e9ff 100644
--- a/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs
+++ b/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs
@@ -1,14 +1,16 @@
-using MediaBrowser.Controller.Dlna;
+using System.Xml.Serialization;
+using MediaBrowser.Controller.Dlna;
namespace MediaBrowser.Dlna.Profiles
{
+ [XmlRoot("Profile")]
public class SamsungSmartTvProfile : DefaultProfile
{
public SamsungSmartTvProfile()
{
Name = "Samsung Smart TV";
- SupportsAlbumArtInDidl = true;
+ EnableAlbumArtInDidl = true;
Identification = new DeviceIdentification
{
diff --git a/MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2013Profile.cs b/MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2013Profile.cs
index cec29b418..04309d55f 100644
--- a/MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2013Profile.cs
+++ b/MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2013Profile.cs
@@ -1,7 +1,9 @@
-using MediaBrowser.Controller.Dlna;
+using System.Xml.Serialization;
+using MediaBrowser.Controller.Dlna;
namespace MediaBrowser.Dlna.Profiles
{
+ [XmlRoot("Profile")]
public class SonyBlurayPlayer2013Profile : DefaultProfile
{
public SonyBlurayPlayer2013Profile()
diff --git a/MediaBrowser.Dlna/Profiles/SonyBlurayPlayerProfile.cs b/MediaBrowser.Dlna/Profiles/SonyBlurayPlayerProfile.cs
index 2c678b11f..d9dfc1caf 100644
--- a/MediaBrowser.Dlna/Profiles/SonyBlurayPlayerProfile.cs
+++ b/MediaBrowser.Dlna/Profiles/SonyBlurayPlayerProfile.cs
@@ -1,7 +1,9 @@
-using MediaBrowser.Controller.Dlna;
+using System.Xml.Serialization;
+using MediaBrowser.Controller.Dlna;
namespace MediaBrowser.Dlna.Profiles
{
+ [XmlRoot("Profile")]
public class SonyBlurayPlayerProfile : DefaultProfile
{
public SonyBlurayPlayerProfile()
diff --git a/MediaBrowser.Dlna/Profiles/SonyBravia2010Profile.cs b/MediaBrowser.Dlna/Profiles/SonyBravia2010Profile.cs
index 042cc0a96..cb91de4a0 100644
--- a/MediaBrowser.Dlna/Profiles/SonyBravia2010Profile.cs
+++ b/MediaBrowser.Dlna/Profiles/SonyBravia2010Profile.cs
@@ -1,7 +1,9 @@
-using MediaBrowser.Controller.Dlna;
+using System.Xml.Serialization;
+using MediaBrowser.Controller.Dlna;
namespace MediaBrowser.Dlna.Profiles
{
+ [XmlRoot("Profile")]
public class SonyBravia2010Profile : DefaultProfile
{
public SonyBravia2010Profile()
@@ -96,13 +98,7 @@ namespace MediaBrowser.Dlna.Profiles
AudioCodec="ac3,aac,mp3",
MimeType = "video/vnd.dlna.mpeg-tts",
OrgPn="AVC_TS_HD_24_AC3_T,AVC_TS_HD_50_AC3_T,AVC_TS_HD_60_AC3_T,AVC_TS_HD_EU_T",
- Type = DlnaProfileType.Video,
-
- Conditions = new []
- {
- new ProfileCondition{ Condition= ProfileConditionType.Equals, Property= ProfileConditionValue.VideoPacketLength, Value="192"},
- new ProfileCondition{ Condition= ProfileConditionType.Equals, Property= ProfileConditionValue.VideoTimestamp, Value="1"}
- }
+ Type = DlnaProfileType.Video
},
new MediaProfile
@@ -112,12 +108,7 @@ namespace MediaBrowser.Dlna.Profiles
AudioCodec="ac3,aac,mp3",
MimeType = "video/mpeg",
OrgPn="AVC_TS_HD_24_AC3_ISO,AVC_TS_HD_50_AC3_ISO,AVC_TS_HD_60_AC3_ISO,AVC_TS_HD_EU_ISO",
- Type = DlnaProfileType.Video,
-
- Conditions = new []
- {
- new ProfileCondition{ Condition= ProfileConditionType.Equals, Property= ProfileConditionValue.VideoPacketLength, Value="188"}
- }
+ Type = DlnaProfileType.Video
},
new MediaProfile
diff --git a/MediaBrowser.Dlna/Profiles/SonyBravia2011Profile.cs b/MediaBrowser.Dlna/Profiles/SonyBravia2011Profile.cs
index 401c40c36..626a91a73 100644
--- a/MediaBrowser.Dlna/Profiles/SonyBravia2011Profile.cs
+++ b/MediaBrowser.Dlna/Profiles/SonyBravia2011Profile.cs
@@ -1,7 +1,9 @@
-using MediaBrowser.Controller.Dlna;
+using System.Xml.Serialization;
+using MediaBrowser.Controller.Dlna;
namespace MediaBrowser.Dlna.Profiles
{
+ [XmlRoot("Profile")]
public class SonyBravia2011Profile : DefaultProfile
{
public SonyBravia2011Profile()
@@ -138,13 +140,7 @@ namespace MediaBrowser.Dlna.Profiles
AudioCodec="ac3,aac,mp3",
MimeType = "video/vnd.dlna.mpeg-tts",
OrgPn="AVC_TS_HD_24_AC3_T,AVC_TS_HD_50_AC3_T,AVC_TS_HD_60_AC3_T,AVC_TS_HD_EU_T",
- Type = DlnaProfileType.Video,
-
- Conditions = new []
- {
- new ProfileCondition{ Condition= ProfileConditionType.Equals, Property= ProfileConditionValue.VideoPacketLength, Value="192"},
- new ProfileCondition{ Condition= ProfileConditionType.Equals, Property= ProfileConditionValue.VideoTimestamp, Value="1"}
- }
+ Type = DlnaProfileType.Video
},
new MediaProfile
@@ -154,12 +150,7 @@ namespace MediaBrowser.Dlna.Profiles
AudioCodec="ac3,aac,mp3",
MimeType = "video/mpeg",
OrgPn="AVC_TS_HD_24_AC3_ISO,AVC_TS_HD_50_AC3_ISO,AVC_TS_HD_60_AC3_ISO,AVC_TS_HD_EU_ISO",
- Type = DlnaProfileType.Video,
-
- Conditions = new []
- {
- new ProfileCondition{ Condition= ProfileConditionType.Equals, Property= ProfileConditionValue.VideoPacketLength, Value="188"}
- }
+ Type = DlnaProfileType.Video
},
new MediaProfile
diff --git a/MediaBrowser.Dlna/Profiles/SonyBravia2012Profile.cs b/MediaBrowser.Dlna/Profiles/SonyBravia2012Profile.cs
index 2d24c406e..82b6b6d5f 100644
--- a/MediaBrowser.Dlna/Profiles/SonyBravia2012Profile.cs
+++ b/MediaBrowser.Dlna/Profiles/SonyBravia2012Profile.cs
@@ -1,7 +1,9 @@
-using MediaBrowser.Controller.Dlna;
+using System.Xml.Serialization;
+using MediaBrowser.Controller.Dlna;
namespace MediaBrowser.Dlna.Profiles
{
+ [XmlRoot("Profile")]
public class SonyBravia2012Profile : DefaultProfile
{
public SonyBravia2012Profile()
@@ -126,13 +128,7 @@ namespace MediaBrowser.Dlna.Profiles
AudioCodec="ac3,aac,mp3",
MimeType = "video/vnd.dlna.mpeg-tts",
OrgPn="AVC_TS_HD_24_AC3_T,AVC_TS_HD_50_AC3_T,AVC_TS_HD_60_AC3_T,AVC_TS_HD_EU_T",
- Type = DlnaProfileType.Video,
-
- Conditions = new []
- {
- new ProfileCondition{ Condition= ProfileConditionType.Equals, Property= ProfileConditionValue.VideoPacketLength, Value="192"},
- new ProfileCondition{ Condition= ProfileConditionType.Equals, Property= ProfileConditionValue.VideoTimestamp, Value="1"}
- }
+ Type = DlnaProfileType.Video
},
new MediaProfile
@@ -142,12 +138,7 @@ namespace MediaBrowser.Dlna.Profiles
AudioCodec="ac3,aac,mp3",
MimeType = "video/mpeg",
OrgPn="AVC_TS_HD_24_AC3_ISO,AVC_TS_HD_50_AC3_ISO,AVC_TS_HD_60_AC3_ISO,AVC_TS_HD_EU_ISO",
- Type = DlnaProfileType.Video,
-
- Conditions = new []
- {
- new ProfileCondition{ Condition= ProfileConditionType.Equals, Property= ProfileConditionValue.VideoPacketLength, Value="188"}
- }
+ Type = DlnaProfileType.Video
},
new MediaProfile
diff --git a/MediaBrowser.Dlna/Profiles/SonyBravia2013Profile.cs b/MediaBrowser.Dlna/Profiles/SonyBravia2013Profile.cs
index 10f712958..aec65e98e 100644
--- a/MediaBrowser.Dlna/Profiles/SonyBravia2013Profile.cs
+++ b/MediaBrowser.Dlna/Profiles/SonyBravia2013Profile.cs
@@ -1,7 +1,9 @@
-using MediaBrowser.Controller.Dlna;
+using System.Xml.Serialization;
+using MediaBrowser.Controller.Dlna;
namespace MediaBrowser.Dlna.Profiles
{
+ [XmlRoot("Profile")]
public class SonyBravia2013Profile : DefaultProfile
{
public SonyBravia2013Profile()
@@ -182,13 +184,7 @@ namespace MediaBrowser.Dlna.Profiles
AudioCodec="ac3,aac,mp3",
MimeType = "video/vnd.dlna.mpeg-tts",
OrgPn="AVC_TS_HD_24_AC3_T,AVC_TS_HD_50_AC3_T,AVC_TS_HD_60_AC3_T,AVC_TS_HD_EU_T",
- Type = DlnaProfileType.Video,
-
- Conditions = new []
- {
- new ProfileCondition{ Condition= ProfileConditionType.Equals, Property= ProfileConditionValue.VideoPacketLength, Value="192"},
- new ProfileCondition{ Condition= ProfileConditionType.Equals, Property= ProfileConditionValue.VideoTimestamp, Value="1"}
- }
+ Type = DlnaProfileType.Video
},
new MediaProfile
@@ -198,12 +194,7 @@ namespace MediaBrowser.Dlna.Profiles
AudioCodec="ac3,aac,mp3",
MimeType = "video/mpeg",
OrgPn="AVC_TS_HD_24_AC3_ISO,AVC_TS_HD_50_AC3_ISO,AVC_TS_HD_60_AC3_ISO,AVC_TS_HD_EU_ISO",
- Type = DlnaProfileType.Video,
-
- Conditions = new []
- {
- new ProfileCondition{ Condition= ProfileConditionType.Equals, Property= ProfileConditionValue.VideoPacketLength, Value="188"}
- }
+ Type = DlnaProfileType.Video
},
new MediaProfile
diff --git a/MediaBrowser.Dlna/Profiles/SonyPs3Profile.cs b/MediaBrowser.Dlna/Profiles/SonyPs3Profile.cs
index 39490f806..7502201ea 100644
--- a/MediaBrowser.Dlna/Profiles/SonyPs3Profile.cs
+++ b/MediaBrowser.Dlna/Profiles/SonyPs3Profile.cs
@@ -1,7 +1,9 @@
-using MediaBrowser.Controller.Dlna;
+using System.Xml.Serialization;
+using MediaBrowser.Controller.Dlna;
namespace MediaBrowser.Dlna.Profiles
{
+ [XmlRoot("Profile")]
public class SonyPs3Profile : DefaultProfile
{
public SonyPs3Profile()
diff --git a/MediaBrowser.Dlna/Profiles/WdtvLiveProfile.cs b/MediaBrowser.Dlna/Profiles/WdtvLiveProfile.cs
index 47c7b21cc..af5d9b295 100644
--- a/MediaBrowser.Dlna/Profiles/WdtvLiveProfile.cs
+++ b/MediaBrowser.Dlna/Profiles/WdtvLiveProfile.cs
@@ -1,7 +1,9 @@
using MediaBrowser.Controller.Dlna;
+using System.Xml.Serialization;
namespace MediaBrowser.Dlna.Profiles
{
+ [XmlRoot("Profile")]
public class WdtvLiveProfile : DefaultProfile
{
public WdtvLiveProfile()
diff --git a/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs b/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs
index 660d821d3..640317fbc 100644
--- a/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs
+++ b/MediaBrowser.Dlna/Profiles/Xbox360Profile.cs
@@ -1,7 +1,9 @@
-using MediaBrowser.Controller.Dlna;
+using System.Xml.Serialization;
+using MediaBrowser.Controller.Dlna;
namespace MediaBrowser.Dlna.Profiles
{
+ [XmlRoot("Profile")]
public class Xbox360Profile : DefaultProfile
{
public Xbox360Profile()
diff --git a/MediaBrowser.Dlna/Profiles/XboxOneProfile.cs b/MediaBrowser.Dlna/Profiles/XboxOneProfile.cs
index 0daa5d7a2..058c69e1f 100644
--- a/MediaBrowser.Dlna/Profiles/XboxOneProfile.cs
+++ b/MediaBrowser.Dlna/Profiles/XboxOneProfile.cs
@@ -1,7 +1,9 @@
-using MediaBrowser.Controller.Dlna;
+using System.Xml.Serialization;
+using MediaBrowser.Controller.Dlna;
namespace MediaBrowser.Dlna.Profiles
{
+ [XmlRoot("Profile")]
public class XboxOneProfile : DefaultProfile
{
public XboxOneProfile()
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Default.xml b/MediaBrowser.Dlna/Profiles/Xml/Default.xml
new file mode 100644
index 000000000..52b92c6f3
--- /dev/null
+++ b/MediaBrowser.Dlna/Profiles/Xml/Default.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0"?>
+<Profile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <Name>Generic Device</Name>
+ <FriendlyName>Media Browser</FriendlyName>
+ <Manufacturer>Media Browser</Manufacturer>
+ <ManufacturerUrl>http://mediabrowser3.com/</ManufacturerUrl>
+ <ModelName>Media Browser</ModelName>
+ <ModelDescription>Media Browser</ModelDescription>
+ <ModelNumber>Media Browser</ModelNumber>
+ <ModelUrl>http://mediabrowser3.com/</ModelUrl>
+ <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
+ <EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
+ <SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
+ <ProtocolInfo>DLNA</ProtocolInfo>
+ <TimelineOffsetSeconds>0</TimelineOffsetSeconds>
+ <RequiresPlainVideoItems>false</RequiresPlainVideoItems>
+ <RequiresPlainFolders>false</RequiresPlainFolders>
+ <DirectPlayProfiles>
+ <DirectPlayProfile container="mp3,wma" type="Audio" />
+ <DirectPlayProfile container="avi,mp4" type="Video" />
+ </DirectPlayProfiles>
+ <TranscodingProfiles>
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings>
+ <TranscodingSetting name="VideoProfile" value="baseline" />
+ </Settings>
+ </TranscodingProfile>
+ </TranscodingProfiles>
+ <ContainerProfiles />
+ <CodecProfiles>
+ <CodecProfile type="VideoCodec">
+ <Conditions>
+ <ProfileCondition condition="LessThanEqual" property="VideoLevel" value="3" isRequired="false" />
+ </Conditions>
+ </CodecProfile>
+ </CodecProfiles>
+ <MediaProfiles />
+</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml b/MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml
new file mode 100644
index 000000000..3332e4d45
--- /dev/null
+++ b/MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+<Profile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <Name>Denon AVR</Name>
+ <Identification>
+ <FriendlyName>Denon:\[AVR:.*</FriendlyName>
+ <Manufacturer>Denon</Manufacturer>
+ <Headers />
+ </Identification>
+ <FriendlyName>Media Browser</FriendlyName>
+ <Manufacturer>Media Browser</Manufacturer>
+ <ManufacturerUrl>http://mediabrowser3.com/</ManufacturerUrl>
+ <ModelName>Media Browser</ModelName>
+ <ModelDescription>Media Browser</ModelDescription>
+ <ModelNumber>Media Browser</ModelNumber>
+ <ModelUrl>http://mediabrowser3.com/</ModelUrl>
+ <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
+ <EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
+ <SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
+ <ProtocolInfo>DLNA</ProtocolInfo>
+ <TimelineOffsetSeconds>0</TimelineOffsetSeconds>
+ <RequiresPlainVideoItems>false</RequiresPlainVideoItems>
+ <RequiresPlainFolders>false</RequiresPlainFolders>
+ <DirectPlayProfiles>
+ <DirectPlayProfile container="mp3,flac,m4a,wma" type="Audio" />
+ </DirectPlayProfiles>
+ <TranscodingProfiles>
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings>
+ <TranscodingSetting name="VideoProfile" value="baseline" />
+ </Settings>
+ </TranscodingProfile>
+ </TranscodingProfiles>
+ <ContainerProfiles />
+ <CodecProfiles>
+ <CodecProfile type="VideoCodec">
+ <Conditions>
+ <ProfileCondition condition="LessThanEqual" property="VideoLevel" value="3" isRequired="false" />
+ </Conditions>
+ </CodecProfile>
+ </CodecProfiles>
+ <MediaProfiles />
+</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml b/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml
new file mode 100644
index 000000000..cc8b40430
--- /dev/null
+++ b/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0"?>
+<Profile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <Name>LG Smart TV</Name>
+ <Identification>
+ <FriendlyName>LG.*</FriendlyName>
+ <Headers>
+ <HttpHeaderInfo name="User-Agent" value="LG" match="Substring" />
+ </Headers>
+ </Identification>
+ <FriendlyName>Media Browser</FriendlyName>
+ <Manufacturer>Media Browser</Manufacturer>
+ <ManufacturerUrl>http://mediabrowser3.com/</ManufacturerUrl>
+ <ModelName>Media Browser</ModelName>
+ <ModelDescription>Media Browser</ModelDescription>
+ <ModelNumber>Media Browser</ModelNumber>
+ <ModelUrl>http://mediabrowser3.com/</ModelUrl>
+ <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
+ <EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
+ <SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
+ <ProtocolInfo>DLNA</ProtocolInfo>
+ <TimelineOffsetSeconds>10</TimelineOffsetSeconds>
+ <RequiresPlainVideoItems>false</RequiresPlainVideoItems>
+ <RequiresPlainFolders>false</RequiresPlainFolders>
+ <DirectPlayProfiles>
+ <DirectPlayProfile container="ts" audioCodec="aac,ac3,mp3" videoCodec="h264" type="Video" />
+ <DirectPlayProfile container="mkv" audioCodec="aac,ac3,mp3" videoCodec="h264" type="Video" />
+ <DirectPlayProfile container="mp4" audioCodec="aac,ac3,mp3" videoCodec="h264,mpeg4" type="Video" />
+ <DirectPlayProfile container="mp3" audioCodec="mp3" type="Audio" />
+ <DirectPlayProfile container="jpeg" type="Photo" />
+ </DirectPlayProfiles>
+ <TranscodingProfiles>
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ </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="VideoCodec" codec="mpeg4">
+ <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>
+ </CodecProfile>
+ <CodecProfile type="VideoCodec" 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="VideoLevel" value="41" isRequired="true" />
+ </Conditions>
+ </CodecProfile>
+ <CodecProfile type="VideoAudioCodec" codec="ac3,aac,mp3">
+ <Conditions>
+ <ProfileCondition condition="LessThanEqual" property="AudioChannels" value="6" isRequired="true" />
+ </Conditions>
+ </CodecProfile>
+ </CodecProfiles>
+ <MediaProfiles />
+</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml b/MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml
new file mode 100644
index 000000000..b19cb0f7b
--- /dev/null
+++ b/MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+<Profile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <Name>Linksys DMA2100</Name>
+ <Identification>
+ <ModelName>DMA2100us</ModelName>
+ <Headers />
+ </Identification>
+ <FriendlyName>Media Browser</FriendlyName>
+ <Manufacturer>Media Browser</Manufacturer>
+ <ManufacturerUrl>http://mediabrowser3.com/</ManufacturerUrl>
+ <ModelName>Media Browser</ModelName>
+ <ModelDescription>Media Browser</ModelDescription>
+ <ModelNumber>Media Browser</ModelNumber>
+ <ModelUrl>http://mediabrowser3.com/</ModelUrl>
+ <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
+ <EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
+ <SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
+ <ProtocolInfo>DLNA</ProtocolInfo>
+ <TimelineOffsetSeconds>0</TimelineOffsetSeconds>
+ <RequiresPlainVideoItems>false</RequiresPlainVideoItems>
+ <RequiresPlainFolders>false</RequiresPlainFolders>
+ <DirectPlayProfiles>
+ <DirectPlayProfile container="mp3,flac,m4a,wma" type="Audio" />
+ <DirectPlayProfile container="avi,mp4,mkv,ts" type="Video" />
+ </DirectPlayProfiles>
+ <TranscodingProfiles>
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings>
+ <TranscodingSetting name="VideoProfile" value="baseline" />
+ </Settings>
+ </TranscodingProfile>
+ </TranscodingProfiles>
+ <ContainerProfiles />
+ <CodecProfiles>
+ <CodecProfile type="VideoCodec">
+ <Conditions>
+ <ProfileCondition condition="LessThanEqual" property="VideoLevel" value="3" isRequired="false" />
+ </Conditions>
+ </CodecProfile>
+ </CodecProfiles>
+ <MediaProfiles />
+</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml b/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml
new file mode 100644
index 000000000..71e240313
--- /dev/null
+++ b/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0"?>
+<Profile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <Name>Panasonic Viera</Name>
+ <Identification>
+ <FriendlyName>VIERA</FriendlyName>
+ <Manufacturer>Panasonic</Manufacturer>
+ <Headers>
+ <HttpHeaderInfo name="User-Agent" value="Panasonic MIL DLNA" match="Substring" />
+ </Headers>
+ </Identification>
+ <FriendlyName>Media Browser</FriendlyName>
+ <Manufacturer>Media Browser</Manufacturer>
+ <ManufacturerUrl>http://mediabrowser3.com/</ManufacturerUrl>
+ <ModelName>Media Browser</ModelName>
+ <ModelDescription>Media Browser</ModelDescription>
+ <ModelNumber>Media Browser</ModelNumber>
+ <ModelUrl>http://mediabrowser3.com/</ModelUrl>
+ <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
+ <EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
+ <SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
+ <ProtocolInfo>DLNA</ProtocolInfo>
+ <TimelineOffsetSeconds>10</TimelineOffsetSeconds>
+ <RequiresPlainVideoItems>false</RequiresPlainVideoItems>
+ <RequiresPlainFolders>false</RequiresPlainFolders>
+ <DirectPlayProfiles>
+ <DirectPlayProfile container="mpeg" audioCodec="ac3,mp3" videoCodec="mpeg2video,mpeg4" type="Video" />
+ <DirectPlayProfile container="mkv" audioCodec="aac,ac3,mp3,pcm" videoCodec="h264" type="Video" />
+ <DirectPlayProfile container="ts" audioCodec="aac,mp3" videoCodec="h264" type="Video" />
+ <DirectPlayProfile container="mp4" audioCodec="aac,ac3,mp3,pcm" videoCodec="h264" type="Video" />
+ <DirectPlayProfile container="mov" audioCodec="aac,pcm" videoCodec="h264" type="Video" />
+ <DirectPlayProfile container="avi" audioCodec="pcm" videoCodec="mpeg4" type="Video" />
+ <DirectPlayProfile container="flv" audioCodec="aac" videoCodec="h264" type="Video" />
+ <DirectPlayProfile container="mp3" audioCodec="mp3" type="Audio" />
+ <DirectPlayProfile container="mp4" audioCodec="aac" type="Audio" />
+ <DirectPlayProfile container="jpeg" type="Photo" />
+ </DirectPlayProfiles>
+ <TranscodingProfiles>
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ </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="VideoCodec">
+ <Conditions>
+ <ProfileCondition condition="LessThanEqual" property="Width" value="1920" isRequired="true" />
+ <ProfileCondition condition="LessThanEqual" property="Height" value="1080" isRequired="true" />
+ <ProfileCondition condition="LessThanEqual" property="VideoBitDepth" value="8" isRequired="false" />
+ </Conditions>
+ </CodecProfile>
+ </CodecProfiles>
+ <MediaProfiles />
+</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml b/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml
new file mode 100644
index 000000000..77648147f
--- /dev/null
+++ b/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0"?>
+<Profile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <Name>Samsung Smart TV</Name>
+ <Identification>
+ <ModelUrl>samsung.com</ModelUrl>
+ <Headers />
+ </Identification>
+ <FriendlyName>Media Browser</FriendlyName>
+ <Manufacturer>Media Browser</Manufacturer>
+ <ManufacturerUrl>http://mediabrowser3.com/</ManufacturerUrl>
+ <ModelName>Media Browser</ModelName>
+ <ModelDescription>Media Browser</ModelDescription>
+ <ModelNumber>Media Browser</ModelNumber>
+ <ModelUrl>http://mediabrowser3.com/</ModelUrl>
+ <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
+ <EnableAlbumArtInDidl>true</EnableAlbumArtInDidl>
+ <SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
+ <ProtocolInfo>DLNA</ProtocolInfo>
+ <TimelineOffsetSeconds>0</TimelineOffsetSeconds>
+ <RequiresPlainVideoItems>false</RequiresPlainVideoItems>
+ <RequiresPlainFolders>false</RequiresPlainFolders>
+ <DirectPlayProfiles>
+ <DirectPlayProfile container="asf" audioCodec="mp3,ac3,wmav2,wmapro,wmavoice" videoCodec="h264,mpeg4,mjpeg" type="Video" />
+ <DirectPlayProfile container="avi" audioCodec="mp3,ac3,dca" videoCodec="h264,mpeg4,mjpeg" type="Video" />
+ <DirectPlayProfile container="mkv" audioCodec="mp3,ac3,dca,aac" videoCodec="h264,mpeg4,mjpeg4" type="Video" />
+ <DirectPlayProfile container="mp4" audioCodec="mp3,aac" videoCodec="h264,mpeg4" type="Video" />
+ <DirectPlayProfile container="3gpp" audioCodec="aac,he-aac" videoCodec="h264,mpeg4" type="Video" />
+ <DirectPlayProfile container="mpg,mpeg" audioCodec="ac3,mp2,mp3,aac" videoCodec="mpeg1video,mpeg2video,h264" type="Video" />
+ <DirectPlayProfile container="vro,vob" audioCodec="ac3,mp2,mp3" videoCodec="mpeg1video,mpeg2video" type="Video" />
+ <DirectPlayProfile container="ts" audioCodec="ac3,aac,mp3,eac3" videoCodec="mpeg2video,h264,vc1" type="Video" />
+ <DirectPlayProfile container="asf" audioCodec="wmav2,wmavoice" videoCodec="wmv2,wmv3" type="Video" />
+ <DirectPlayProfile container="mp3" audioCodec="mp3" type="Audio" />
+ <DirectPlayProfile container="jpeg" type="Photo" />
+ </DirectPlayProfiles>
+ <TranscodingProfiles>
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ </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="VideoCodec" 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="30720000" isRequired="true" />
+ </Conditions>
+ </CodecProfile>
+ <CodecProfile type="VideoCodec" codec="mpeg4">
+ <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="8192000" isRequired="true" />
+ </Conditions>
+ </CodecProfile>
+ <CodecProfile type="VideoCodec" 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="37500000" isRequired="true" />
+ <ProfileCondition condition="LessThanEqual" property="VideoLevel" value="41" isRequired="true" />
+ </Conditions>
+ </CodecProfile>
+ <CodecProfile type="VideoCodec" codec="wmv2,wmv3,vc1">
+ <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="25600000" isRequired="true" />
+ </Conditions>
+ </CodecProfile>
+ <CodecProfile type="VideoAudioCodec" codec="ac3,wmav2,dca,aac,mp3">
+ <Conditions>
+ <ProfileCondition condition="LessThanEqual" property="AudioChannels" value="6" isRequired="true" />
+ </Conditions>
+ </CodecProfile>
+ </CodecProfiles>
+ <MediaProfiles>
+ <MediaProfile container="avi" type="Video" mimeType="video/x-msvideo">
+ <Conditions />
+ </MediaProfile>
+ <MediaProfile container="mkv" type="Video" mimeType="video/x-mkv">
+ <Conditions />
+ </MediaProfile>
+ </MediaProfiles>
+</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml
new file mode 100644
index 000000000..942812295
--- /dev/null
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0"?>
+<Profile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <Name>Sony Blu-ray Player 2013</Name>
+ <Identification>
+ <FriendlyName>Blu-ray Disc Player</FriendlyName>
+ <ModelNumber>BDP-2013</ModelNumber>
+ <Manufacturer>Sony</Manufacturer>
+ <Headers />
+ </Identification>
+ <FriendlyName>Media Browser</FriendlyName>
+ <Manufacturer>Microsoft Corporation</Manufacturer>
+ <ManufacturerUrl>http://mediabrowser3.com/</ManufacturerUrl>
+ <ModelName>Windows Media Player Sharing</ModelName>
+ <ModelDescription>Media Browser</ModelDescription>
+ <ModelNumber>3.0</ModelNumber>
+ <ModelUrl>http://mediabrowser3.com/</ModelUrl>
+ <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
+ <EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
+ <SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
+ <ProtocolInfo>http-get:*:video/divx:DLNA.ORG_PN=MATROSKA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_PAL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_NTSC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_EU;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_NA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_KO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMABASE;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMAFULL;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_SD_AAC_MULT5;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/mpeg:DLNA.ORG_PN=MP3;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/L16;rate=44100;channels=1:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/L16;rate=44100;channels=2:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/L16;rate=48000;channels=1:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/L16;rate=48000;channels=2:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/mp4:DLNA.ORG_PN=AAC_ISO;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/mp4:DLNA.ORG_PN=AAC_ISO_320;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/vnd.dlna.adts:DLNA.ORG_PN=AAC_ADTS;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/vnd.dlna.adts:DLNA.ORG_PN=AAC_ADTS_320;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/flac:DLNA.ORG_PN=FLAC;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/ogg:DLNA.ORG_PN=OGG;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:*:image/jpeg:DLNA.ORG_PN=JPEG_MED;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_LRG;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_TN;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/png:DLNA.ORG_PN=PNG_LRG;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/png:DLNA.ORG_PN=PNG_TN;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/gif:DLNA.ORG_PN=GIF_LRG;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG1;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_EU_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_EU_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_NA_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_NA_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_KO_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_KO_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_JP_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-msvideo:DLNA.ORG_PN=AVI;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-flv:DLNA.ORG_PN=FLV;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-ms-dvr:DLNA.ORG_PN=DVR_MS;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/wtv:DLNA.ORG_PN=WTV;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/ogg:DLNA.ORG_PN=OGV;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/vnd.rn-realvideo:DLNA.ORG_PN=REAL_VIDEO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_BASE;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_FULL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVHIGH_FULL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_PRO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVHIGH_PRO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L1_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L2_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L3_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/3gpp:DLNA.ORG_PN=MPEG4_P2_3GPP_SP_L0B_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/3gpp:DLNA.ORG_PN=MPEG4_P2_3GPP_SP_L0B_AMR;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/3gpp:DLNA.ORG_PN=MPEG4_H263_3GPP_P0_L10_AMR;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/3gpp:DLNA.ORG_PN=MPEG4_H263_MP4_P0_L10_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000</ProtocolInfo>
+ <TimelineOffsetSeconds>0</TimelineOffsetSeconds>
+ <RequiresPlainVideoItems>false</RequiresPlainVideoItems>
+ <RequiresPlainFolders>false</RequiresPlainFolders>
+ <DirectPlayProfiles>
+ <DirectPlayProfile container="ts" audioCodec="ac3,aac,mp3,pcm" videoCodec="mpeg1video,mpeg2video,h264" type="Video" />
+ <DirectPlayProfile container="mpeg" audioCodec="ac3,mp3,mp2,pcm" videoCodec="mpeg1video,mpeg2video" type="Video" />
+ <DirectPlayProfile container="mp4" audioCodec="ac3,aac,pcm,mp3" videoCodec="mpeg4,h264" type="Video" />
+ <DirectPlayProfile container="avi" audioCodec="ac3,aac,mp3,pcm" videoCodec="mpeg4,h264" type="Video" />
+ <DirectPlayProfile container="mkv" audioCodec="ac3,dca,aac,mp3,pcm" videoCodec="mpeg4,h264" type="Video" />
+ <DirectPlayProfile container="mp3" audioCodec="mp3" type="Audio" />
+ <DirectPlayProfile container="mp4" audioCodec="aac" type="Audio" />
+ <DirectPlayProfile container="asf" audioCodec="wmav2,wmapro,wmavoice" type="Audio" />
+ <DirectPlayProfile container="jpeg" type="Photo" />
+ </DirectPlayProfiles>
+ <TranscodingProfiles>
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ </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="VideoCodec" 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="false" />
+ </Conditions>
+ </CodecProfile>
+ <CodecProfile type="VideoAudioCodec" codec="ac3">
+ <Conditions>
+ <ProfileCondition condition="LessThanEqual" property="AudioChannels" value="6" isRequired="false" />
+ </Conditions>
+ </CodecProfile>
+ </CodecProfiles>
+ <MediaProfiles />
+</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml
new file mode 100644
index 000000000..519304576
--- /dev/null
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0"?>
+<Profile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <Name>Sony Blu-ray Player</Name>
+ <Identification>
+ <FriendlyName>Blu-ray Disc Player</FriendlyName>
+ <Manufacturer>Sony</Manufacturer>
+ <Headers>
+ <HttpHeaderInfo name="X-AV-Client-Info" value="(Blu-ray Disc Player|Home Theater System|Home Theatre System|Media Player)" match="Regex" />
+ <HttpHeaderInfo name="X-AV-Physical-Unit-Info" value="(Blu-ray Disc Player|Home Theater System|Home Theatre System|Media Player)" match="Regex" />
+ </Headers>
+ </Identification>
+ <FriendlyName>Media Browser</FriendlyName>
+ <Manufacturer>Microsoft Corporation</Manufacturer>
+ <ManufacturerUrl>http://mediabrowser3.com/</ManufacturerUrl>
+ <ModelName>Windows Media Player Sharing</ModelName>
+ <ModelDescription>Media Browser</ModelDescription>
+ <ModelNumber>3.0</ModelNumber>
+ <ModelUrl>http://mediabrowser3.com/</ModelUrl>
+ <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
+ <EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
+ <SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
+ <ProtocolInfo>http-get:*:video/divx:DLNA.ORG_PN=MATROSKA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_PAL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_NTSC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_EU;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_NA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_KO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMABASE;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMAFULL;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_SD_AAC_MULT5;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/mpeg:DLNA.ORG_PN=MP3;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/L16;rate=44100;channels=1:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/L16;rate=44100;channels=2:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/L16;rate=48000;channels=1:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/L16;rate=48000;channels=2:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/mp4:DLNA.ORG_PN=AAC_ISO;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/mp4:DLNA.ORG_PN=AAC_ISO_320;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/vnd.dlna.adts:DLNA.ORG_PN=AAC_ADTS;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/vnd.dlna.adts:DLNA.ORG_PN=AAC_ADTS_320;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/flac:DLNA.ORG_PN=FLAC;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:audio/ogg:DLNA.ORG_PN=OGG;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:*:image/jpeg:DLNA.ORG_PN=JPEG_MED;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_LRG;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_TN;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/png:DLNA.ORG_PN=PNG_LRG;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/png:DLNA.ORG_PN=PNG_TN;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/gif:DLNA.ORG_PN=GIF_LRG;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG1;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_EU_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_EU_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_NA_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_NA_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_KO_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_KO_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_JP_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-msvideo:DLNA.ORG_PN=AVI;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-flv:DLNA.ORG_PN=FLV;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-ms-dvr:DLNA.ORG_PN=DVR_MS;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/wtv:DLNA.ORG_PN=WTV;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/ogg:DLNA.ORG_PN=OGV;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/vnd.rn-realvideo:DLNA.ORG_PN=REAL_VIDEO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_BASE;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_FULL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVHIGH_FULL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_PRO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVHIGH_PRO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L1_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L2_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L3_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/3gpp:DLNA.ORG_PN=MPEG4_P2_3GPP_SP_L0B_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/3gpp:DLNA.ORG_PN=MPEG4_P2_3GPP_SP_L0B_AMR;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/3gpp:DLNA.ORG_PN=MPEG4_H263_3GPP_P0_L10_AMR;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:video/3gpp:DLNA.ORG_PN=MPEG4_H263_MP4_P0_L10_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000</ProtocolInfo>
+ <TimelineOffsetSeconds>0</TimelineOffsetSeconds>
+ <RequiresPlainVideoItems>false</RequiresPlainVideoItems>
+ <RequiresPlainFolders>false</RequiresPlainFolders>
+ <DirectPlayProfiles>
+ <DirectPlayProfile container="ts" audioCodec="ac3,aac,mp3,pcm" videoCodec="mpeg1video,mpeg2video,h264" type="Video" />
+ <DirectPlayProfile container="mpeg" audioCodec="ac3,mp3,pcm" videoCodec="mpeg1video,mpeg2video" type="Video" />
+ <DirectPlayProfile container="avi,mp4" audioCodec="ac3,aac,mp3,pcm" videoCodec="mpeg4,h264" type="Video" />
+ <DirectPlayProfile container="mp3" audioCodec="mp3" type="Audio" />
+ <DirectPlayProfile container="asf" audioCodec="wmav2,wmapro,wmavoice" type="Audio" />
+ <DirectPlayProfile container="jpeg" type="Photo" />
+ </DirectPlayProfiles>
+ <TranscodingProfiles>
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ <TranscodingProfile container="ts" type="Video" videoCodec="mpeg2video" audioCodec="ac3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ </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="VideoCodec" 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="false" />
+ <ProfileCondition condition="LessThanEqual" property="VideoLevel" value="41" isRequired="false" />
+ <ProfileCondition condition="LessThanEqual" property="VideoBitrate" value="15360000" isRequired="false" />
+ </Conditions>
+ </CodecProfile>
+ <CodecProfile type="VideoAudioCodec" codec="ac3">
+ <Conditions>
+ <ProfileCondition condition="LessThanEqual" property="AudioChannels" value="6" isRequired="false" />
+ </Conditions>
+ </CodecProfile>
+ <CodecProfile type="VideoAudioCodec" codec="aac">
+ <Conditions>
+ <ProfileCondition condition="LessThanEqual" property="AudioChannels" value="2" isRequired="false" />
+ </Conditions>
+ </CodecProfile>
+ </CodecProfiles>
+ <MediaProfiles>
+ <MediaProfile container="ts" audioCodec="ac3,aac,mp3" videoCodec="h264,mpeg4,vc1" type="Video" orgPn="MPEG_TS_SD_EU,MPEG_TS_SD_NA,MPEG_TS_SD_KO" mimeType="video/vnd.dlna.mpeg-tts">
+ <Conditions />
+ </MediaProfile>
+ <MediaProfile container="avi" type="Video" mimeType="video/mpeg">
+ <Conditions />
+ </MediaProfile>
+ <MediaProfile container="mkv" type="Video" mimeType="video/vnd.dlna.mpeg-tts">
+ <Conditions />
+ </MediaProfile>
+ <MediaProfile container="ts" type="Video" mimeType="video/vnd.dlna.mpeg-tts">
+ <Conditions />
+ </MediaProfile>
+ <MediaProfile container="mp4" type="Video" mimeType="video/mpeg">
+ <Conditions />
+ </MediaProfile>
+ <MediaProfile container="mpeg" type="Video" mimeType="video/mpeg">
+ <Conditions />
+ </MediaProfile>
+ <MediaProfile container="mp3" type="Audio" mimeType="audio/mpeg">
+ <Conditions />
+ </MediaProfile>
+ </MediaProfiles>
+</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml
new file mode 100644
index 000000000..d240e1d34
--- /dev/null
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml
@@ -0,0 +1,100 @@
+<?xml version="1.0"?>
+<Profile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <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>
+ <FriendlyName>Media Browser</FriendlyName>
+ <Manufacturer>Microsoft Corporation</Manufacturer>
+ <ManufacturerUrl>http://www.microsoft.com/</ManufacturerUrl>
+ <ModelName>Windows Media Player Sharing</ModelName>
+ <ModelDescription>Media Browser</ModelDescription>
+ <ModelNumber>3.0</ModelNumber>
+ <ModelUrl>http://www.microsoft.com/</ModelUrl>
+ <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
+ <EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
+ <SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
+ <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>
+ <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">
+ <Settings />
+ </TranscodingProfile>
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3,aac" estimateContentLength="false" enableMpegtsM2TsMode="true" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ </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="VideoCodec">
+ <Conditions>
+ <ProfileCondition condition="LessThanEqual" property="Width" value="1920" isRequired="true" />
+ <ProfileCondition condition="LessThanEqual" property="Height" value="1080" isRequired="true" />
+ </Conditions>
+ </CodecProfile>
+ <CodecProfile type="VideoCodec" codec="h264">
+ <Conditions>
+ <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>
+ </CodecProfile>
+ <CodecProfile type="VideoCodec" codec="mpeg2video">
+ <Conditions>
+ <ProfileCondition condition="LessThanEqual" property="VideoFramerate" value="30" isRequired="true" />
+ <ProfileCondition condition="LessThanEqual" property="VideoBitrate" value="20000000" isRequired="true" />
+ </Conditions>
+ </CodecProfile>
+ <CodecProfile type="VideoAudioCodec" codec="ac3">
+ <Conditions>
+ <ProfileCondition condition="LessThanEqual" property="AudioChannels" value="6" isRequired="true" />
+ </Conditions>
+ </CodecProfile>
+ <CodecProfile type="VideoAudioCodec" codec="aac">
+ <Conditions>
+ <ProfileCondition condition="LessThanEqual" property="AudioChannels" value="2" isRequired="true" />
+ <ProfileCondition condition="NotEquals" property="AudioProfile" value="he-aac" isRequired="true" />
+ </Conditions>
+ </CodecProfile>
+ </CodecProfiles>
+ <MediaProfiles>
+ <MediaProfile 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 />
+ </MediaProfile>
+ <MediaProfile 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 />
+ </MediaProfile>
+ <MediaProfile 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 />
+ </MediaProfile>
+ <MediaProfile 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 />
+ </MediaProfile>
+ <MediaProfile container="mpeg" videoCodec="mpeg1video,mpeg2video" type="Video" orgPn="MPEG_PS_NTSC,MPEG_PS_PAL" mimeType="video/mpeg">
+ <Conditions />
+ </MediaProfile>
+ </MediaProfiles>
+</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml
new file mode 100644
index 000000000..2372aa5ad
--- /dev/null
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml
@@ -0,0 +1,103 @@
+<?xml version="1.0"?>
+<Profile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <Name>Sony Bravia (2011)</Name>
+ <Identification>
+ <FriendlyName>KDL-\d{2}([A-Z]X\d2\d|CX400).*</FriendlyName>
+ <Manufacturer>Sony</Manufacturer>
+ <Headers>
+ <HttpHeaderInfo name="X-AV-Client-Info" value=".*KDL-\d{2}([A-Z]X\d2\d|CX400).*" match="Regex" />
+ </Headers>
+ </Identification>
+ <FriendlyName>Media Browser</FriendlyName>
+ <Manufacturer>Microsoft Corporation</Manufacturer>
+ <ManufacturerUrl>http://www.microsoft.com/</ManufacturerUrl>
+ <ModelName>Windows Media Player Sharing</ModelName>
+ <ModelDescription>Media Browser</ModelDescription>
+ <ModelNumber>3.0</ModelNumber>
+ <ModelUrl>http://www.microsoft.com/</ModelUrl>
+ <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
+ <EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
+ <SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
+ <SonyAggregationFlags>10</SonyAggregationFlags>
+ <ProtocolInfo>DLNA</ProtocolInfo>
+ <TimelineOffsetSeconds>0</TimelineOffsetSeconds>
+ <RequiresPlainVideoItems>false</RequiresPlainVideoItems>
+ <RequiresPlainFolders>false</RequiresPlainFolders>
+ <DirectPlayProfiles>
+ <DirectPlayProfile container="ts" audioCodec="ac3,aac,mp3" videoCodec="h264" type="Video" />
+ <DirectPlayProfile container="ts" audioCodec="mp3,mp2" videoCodec="mpeg2video" type="Video" />
+ <DirectPlayProfile container="mp4" audioCodec="ac3,aac,mp3,mp2" videoCodec="h264,mpeg4" type="Video" />
+ <DirectPlayProfile container="mpeg" audioCodec="mp3,mp2" videoCodec="mpeg2video,mpeg1video" type="Video" />
+ <DirectPlayProfile container="asf" audioCodec="wmav2,wmapro,wmavoice" videoCodec="wmv2,wmv3,vc1" type="Video" />
+ <DirectPlayProfile container="mp3" audioCodec="mp3" type="Audio" />
+ <DirectPlayProfile container="asf" audioCodec="wmav2,wmapro,wmavoice" type="Audio" />
+ </DirectPlayProfiles>
+ <TranscodingProfiles>
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3,aac" estimateContentLength="false" enableMpegtsM2TsMode="true" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ </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="VideoCodec">
+ <Conditions>
+ <ProfileCondition condition="LessThanEqual" property="Width" value="1920" isRequired="true" />
+ <ProfileCondition condition="LessThanEqual" property="Height" value="1080" isRequired="true" />
+ </Conditions>
+ </CodecProfile>
+ <CodecProfile type="VideoCodec" codec="h264">
+ <Conditions>
+ <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>
+ </CodecProfile>
+ <CodecProfile type="VideoCodec" codec="mpeg2video">
+ <Conditions>
+ <ProfileCondition condition="LessThanEqual" property="VideoFramerate" value="30" isRequired="true" />
+ <ProfileCondition condition="LessThanEqual" property="VideoBitrate" value="20000000" isRequired="true" />
+ </Conditions>
+ </CodecProfile>
+ <CodecProfile type="VideoAudioCodec" codec="ac3">
+ <Conditions>
+ <ProfileCondition condition="LessThanEqual" property="AudioChannels" value="6" isRequired="true" />
+ </Conditions>
+ </CodecProfile>
+ <CodecProfile type="VideoAudioCodec" codec="aac">
+ <Conditions>
+ <ProfileCondition condition="LessThanEqual" property="AudioChannels" value="2" isRequired="true" />
+ <ProfileCondition condition="NotEquals" property="AudioProfile" value="he-aac" isRequired="true" />
+ </Conditions>
+ </CodecProfile>
+ </CodecProfiles>
+ <MediaProfiles>
+ <MediaProfile 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 />
+ </MediaProfile>
+ <MediaProfile 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 />
+ </MediaProfile>
+ <MediaProfile 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 />
+ </MediaProfile>
+ <MediaProfile 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 />
+ </MediaProfile>
+ <MediaProfile container="mpeg" videoCodec="mpeg1video,mpeg2video" type="Video" orgPn="MPEG_PS_NTSC,MPEG_PS_PAL" mimeType="video/mpeg">
+ <Conditions />
+ </MediaProfile>
+ </MediaProfiles>
+</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml
new file mode 100644
index 000000000..7edf09134
--- /dev/null
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml
@@ -0,0 +1,86 @@
+<?xml version="1.0"?>
+<Profile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <Name>Sony Bravia (2012)</Name>
+ <Identification>
+ <FriendlyName>KDL-\d{2}[A-Z]X\d5(\d|G).*</FriendlyName>
+ <Manufacturer>Sony</Manufacturer>
+ <Headers>
+ <HttpHeaderInfo name="X-AV-Client-Info" value=".*KDL-\d{2}[A-Z]X\d5(\d|G).*" match="Regex" />
+ </Headers>
+ </Identification>
+ <FriendlyName>Media Browser</FriendlyName>
+ <Manufacturer>Microsoft Corporation</Manufacturer>
+ <ManufacturerUrl>http://www.microsoft.com/</ManufacturerUrl>
+ <ModelName>Windows Media Player Sharing</ModelName>
+ <ModelDescription>Media Browser</ModelDescription>
+ <ModelNumber>3.0</ModelNumber>
+ <ModelUrl>http://www.microsoft.com/</ModelUrl>
+ <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
+ <EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
+ <SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
+ <SonyAggregationFlags>10</SonyAggregationFlags>
+ <ProtocolInfo>DLNA</ProtocolInfo>
+ <TimelineOffsetSeconds>0</TimelineOffsetSeconds>
+ <RequiresPlainVideoItems>false</RequiresPlainVideoItems>
+ <RequiresPlainFolders>false</RequiresPlainFolders>
+ <DirectPlayProfiles>
+ <DirectPlayProfile container="ts" audioCodec="ac3,aac,mp3" videoCodec="h264" type="Video" />
+ <DirectPlayProfile container="ts" audioCodec="mp3,mp2" videoCodec="mpeg2video" type="Video" />
+ <DirectPlayProfile container="mp4" audioCodec="ac3,aac,mp3,mp2" videoCodec="h264,mpeg4" type="Video" />
+ <DirectPlayProfile container="avi" audioCodec="ac3,mp3" videoCodec="mpeg4" type="Video" />
+ <DirectPlayProfile container="mpeg" audioCodec="mp3,mp2" videoCodec="mpeg2video,mpeg1video" type="Video" />
+ <DirectPlayProfile container="asf" audioCodec="wmav2,wmapro,wmavoice" videoCodec="wmv2,wmv3,vc1" type="Video" />
+ <DirectPlayProfile container="mp3" audioCodec="mp3" type="Audio" />
+ <DirectPlayProfile container="asf" audioCodec="wmav2,wmapro,wmavoice" type="Audio" />
+ <DirectPlayProfile container="jpeg" type="Photo" />
+ </DirectPlayProfiles>
+ <TranscodingProfiles>
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3,aac" estimateContentLength="false" enableMpegtsM2TsMode="true" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ </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="VideoCodec">
+ <Conditions>
+ <ProfileCondition condition="LessThanEqual" property="Width" value="1920" isRequired="true" />
+ <ProfileCondition condition="LessThanEqual" property="Height" value="1080" isRequired="true" />
+ </Conditions>
+ </CodecProfile>
+ <CodecProfile type="VideoAudioCodec" codec="ac3">
+ <Conditions>
+ <ProfileCondition condition="LessThanEqual" property="AudioChannels" value="6" isRequired="true" />
+ </Conditions>
+ </CodecProfile>
+ </CodecProfiles>
+ <MediaProfiles>
+ <MediaProfile 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 />
+ </MediaProfile>
+ <MediaProfile 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 />
+ </MediaProfile>
+ <MediaProfile 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 />
+ </MediaProfile>
+ <MediaProfile 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 />
+ </MediaProfile>
+ <MediaProfile container="mpeg" videoCodec="mpeg1video,mpeg2video" type="Video" orgPn="MPEG_PS_NTSC,MPEG_PS_PAL" mimeType="video/mpeg">
+ <Conditions />
+ </MediaProfile>
+ </MediaProfiles>
+</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml
new file mode 100644
index 000000000..ec624cd8e
--- /dev/null
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml
@@ -0,0 +1,86 @@
+<?xml version="1.0"?>
+<Profile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <Name>Sony Bravia (2013)</Name>
+ <Identification>
+ <FriendlyName>KDL-\d{2}[WR][5689]\d{2}A.*</FriendlyName>
+ <Manufacturer>Sony</Manufacturer>
+ <Headers>
+ <HttpHeaderInfo name="X-AV-Client-Info" value=".*KDL-\d{2}[WR][5689]\d{2}A.*" match="Regex" />
+ </Headers>
+ </Identification>
+ <FriendlyName>Media Browser</FriendlyName>
+ <Manufacturer>Microsoft Corporation</Manufacturer>
+ <ManufacturerUrl>http://www.microsoft.com/</ManufacturerUrl>
+ <ModelName>Windows Media Player Sharing</ModelName>
+ <ModelDescription>Media Browser</ModelDescription>
+ <ModelNumber>3.0</ModelNumber>
+ <ModelUrl>http://www.microsoft.com/</ModelUrl>
+ <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
+ <EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
+ <SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
+ <SonyAggregationFlags>10</SonyAggregationFlags>
+ <ProtocolInfo>DLNA</ProtocolInfo>
+ <TimelineOffsetSeconds>0</TimelineOffsetSeconds>
+ <RequiresPlainVideoItems>false</RequiresPlainVideoItems>
+ <RequiresPlainFolders>false</RequiresPlainFolders>
+ <DirectPlayProfiles>
+ <DirectPlayProfile container="ts" audioCodec="ac3,eac3,aac,mp3" videoCodec="h264" type="Video" />
+ <DirectPlayProfile container="ts" audioCodec="mp3,mp2" videoCodec="mpeg2video" type="Video" />
+ <DirectPlayProfile container="mp4" audioCodec="ac3,eac3,aac,mp3,mp2" videoCodec="h264,mpeg4" type="Video" />
+ <DirectPlayProfile container="mov" audioCodec="ac3,eac3,aac,mp3,mp2" videoCodec="h264,mpeg4,mjpeg" type="Video" />
+ <DirectPlayProfile container="mkv" audioCodec="ac3,eac3,aac,mp3,mp2,pcm,vorbis" videoCodec="h264,mpeg4,vp8" type="Video" />
+ <DirectPlayProfile container="avi" audioCodec="ac3,eac3,mp3" videoCodec="mpeg4" type="Video" />
+ <DirectPlayProfile container="avi" audioCodec="pcm" videoCodec="mjpeg" type="Video" />
+ <DirectPlayProfile container="mpeg" audioCodec="mp3,mp2" videoCodec="mpeg2video,mpeg1video" type="Video" />
+ <DirectPlayProfile container="asf" audioCodec="wmav2,wmapro,wmavoice" videoCodec="wmv2,wmv3,vc1" type="Video" />
+ <DirectPlayProfile container="mp3" audioCodec="mp3" type="Audio" />
+ <DirectPlayProfile container="mp4" audioCodec="aac" type="Audio" />
+ <DirectPlayProfile container="wav" audioCodec="pcm" type="Audio" />
+ <DirectPlayProfile container="asf" audioCodec="wmav2,wmapro,wmavoice" type="Audio" />
+ <DirectPlayProfile container="jpeg" type="Photo" />
+ </DirectPlayProfiles>
+ <TranscodingProfiles>
+ <TranscodingProfile container="mp3" type="Audio" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="ac3,aac" estimateContentLength="false" enableMpegtsM2TsMode="true" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ </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="VideoCodec">
+ <Conditions>
+ <ProfileCondition condition="LessThanEqual" property="Width" value="1920" isRequired="true" />
+ <ProfileCondition condition="LessThanEqual" property="Height" value="1080" isRequired="true" />
+ </Conditions>
+ </CodecProfile>
+ </CodecProfiles>
+ <MediaProfiles>
+ <MediaProfile 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 />
+ </MediaProfile>
+ <MediaProfile 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 />
+ </MediaProfile>
+ <MediaProfile 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 />
+ </MediaProfile>
+ <MediaProfile 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 />
+ </MediaProfile>
+ <MediaProfile container="mpeg" videoCodec="mpeg1video,mpeg2video" type="Video" orgPn="MPEG_PS_NTSC,MPEG_PS_PAL" mimeType="video/mpeg">
+ <Conditions />
+ </MediaProfile>
+ </MediaProfiles>
+</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml b/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml
new file mode 100644
index 000000000..eeaf2d819
--- /dev/null
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml
@@ -0,0 +1,94 @@
+<?xml version="1.0"?>
+<Profile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <Name>Sony PlayStation 3</Name>
+ <Identification>
+ <FriendlyName>PLAYSTATION 3</FriendlyName>
+ <Headers>
+ <HttpHeaderInfo name="User-Agent" value="PLAYSTATION 3" match="Substring" />
+ <HttpHeaderInfo name="X-AV-Client-Info" value="PLAYSTATION 3" match="Substring" />
+ </Headers>
+ </Identification>
+ <FriendlyName>Media Browser</FriendlyName>
+ <Manufacturer>Media Browser</Manufacturer>
+ <ManufacturerUrl>http://mediabrowser3.com/</ManufacturerUrl>
+ <ModelName>Media Browser</ModelName>
+ <ModelDescription>Media Browser</ModelDescription>
+ <ModelNumber>Media Browser</ModelNumber>
+ <ModelUrl>http://mediabrowser3.com/</ModelUrl>
+ <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
+ <EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
+ <SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
+ <XDlnaDoc>DMS-1.50</XDlnaDoc>
+ <SonyAggregationFlags>10</SonyAggregationFlags>
+ <ProtocolInfo>DLNA</ProtocolInfo>
+ <TimelineOffsetSeconds>0</TimelineOffsetSeconds>
+ <RequiresPlainVideoItems>false</RequiresPlainVideoItems>
+ <RequiresPlainFolders>false</RequiresPlainFolders>
+ <DirectPlayProfiles>
+ <DirectPlayProfile container="mp3,wma" type="Audio" />
+ <DirectPlayProfile container="avi,mp4" type="Video" />
+ </DirectPlayProfiles>
+ <TranscodingProfiles>
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ </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="VideoCodec" 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="false" />
+ <ProfileCondition condition="LessThanEqual" property="VideoBitrate" value="15360000" isRequired="false" />
+ <ProfileCondition condition="LessThanEqual" property="VideoLevel" value="41" isRequired="false" />
+ </Conditions>
+ </CodecProfile>
+ <CodecProfile type="VideoAudioCodec" codec="ac3">
+ <Conditions>
+ <ProfileCondition condition="LessThanEqual" property="AudioChannels" value="6" isRequired="false" />
+ <ProfileCondition condition="LessThanEqual" property="AudioBitrate" value="640000" isRequired="false" />
+ </Conditions>
+ </CodecProfile>
+ <CodecProfile type="VideoAudioCodec" codec="wmapro">
+ <Conditions>
+ <ProfileCondition condition="LessThanEqual" property="AudioChannels" value="2" isRequired="true" />
+ </Conditions>
+ </CodecProfile>
+ <CodecProfile type="VideoAudioCodec" codec="aac">
+ <Conditions>
+ <ProfileCondition condition="NotEquals" property="AudioProfile" value="he-aac" isRequired="false" />
+ </Conditions>
+ </CodecProfile>
+ <CodecProfile type="VideoAudioCodec" codec="aac">
+ <Conditions>
+ <ProfileCondition condition="LessThanEqual" property="AudioChannels" value="2" isRequired="true" />
+ <ProfileCondition condition="NotEquals" property="AudioProfile" value="he-aac" isRequired="true" />
+ </Conditions>
+ </CodecProfile>
+ </CodecProfiles>
+ <MediaProfiles>
+ <MediaProfile container="mp4,mov" audioCodec="aac" type="Video" mimeType="video/mp4">
+ <Conditions />
+ </MediaProfile>
+ <MediaProfile container="avi" type="Video" orgPn="AVI" mimeType="video/divx">
+ <Conditions />
+ </MediaProfile>
+ <MediaProfile container="wav" type="Audio" mimeType="audio/wav">
+ <Conditions />
+ </MediaProfile>
+ </MediaProfiles>
+</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml b/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml
new file mode 100644
index 000000000..ffa39c26d
--- /dev/null
+++ b/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<Profile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <Name>WDTV Live</Name>
+ <Identification>
+ <ModelName>WD TV HD Live</ModelName>
+ <Headers>
+ <HttpHeaderInfo name="User-Agent" value="alphanetworks" match="Substring" />
+ <HttpHeaderInfo name="User-Agent" value="ALPHA Networks" match="Substring" />
+ </Headers>
+ </Identification>
+ <FriendlyName>Media Browser</FriendlyName>
+ <Manufacturer>Media Browser</Manufacturer>
+ <ManufacturerUrl>http://mediabrowser3.com/</ManufacturerUrl>
+ <ModelName>Media Browser</ModelName>
+ <ModelDescription>Media Browser</ModelDescription>
+ <ModelNumber>Media Browser</ModelNumber>
+ <ModelUrl>http://mediabrowser3.com/</ModelUrl>
+ <IgnoreTranscodeByteRangeRequests>true</IgnoreTranscodeByteRangeRequests>
+ <EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
+ <SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
+ <ProtocolInfo>DLNA</ProtocolInfo>
+ <TimelineOffsetSeconds>5</TimelineOffsetSeconds>
+ <RequiresPlainVideoItems>false</RequiresPlainVideoItems>
+ <RequiresPlainFolders>false</RequiresPlainFolders>
+ <DirectPlayProfiles>
+ <DirectPlayProfile container="avi" audioCodec="ac3,dca,mp2,mp3,pcm" videoCodec="mpeg1video,mpeg2video,mpeg4,h264,vc1" type="Video" />
+ <DirectPlayProfile container="mpeg" audioCodec="ac3,dca,mp2,mp3,pcm" videoCodec="mpeg1video,mpeg2video" type="Video" />
+ <DirectPlayProfile container="mkv" audioCodec="ac3,dca,aac,mp2,mp3,pcm" videoCodec="mpeg1video,mpeg2video,mpeg4,h264,vc1" type="Video" />
+ <DirectPlayProfile container="ts" audioCodec="ac3,dca,mp2,mp3" videoCodec="mpeg1video,mpeg2video,h264,vc1" type="Video" />
+ <DirectPlayProfile container="mp4,mov" audioCodec="ac3,aac,mp2,mp3" videoCodec="h264,mpeg4" type="Video" />
+ <DirectPlayProfile container="asf" audioCodec="wmav2,wmapro" videoCodec="vc1" type="Video" />
+ <DirectPlayProfile container="asf" audioCodec="mp2,ac3" videoCodec="mpeg2video" type="Video" />
+ <DirectPlayProfile container="mp3" audioCodec="mp2,mp3" type="Audio" />
+ <DirectPlayProfile container="mp4" audioCodec="mp4" type="Audio" />
+ <DirectPlayProfile container="flac" audioCodec="flac" type="Audio" />
+ <DirectPlayProfile container="asf" audioCodec="wmav2,wmapro,wmavoice" type="Audio" />
+ <DirectPlayProfile container="ogg" audioCodec="vorbis" type="Audio" />
+ <DirectPlayProfile container="jpeg,png,gif,bmp,tiff" type="Photo" />
+ </DirectPlayProfiles>
+ <TranscodingProfiles>
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings>
+ <TranscodingSetting name="VideoProfile" value="baseline" />
+ </Settings>
+ </TranscodingProfile>
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ </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="VideoCodec" 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="VideoLevel" value="41" isRequired="true" />
+ </Conditions>
+ </CodecProfile>
+ <CodecProfile type="VideoAudioCodec" codec="aac">
+ <Conditions>
+ <ProfileCondition condition="LessThanEqual" property="AudioChannels" value="2" isRequired="true" />
+ </Conditions>
+ </CodecProfile>
+ </CodecProfiles>
+ <MediaProfiles>
+ <MediaProfile container="ts" type="Video" orgPn="MPEG_TS_SD_NA">
+ <Conditions />
+ </MediaProfile>
+ </MediaProfiles>
+</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml b/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml
new file mode 100644
index 000000000..e7839ca77
--- /dev/null
+++ b/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0"?>
+<Profile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <Name>Xbox 360</Name>
+ <Identification>
+ <ModelName>Xbox 360</ModelName>
+ <Headers>
+ <HttpHeaderInfo name="User-Agent" value="Xbox" match="Substring" />
+ <HttpHeaderInfo name="User-Agent" value="Xenon" match="Substring" />
+ </Headers>
+ </Identification>
+ <FriendlyName>Media Browser</FriendlyName>
+ <Manufacturer>Microsoft Corporation</Manufacturer>
+ <ManufacturerUrl>http://www.microsoft.com/</ManufacturerUrl>
+ <ModelName>Windows Media Player Sharing</ModelName>
+ <ModelDescription>Media Browser</ModelDescription>
+ <ModelNumber>12.0</ModelNumber>
+ <ModelUrl>http://www.microsoft.com/</ModelUrl>
+ <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
+ <EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
+ <SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
+ <XDlnaDoc>DMS-1.50</XDlnaDoc>
+ <ProtocolInfo>DLNA</ProtocolInfo>
+ <TimelineOffsetSeconds>40</TimelineOffsetSeconds>
+ <RequiresPlainVideoItems>true</RequiresPlainVideoItems>
+ <RequiresPlainFolders>true</RequiresPlainFolders>
+ <DirectPlayProfiles>
+ <DirectPlayProfile container="avi" audioCodec="ac3,mp3" videoCodec="mpeg4" type="Video" />
+ <DirectPlayProfile container="avi" audioCodec="aac" videoCodec="h264" type="Video" />
+ <DirectPlayProfile container="mp4,mov" audioCodec="aac,ac3" videoCodec="h264,mpeg4" type="Video" />
+ <DirectPlayProfile container="asf" audioCodec="wmav2,wmapro" videoCodec="wmv2,wmv3,vc1" type="Video" />
+ <DirectPlayProfile container="asf" audioCodec="wmav2,wmapro,wmavoice" type="Audio" />
+ <DirectPlayProfile container="mp3" audioCodec="mp3" type="Audio" />
+ <DirectPlayProfile container="jpeg" type="Photo" />
+ </DirectPlayProfiles>
+ <TranscodingProfiles>
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ <TranscodingProfile container="asf" type="Video" videoCodec="wmv2" audioCodec="wmav2" estimateContentLength="true" enableMpegtsM2TsMode="false" transcodeSeekInfo="Bytes">
+ <Settings>
+ <TranscodingSetting name="VideoProfile" value="baseline" />
+ </Settings>
+ </TranscodingProfile>
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ </TranscodingProfiles>
+ <ContainerProfiles>
+ <ContainerProfile type="Video" container="mp4,mov">
+ <Conditions>
+ <ProfileCondition condition="LessThanEqual" property="Has64BitOffsets" value="false" isRequired="false" />
+ </Conditions>
+ </ContainerProfile>
+ <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="VideoCodec" codec="mpeg4">
+ <Conditions>
+ <ProfileCondition condition="LessThanEqual" property="Width" value="1280" isRequired="true" />
+ <ProfileCondition condition="LessThanEqual" property="Height" value="720" isRequired="true" />
+ <ProfileCondition condition="LessThanEqual" property="VideoFramerate" value="30" isRequired="false" />
+ <ProfileCondition condition="LessThanEqual" property="VideoBitrate" value="5120000" isRequired="false" />
+ </Conditions>
+ </CodecProfile>
+ <CodecProfile type="VideoCodec" 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="VideoLevel" value="41" isRequired="false" />
+ <ProfileCondition condition="LessThanEqual" property="VideoBitrate" value="10240000" isRequired="false" />
+ <ProfileCondition condition="LessThanEqual" property="VideoLevel" value="3" isRequired="false" />
+ </Conditions>
+ </CodecProfile>
+ <CodecProfile type="VideoCodec" codec="wmv2,wmv3,vc1">
+ <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="false" />
+ <ProfileCondition condition="LessThanEqual" property="VideoBitrate" value="15360000" isRequired="false" />
+ <ProfileCondition condition="LessThanEqual" property="VideoLevel" value="3" isRequired="false" />
+ </Conditions>
+ </CodecProfile>
+ <CodecProfile type="VideoAudioCodec" codec="ac3,wmav2,wmapro">
+ <Conditions>
+ <ProfileCondition condition="LessThanEqual" property="AudioChannels" value="6" isRequired="false" />
+ </Conditions>
+ </CodecProfile>
+ <CodecProfile type="VideoAudioCodec" codec="aac">
+ <Conditions>
+ <ProfileCondition condition="LessThanEqual" property="AudioChannels" value="2" isRequired="false" />
+ <ProfileCondition condition="Equals" property="AudioProfile" value="lc" isRequired="false" />
+ </Conditions>
+ </CodecProfile>
+ </CodecProfiles>
+ <MediaProfiles>
+ <MediaProfile container="avi" type="Video" mimeType="video/avi">
+ <Conditions />
+ </MediaProfile>
+ </MediaProfiles>
+</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml b/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml
new file mode 100644
index 000000000..5243218fb
--- /dev/null
+++ b/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0"?>
+<Profile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <Name>Xbox One</Name>
+ <Identification>
+ <FriendlyName>Xbox-SystemOS</FriendlyName>
+ <ModelName>Xbox One</ModelName>
+ <Headers />
+ </Identification>
+ <FriendlyName>Media Browser</FriendlyName>
+ <Manufacturer>Media Browser</Manufacturer>
+ <ManufacturerUrl>http://mediabrowser3.com/</ManufacturerUrl>
+ <ModelName>Media Browser</ModelName>
+ <ModelDescription>Media Browser</ModelDescription>
+ <ModelNumber>Media Browser</ModelNumber>
+ <ModelUrl>http://mediabrowser3.com/</ModelUrl>
+ <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
+ <EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
+ <SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
+ <ProtocolInfo>DLNA</ProtocolInfo>
+ <TimelineOffsetSeconds>0</TimelineOffsetSeconds>
+ <RequiresPlainVideoItems>false</RequiresPlainVideoItems>
+ <RequiresPlainFolders>false</RequiresPlainFolders>
+ <DirectPlayProfiles>
+ <DirectPlayProfile container="mp3,wma" type="Audio" />
+ </DirectPlayProfiles>
+ <TranscodingProfiles>
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ </TranscodingProfiles>
+ <ContainerProfiles />
+ <CodecProfiles>
+ <CodecProfile type="VideoCodec">
+ <Conditions>
+ <ProfileCondition condition="LessThanEqual" property="VideoLevel" value="3" isRequired="false" />
+ </Conditions>
+ </CodecProfile>
+ </CodecProfiles>
+ <MediaProfiles>
+ <MediaProfile container="avi" type="Video" mimeType="video/x-msvideo">
+ <Conditions />
+ </MediaProfile>
+ </MediaProfiles>
+</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml b/MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml
new file mode 100644
index 000000000..126d7fe73
--- /dev/null
+++ b/MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0"?>
+<Profile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <Name>foobar2000</Name>
+ <Identification>
+ <FriendlyName>foobar</FriendlyName>
+ <Headers>
+ <HttpHeaderInfo name="User-Agent" value="foobar" match="Substring" />
+ </Headers>
+ </Identification>
+ <FriendlyName>Media Browser</FriendlyName>
+ <Manufacturer>Media Browser</Manufacturer>
+ <ManufacturerUrl>http://mediabrowser3.com/</ManufacturerUrl>
+ <ModelName>Media Browser</ModelName>
+ <ModelDescription>Media Browser</ModelDescription>
+ <ModelNumber>Media Browser</ModelNumber>
+ <ModelUrl>http://mediabrowser3.com/</ModelUrl>
+ <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
+ <EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
+ <SupportedMediaTypes>Audio</SupportedMediaTypes>
+ <ProtocolInfo>DLNA</ProtocolInfo>
+ <TimelineOffsetSeconds>0</TimelineOffsetSeconds>
+ <RequiresPlainVideoItems>false</RequiresPlainVideoItems>
+ <RequiresPlainFolders>false</RequiresPlainFolders>
+ <DirectPlayProfiles>
+ <DirectPlayProfile container="mp3,wma" type="Audio" />
+ <DirectPlayProfile container="avi,mp4" type="Video" />
+ </DirectPlayProfiles>
+ <TranscodingProfiles>
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings />
+ </TranscodingProfile>
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto">
+ <Settings>
+ <TranscodingSetting name="VideoProfile" value="baseline" />
+ </Settings>
+ </TranscodingProfile>
+ </TranscodingProfiles>
+ <ContainerProfiles />
+ <CodecProfiles>
+ <CodecProfile type="VideoCodec">
+ <Conditions>
+ <ProfileCondition condition="LessThanEqual" property="VideoLevel" value="3" isRequired="false" />
+ </Conditions>
+ </CodecProfile>
+ </CodecProfiles>
+ <MediaProfiles />
+</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
index 960b0f635..9aefb4f1c 100644
--- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
+++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
@@ -101,6 +101,9 @@
<Compile Include="..\MediaBrowser.Model\Configuration\UserConfiguration.cs">
<Link>Configuration\UserConfiguration.cs</Link>
</Compile>
+ <Compile Include="..\MediaBrowser.Model\Dlna\DeviceProfileInfo.cs">
+ <Link>Dlna\DeviceProfileInfo.cs</Link>
+ </Compile>
<Compile Include="..\MediaBrowser.Model\Drawing\DrawingUtils.cs">
<Link>Drawing\DrawingUtils.cs</Link>
</Compile>
diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
index b010ad9c9..ce2a7600f 100644
--- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
+++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
@@ -88,6 +88,9 @@
<Compile Include="..\MediaBrowser.Model\Configuration\UserConfiguration.cs">
<Link>Configuration\UserConfiguration.cs</Link>
</Compile>
+ <Compile Include="..\MediaBrowser.Model\Dlna\DeviceProfileInfo.cs">
+ <Link>Dlna\DeviceProfileInfo.cs</Link>
+ </Compile>
<Compile Include="..\MediaBrowser.Model\Drawing\DrawingUtils.cs">
<Link>Drawing\DrawingUtils.cs</Link>
</Compile>
diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
index 1f304112f..d0caa3ad2 100644
--- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs
+++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
@@ -58,6 +58,12 @@ namespace MediaBrowser.Model.Configuration
public string ItemsByNamePath { get; set; }
/// <summary>
+ /// Gets or sets the metadata path.
+ /// </summary>
+ /// <value>The metadata path.</value>
+ public string MetadataPath { get; set; }
+
+ /// <summary>
/// Gets or sets the display name of the season zero.
/// </summary>
/// <value>The display name of the season zero.</value>
diff --git a/MediaBrowser.Model/Configuration/UserConfiguration.cs b/MediaBrowser.Model/Configuration/UserConfiguration.cs
index 2145860c7..10f984f88 100644
--- a/MediaBrowser.Model/Configuration/UserConfiguration.cs
+++ b/MediaBrowser.Model/Configuration/UserConfiguration.cs
@@ -52,6 +52,7 @@ namespace MediaBrowser.Model.Configuration
public bool EnableLiveTvAccess { get; set; }
public bool EnableMediaPlayback { get; set; }
+ public bool EnableContentDeletion { get; set; }
public string[] BlockedMediaFolders { get; set; }
@@ -63,8 +64,9 @@ namespace MediaBrowser.Model.Configuration
public UserConfiguration()
{
IsAdministrator = true;
- EnableRemoteControlOfOtherUsers = true;
+ EnableRemoteControlOfOtherUsers = true;
+ EnableContentDeletion = true;
EnableLiveTvManagement = true;
EnableMediaPlayback = true;
EnableLiveTvAccess = true;
diff --git a/MediaBrowser.Model/Dlna/DeviceProfileInfo.cs b/MediaBrowser.Model/Dlna/DeviceProfileInfo.cs
new file mode 100644
index 000000000..ceb27386c
--- /dev/null
+++ b/MediaBrowser.Model/Dlna/DeviceProfileInfo.cs
@@ -0,0 +1,30 @@
+
+namespace MediaBrowser.Model.Dlna
+{
+ public class DeviceProfileInfo
+ {
+ /// <summary>
+ /// Gets or sets the identifier.
+ /// </summary>
+ /// <value>The identifier.</value>
+ public string Id { get; set; }
+
+ /// <summary>
+ /// Gets or sets the name.
+ /// </summary>
+ /// <value>The name.</value>
+ public string Name { get; set; }
+
+ /// <summary>
+ /// Gets or sets the type.
+ /// </summary>
+ /// <value>The type.</value>
+ public DeviceProfileType Type { get; set; }
+ }
+
+ public enum DeviceProfileType
+ {
+ System = 0,
+ User = 1
+ }
+}
diff --git a/MediaBrowser.Model/Entities/MediaStream.cs b/MediaBrowser.Model/Entities/MediaStream.cs
index a8f751c10..b644661f4 100644
--- a/MediaBrowser.Model/Entities/MediaStream.cs
+++ b/MediaBrowser.Model/Entities/MediaStream.cs
@@ -124,6 +124,12 @@ namespace MediaBrowser.Model.Entities
public string Path { get; set; }
/// <summary>
+ /// Gets or sets the pixel format.
+ /// </summary>
+ /// <value>The pixel format.</value>
+ public string PixelFormat { get; set; }
+
+ /// <summary>
/// Gets or sets the level.
/// </summary>
/// <value>The level.</value>
diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj
index 5e9b97939..bf29b4bff 100644
--- a/MediaBrowser.Model/MediaBrowser.Model.csproj
+++ b/MediaBrowser.Model/MediaBrowser.Model.csproj
@@ -66,6 +66,7 @@
<Compile Include="Configuration\MetadataPlugin.cs" />
<Compile Include="Configuration\MetadataOptions.cs" />
<Compile Include="Configuration\ServerConfiguration.cs" />
+ <Compile Include="Dlna\DeviceProfileInfo.cs" />
<Compile Include="Drawing\ImageOutputFormat.cs" />
<Compile Include="Dto\BaseItemPerson.cs" />
<Compile Include="Dto\ChapterInfoDto.cs" />
diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs
index 044973064..75a9d9c36 100644
--- a/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs
+++ b/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs
@@ -50,12 +50,16 @@ namespace MediaBrowser.Providers.MediaInfo
return ItemUpdateType.MetadataImport;
}
+ private const string SchemaVersion = "1";
+
private async Task<InternalMediaInfoResult> GetMediaInfo(BaseItem item, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
var idString = item.Id.ToString("N");
- var cachePath = Path.Combine(_appPaths.CachePath, "ffprobe-audio", idString.Substring(0, 2), idString, "v" + _mediaEncoder.Version + item.DateModified.Ticks.ToString(_usCulture) + ".json");
+ var cachePath = Path.Combine(_appPaths.CachePath,
+ "ffprobe-audio",
+ idString.Substring(0, 2), idString, "v" + SchemaVersion + _mediaEncoder.Version + item.DateModified.Ticks.ToString(_usCulture) + ".json");
try
{
@@ -148,7 +152,7 @@ namespace MediaBrowser.Providers.MediaInfo
if (!string.IsNullOrWhiteSpace(composer))
{
- foreach (var person in Split(composer))
+ foreach (var person in Split(composer, false))
{
audio.AddPerson(new PersonInfo { Name = person, Type = PersonType.Composer });
}
@@ -221,12 +225,15 @@ namespace MediaBrowser.Providers.MediaInfo
/// Splits the specified val.
/// </summary>
/// <param name="val">The val.</param>
+ /// <param name="allowCommaDelimiter">if set to <c>true</c> [allow comma delimiter].</param>
/// <returns>System.String[][].</returns>
- private IEnumerable<string> Split(string val)
+ private IEnumerable<string> Split(string val, bool allowCommaDelimiter)
{
// Only use the comma as a delimeter if there are no slashes or pipes.
// We want to be careful not to split names that have commas in them
- var delimeter = _nameDelimiters.Any(i => val.IndexOf(i) != -1) ? _nameDelimiters : new[] { ',' };
+ var delimeter = !allowCommaDelimiter || _nameDelimiters.Any(i => val.IndexOf(i) != -1) ?
+ _nameDelimiters :
+ new[] { ',' };
return val.Split(delimeter, StringSplitOptions.RemoveEmptyEntries)
.Where(i => !string.IsNullOrWhiteSpace(i))
@@ -312,7 +319,7 @@ namespace MediaBrowser.Providers.MediaInfo
if (!string.IsNullOrEmpty(val))
{
// Sometimes the artist name is listed here, account for that
- var studios = Split(val).Where(i => !audio.HasArtist(i));
+ var studios = Split(val, true).Where(i => !audio.HasArtist(i));
foreach (var studio in studios)
{
@@ -334,7 +341,7 @@ namespace MediaBrowser.Providers.MediaInfo
{
audio.Genres.Clear();
- foreach (var genre in Split(val))
+ foreach (var genre in Split(val, true))
{
audio.AddGenre(genre);
}
diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs
index d516a8221..58fe7f66d 100644
--- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs
+++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs
@@ -107,6 +107,8 @@ namespace MediaBrowser.Providers.MediaInfo
return ItemUpdateType.MetadataImport;
}
+ private const string SchemaVersion = "1";
+
private async Task<InternalMediaInfoResult> GetMediaInfo(BaseItem item, IIsoMount isoMount, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
@@ -114,7 +116,9 @@ namespace MediaBrowser.Providers.MediaInfo
cancellationToken.ThrowIfCancellationRequested();
var idString = item.Id.ToString("N");
- var cachePath = Path.Combine(_appPaths.CachePath, "ffprobe-video", idString.Substring(0, 2), idString, "v" + _mediaEncoder.Version + item.DateModified.Ticks.ToString(_usCulture) + ".json");
+ var cachePath = Path.Combine(_appPaths.CachePath,
+ "ffprobe-video",
+ idString.Substring(0, 2), idString, "v" + SchemaVersion + _mediaEncoder.Version + item.DateModified.Ticks.ToString(_usCulture) + ".json");
try
{
@@ -161,7 +165,8 @@ namespace MediaBrowser.Providers.MediaInfo
var mediaStreams = MediaEncoderHelpers.GetMediaInfo(data).MediaStreams;
- var chapters = data.Chapters ?? new List<ChapterInfo>();
+ var mediaChapters = (data.Chapters ?? new MediaChapter[] { }).ToList();
+ var chapters = mediaChapters.Select(GetChapterInfo).ToList();
if (video.VideoType == VideoType.BluRay || (video.IsoType.HasValue && video.IsoType.Value == IsoType.BluRay))
{
@@ -200,6 +205,24 @@ namespace MediaBrowser.Providers.MediaInfo
await _itemRepo.SaveChapters(video.Id, chapters, cancellationToken).ConfigureAwait(false);
}
+ private ChapterInfo GetChapterInfo(MediaChapter chapter)
+ {
+ var info = new ChapterInfo();
+
+ if (chapter.tags != null)
+ {
+ string name;
+ if (chapter.tags.TryGetValue("title", out name))
+ {
+ info.Name = name;
+ }
+ }
+
+ info.StartPositionTicks = chapter.start/100;
+
+ return info;
+ }
+
private void FetchBdInfo(BaseItem item, List<ChapterInfo> chapters, List<MediaStream> mediaStreams, BlurayDiscInfo blurayInfo)
{
var video = (Video)item;
diff --git a/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs b/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs
index 415205cb1..cb3621fd1 100644
--- a/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs
+++ b/MediaBrowser.Server.Implementations/Configuration/ServerConfigurationManager.cs
@@ -26,6 +26,7 @@ namespace MediaBrowser.Server.Implementations.Configuration
{
UpdateItemsByNamePath();
UpdateTranscodingTempPath();
+ UpdateMetadataPath();
}
/// <summary>
@@ -77,6 +78,16 @@ namespace MediaBrowser.Server.Implementations.Configuration
}
/// <summary>
+ /// Updates the metadata path.
+ /// </summary>
+ private void UpdateMetadataPath()
+ {
+ ((ServerApplicationPaths)ApplicationPaths).InternalMetadataPath = string.IsNullOrEmpty(Configuration.MetadataPath) ?
+ null :
+ Configuration.MetadataPath;
+ }
+
+ /// <summary>
/// Updates the transcoding temporary path.
/// </summary>
private void UpdateTranscodingTempPath()
@@ -98,6 +109,7 @@ namespace MediaBrowser.Server.Implementations.Configuration
ValidateItemByNamePath(newConfig);
ValidateTranscodingTempPath(newConfig);
ValidatePathSubstitutions(newConfig);
+ ValidateMetadataPath(newConfig);
base.ReplaceConfiguration(newConfiguration);
}
@@ -166,5 +178,25 @@ namespace MediaBrowser.Server.Implementations.Configuration
}
}
}
+
+ /// <summary>
+ /// Validates the metadata path.
+ /// </summary>
+ /// <param name="newConfig">The new configuration.</param>
+ /// <exception cref="System.IO.DirectoryNotFoundException"></exception>
+ private void ValidateMetadataPath(ServerConfiguration newConfig)
+ {
+ var newPath = newConfig.MetadataPath;
+
+ if (!string.IsNullOrWhiteSpace(newPath)
+ && !string.Equals(Configuration.MetadataPath ?? string.Empty, newPath))
+ {
+ // Validate
+ if (!Directory.Exists(newPath))
+ {
+ throw new DirectoryNotFoundException(string.Format("{0} does not exist.", newPath));
+ }
+ }
+ }
}
}
diff --git a/MediaBrowser.Server.Implementations/Library/UserManager.cs b/MediaBrowser.Server.Implementations/Library/UserManager.cs
index 06028d37e..2ee843f09 100644
--- a/MediaBrowser.Server.Implementations/Library/UserManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/UserManager.cs
@@ -260,6 +260,8 @@ namespace MediaBrowser.Server.Implementations.Library
public event EventHandler<GenericEventArgs<User>> UserCreated;
+ private readonly SemaphoreSlim _userListLock = new SemaphoreSlim(1, 1);
+
/// <summary>
/// Creates the user.
/// </summary>
@@ -279,19 +281,28 @@ namespace MediaBrowser.Server.Implementations.Library
throw new ArgumentException(string.Format("A user with the name '{0}' already exists.", name));
}
- var user = InstantiateNewUser(name);
+ await _userListLock.WaitAsync(CancellationToken.None).ConfigureAwait(false);
- var list = Users.ToList();
- list.Add(user);
- Users = list;
+ try
+ {
+ var user = InstantiateNewUser(name);
- user.DateLastSaved = DateTime.UtcNow;
+ var list = Users.ToList();
+ list.Add(user);
+ Users = list;
- await UserRepository.SaveUser(user, CancellationToken.None).ConfigureAwait(false);
+ user.DateLastSaved = DateTime.UtcNow;
- EventHelper.QueueEventIfNotNull(UserCreated, this, new GenericEventArgs<User> { Argument = user }, _logger);
+ await UserRepository.SaveUser(user, CancellationToken.None).ConfigureAwait(false);
- return user;
+ EventHelper.QueueEventIfNotNull(UserCreated, this, new GenericEventArgs<User> { Argument = user }, _logger);
+
+ return user;
+ }
+ finally
+ {
+ _userListLock.Release();
+ }
}
/// <summary>
@@ -325,23 +336,32 @@ namespace MediaBrowser.Server.Implementations.Library
throw new ArgumentException(string.Format("The user '{0}' cannot be deleted because there must be at least one admin user in the system.", user.Name));
}
- await UserRepository.DeleteUser(user, CancellationToken.None).ConfigureAwait(false);
-
- var path = user.ConfigurationFilePath;
+ await _userListLock.WaitAsync(CancellationToken.None).ConfigureAwait(false);
try
{
- File.Delete(path);
+ await UserRepository.DeleteUser(user, CancellationToken.None).ConfigureAwait(false);
+
+ var path = user.ConfigurationFilePath;
+
+ try
+ {
+ File.Delete(path);
+ }
+ catch (IOException ex)
+ {
+ _logger.ErrorException("Error deleting file {0}", ex, path);
+ }
+
+ // Force this to be lazy loaded again
+ Users = await LoadUsers().ConfigureAwait(false);
+
+ OnUserDeleted(user);
}
- catch (IOException ex)
+ finally
{
- _logger.ErrorException("Error deleting file {0}", ex, path);
+ _userListLock.Release();
}
-
- // Force this to be lazy loaded again
- Users = await LoadUsers().ConfigureAwait(false);
-
- OnUserDeleted(user);
}
/// <summary>
diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
index 6a4c3930a..db8786d62 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -1498,8 +1498,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv
{
var programs = _programs.ToList();
- var startDate = programs.Select(i => i.Value.StartDate).Min();
- var endDate = programs.Select(i => i.Value.StartDate).Max();
+ var startDate = _programs.Count == 0 ? DateTime.MinValue :
+ programs.Select(i => i.Value.StartDate).Min();
+
+ var endDate = programs.Count == 0 ? DateTime.MinValue :
+ programs.Select(i => i.Value.StartDate).Max();
return new GuideInfo
{
diff --git a/MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs b/MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs
index fddba7662..c646d80bc 100644
--- a/MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs
+++ b/MediaBrowser.Server.Implementations/MediaEncoder/MediaEncoder.cs
@@ -175,6 +175,10 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
string probeSizeArgument,
CancellationToken cancellationToken)
{
+ var args = extractChapters
+ ? "{0} -i {1} -threads 0 -v info -print_format json -show_streams -show_chapters -show_format"
+ : "{0} -i {1} -threads 0 -v info -print_format json -show_streams -show_format";
+
var process = new Process
{
StartInfo = new ProcessStartInfo
@@ -186,8 +190,7 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
RedirectStandardOutput = true,
RedirectStandardError = true,
FileName = FFProbePath,
- Arguments = string.Format(
- "{0} -i {1} -threads 0 -v info -print_format json -show_streams -show_format",
+ Arguments = string.Format(args,
probeSizeArgument, inputPath).Trim(),
WindowStyle = ProcessWindowStyle.Hidden,
@@ -204,7 +207,6 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
await _ffProbeResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);
InternalMediaInfoResult result;
- string standardError = null;
try
{
@@ -221,24 +223,9 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
try
{
- Task<string> standardErrorReadTask = null;
-
- // MUST read both stdout and stderr asynchronously or a deadlock may occurr
- if (extractChapters)
- {
- standardErrorReadTask = process.StandardError.ReadToEndAsync();
- }
- else
- {
- process.BeginErrorReadLine();
- }
+ process.BeginErrorReadLine();
result = _jsonSerializer.DeserializeFromStream<InternalMediaInfoResult>(process.StandardOutput.BaseStream);
-
- if (extractChapters)
- {
- standardError = await standardErrorReadTask.ConfigureAwait(false);
- }
}
catch
{
@@ -282,11 +269,6 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
}
}
- if (extractChapters && !string.IsNullOrEmpty(standardError))
- {
- AddChapters(result, standardError);
- }
-
return result;
}
@@ -296,66 +278,6 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder
protected readonly CultureInfo UsCulture = new CultureInfo("en-US");
/// <summary>
- /// Adds the chapters.
- /// </summary>
- /// <param name="result">The result.</param>
- /// <param name="standardError">The standard error.</param>
- private void AddChapters(InternalMediaInfoResult result, string standardError)
- {
- var lines = standardError.Split('\n').Select(l => l.TrimStart());
-
- var chapters = new List<ChapterInfo>();
-
- ChapterInfo lastChapter = null;
-
- foreach (var line in lines)
- {
- if (line.StartsWith("Chapter", StringComparison.OrdinalIgnoreCase))
- {
- // Example:
- // Chapter #0.2: start 400.534, end 4565.435
- const string srch = "start ";
- var start = line.IndexOf(srch, StringComparison.OrdinalIgnoreCase);
-
- if (start == -1)
- {
- continue;
- }
-
- var subString = line.Substring(start + srch.Length);
- subString = subString.Substring(0, subString.IndexOf(','));
-
- double seconds;
-
- if (double.TryParse(subString, NumberStyles.Any, UsCulture, out seconds))
- {
- lastChapter = new ChapterInfo
- {
- StartPositionTicks = TimeSpan.FromSeconds(seconds).Ticks
- };
-
- chapters.Add(lastChapter);
- }
- }
-
- else if (line.StartsWith("title", StringComparison.OrdinalIgnoreCase))
- {
- if (lastChapter != null && string.IsNullOrEmpty(lastChapter.Name))
- {
- var index = line.IndexOf(':');
-
- if (index != -1)
- {
- lastChapter.Name = line.Substring(index + 1).Trim().TrimEnd('\r');
- }
- }
- }
- }
-
- result.Chapters = chapters;
- }
-
- /// <summary>
/// Processes the exited.
/// </summary>
/// <param name="sender">The sender.</param>
diff --git a/MediaBrowser.Server.Implementations/ServerApplicationPaths.cs b/MediaBrowser.Server.Implementations/ServerApplicationPaths.cs
index c36c49df0..df2a5f83c 100644
--- a/MediaBrowser.Server.Implementations/ServerApplicationPaths.cs
+++ b/MediaBrowser.Server.Implementations/ServerApplicationPaths.cs
@@ -1,6 +1,6 @@
-using System;
-using MediaBrowser.Common.Implementations;
+using MediaBrowser.Common.Implementations;
using MediaBrowser.Controller;
+using System;
using System.IO;
namespace MediaBrowser.Server.Implementations
@@ -239,14 +239,20 @@ namespace MediaBrowser.Server.Implementations
}
}
+ private string _internalMetadataPath;
public string InternalMetadataPath
{
get
{
- return Path.Combine(DataPath, "metadata");
+ return _internalMetadataPath ?? (_internalMetadataPath = Path.Combine(DataPath, "metadata"));
+ }
+ set
+ {
+ _internalMetadataPath = value;
}
}
+
public string GetInternalMetadataPath(Guid id)
{
var idString = id.ToString("N");
diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs
index 93b9b87c6..06ffa37a1 100644
--- a/MediaBrowser.ServerApplication/ApplicationHost.cs
+++ b/MediaBrowser.ServerApplication/ApplicationHost.cs
@@ -442,7 +442,7 @@ namespace MediaBrowser.ServerApplication
FileOrganizationRepository = await GetFileOrganizationRepository().ConfigureAwait(false);
RegisterSingleInstance(FileOrganizationRepository);
- UserManager = new UserManager(Logger, ServerConfigurationManager, UserRepository);
+ UserManager = new UserManager(LogManager.GetLogger("UserManager"), ServerConfigurationManager, UserRepository);
RegisterSingleInstance(UserManager);
LibraryManager = new LibraryManager(Logger, TaskManager, UserManager, ServerConfigurationManager, UserDataManager, () => LibraryMonitor, FileSystemManager, () => ProviderManager);
@@ -466,13 +466,13 @@ namespace MediaBrowser.ServerApplication
RegisterSingleInstance(HttpServer, false);
progress.Report(10);
- ServerManager = new ServerManager(this, JsonSerializer, Logger, ServerConfigurationManager);
+ ServerManager = new ServerManager(this, JsonSerializer, LogManager.GetLogger("ServerManager"), ServerConfigurationManager);
RegisterSingleInstance(ServerManager);
LocalizationManager = new LocalizationManager(ServerConfigurationManager, FileSystemManager);
RegisterSingleInstance(LocalizationManager);
- ImageProcessor = new ImageProcessor(Logger, ServerConfigurationManager.ApplicationPaths, FileSystemManager, JsonSerializer);
+ ImageProcessor = new ImageProcessor(LogManager.GetLogger("ImageProcessor"), ServerConfigurationManager.ApplicationPaths, FileSystemManager, JsonSerializer);
RegisterSingleInstance(ImageProcessor);
DtoService = new DtoService(Logger, LibraryManager, UserManager, UserDataManager, ItemRepository, ImageProcessor, ServerConfigurationManager, FileSystemManager, ProviderManager);
@@ -481,7 +481,7 @@ namespace MediaBrowser.ServerApplication
var newsService = new Server.Implementations.News.NewsService(ApplicationPaths, JsonSerializer);
RegisterSingleInstance<INewsService>(newsService);
- var fileOrganizationService = new FileOrganizationService(TaskManager, FileOrganizationRepository, Logger, LibraryMonitor, LibraryManager, ServerConfigurationManager, FileSystemManager, ProviderManager);
+ var fileOrganizationService = new FileOrganizationService(TaskManager, FileOrganizationRepository, LogManager.GetLogger("FileOrganizationService"), LibraryMonitor, LibraryManager, ServerConfigurationManager, FileSystemManager, ProviderManager);
RegisterSingleInstance<IFileOrganizationService>(fileOrganizationService);
progress.Report(15);
@@ -502,7 +502,7 @@ namespace MediaBrowser.ServerApplication
var appThemeManager = new AppThemeManager(ApplicationPaths, FileSystemManager, JsonSerializer, Logger);
RegisterSingleInstance<IAppThemeManager>(appThemeManager);
- var dlnaManager = new DlnaManager(XmlSerializer, FileSystemManager, JsonSerializer);
+ var dlnaManager = new DlnaManager(XmlSerializer, FileSystemManager, ApplicationPaths, LogManager.GetLogger("DLNA"));
RegisterSingleInstance<IDlnaManager>(dlnaManager);
var collectionManager = new CollectionManager(LibraryManager, FileSystemManager, LibraryMonitor);
@@ -801,7 +801,7 @@ namespace MediaBrowser.ServerApplication
list.Add(typeof(ApiEntryPoint).Assembly);
// Include composable parts in the Dashboard assembly
- list.Add(typeof(DashboardInfo).Assembly);
+ list.Add(typeof(DashboardService).Assembly);
// Include composable parts in the Model assembly
list.Add(typeof(SystemInfo).Assembly);
diff --git a/MediaBrowser.WebDashboard/Api/DashboardInfo.cs b/MediaBrowser.WebDashboard/Api/DashboardInfo.cs
deleted file mode 100644
index 78cc5a758..000000000
--- a/MediaBrowser.WebDashboard/Api/DashboardInfo.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-using MediaBrowser.Model.Session;
-using MediaBrowser.Model.System;
-using MediaBrowser.Model.Tasks;
-using System;
-using System.Collections.Generic;
-
-namespace MediaBrowser.WebDashboard.Api
-{
- /// <summary>
- /// Class DashboardInfo
- /// </summary>
- public class DashboardInfo
- {
- /// <summary>
- /// Gets or sets the system info.
- /// </summary>
- /// <value>The system info.</value>
- public SystemInfo SystemInfo { get; set; }
-
- /// <summary>
- /// Gets or sets the running tasks.
- /// </summary>
- /// <value>The running tasks.</value>
- public List<TaskInfo> RunningTasks { get; set; }
-
- /// <summary>
- /// Gets or sets the application update task id.
- /// </summary>
- /// <value>The application update task id.</value>
- public Guid ApplicationUpdateTaskId { get; set; }
-
- /// <summary>
- /// Gets or sets the active connections.
- /// </summary>
- /// <value>The active connections.</value>
- public List<SessionInfoDto> ActiveConnections { get; set; }
- }
-
-}
diff --git a/MediaBrowser.WebDashboard/Api/DashboardInfoWebSocketListener.cs b/MediaBrowser.WebDashboard/Api/DashboardInfoWebSocketListener.cs
deleted file mode 100644
index af0f9e3a0..000000000
--- a/MediaBrowser.WebDashboard/Api/DashboardInfoWebSocketListener.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-using MediaBrowser.Common.Net;
-using MediaBrowser.Common.ScheduledTasks;
-using MediaBrowser.Controller;
-using MediaBrowser.Controller.Dto;
-using MediaBrowser.Controller.Session;
-using MediaBrowser.Model.Logging;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.WebDashboard.Api
-{
- /// <summary>
- /// Class DashboardInfoWebSocketListener
- /// </summary>
- class DashboardInfoWebSocketListener : BasePeriodicWebSocketListener<DashboardInfo, object>
- {
- /// <summary>
- /// Gets the name.
- /// </summary>
- /// <value>The name.</value>
- protected override string Name
- {
- get { return "DashboardInfo"; }
- }
-
- private readonly IServerApplicationHost _appHost;
-
- /// <summary>
- /// Gets or sets the task manager.
- /// </summary>
- /// <value>The task manager.</value>
- private readonly ITaskManager _taskManager;
-
- private readonly ISessionManager _sessionManager;
- private readonly IDtoService _dtoService;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="DashboardInfoWebSocketListener" /> class.
- /// </summary>
- /// <param name="appHost">The app host.</param>
- /// <param name="logger">The logger.</param>
- /// <param name="taskManager">The task manager.</param>
- /// <param name="sessionManager">The session manager.</param>
- public DashboardInfoWebSocketListener(IServerApplicationHost appHost, ILogger logger, ITaskManager taskManager, ISessionManager sessionManager, IDtoService dtoService)
- : base(logger)
- {
- _appHost = appHost;
- _taskManager = taskManager;
- _sessionManager = sessionManager;
- _dtoService = dtoService;
- }
-
- /// <summary>
- /// Gets the data to send.
- /// </summary>
- /// <param name="state">The state.</param>
- /// <returns>Task{IEnumerable{TaskInfo}}.</returns>
- protected override Task<DashboardInfo> GetDataToSend(object state)
- {
- return Task.FromResult(DashboardService.GetDashboardInfo(_appHost, _taskManager, _sessionManager, _dtoService));
- }
- }
-}
diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs
index 88f86632b..99afbbdd7 100644
--- a/MediaBrowser.WebDashboard/Api/DashboardService.cs
+++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs
@@ -1,16 +1,13 @@
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.IO;
using MediaBrowser.Common.Net;
-using MediaBrowser.Common.ScheduledTasks;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Plugins;
-using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Logging;
-using MediaBrowser.Model.Tasks;
using ServiceStack;
+using ServiceStack.Web;
using System;
using System.Collections.Generic;
using System.IO;
@@ -18,7 +15,6 @@ using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
-using ServiceStack.Web;
namespace MediaBrowser.WebDashboard.Api
{
@@ -67,14 +63,6 @@ namespace MediaBrowser.WebDashboard.Api
}
/// <summary>
- /// Class GetDashboardInfo
- /// </summary>
- [Route("/dashboard/dashboardInfo", "GET")]
- public class GetDashboardInfo : IReturn<DashboardInfo>
- {
- }
-
- /// <summary>
/// Class DashboardService
/// </summary>
public class DashboardService : IRestfulService, IHasResultFactory
@@ -98,12 +86,6 @@ namespace MediaBrowser.WebDashboard.Api
public IRequest Request { get; set; }
/// <summary>
- /// Gets or sets the task manager.
- /// </summary>
- /// <value>The task manager.</value>
- private readonly ITaskManager _taskManager;
-
- /// <summary>
/// The _app host
/// </summary>
private readonly IServerApplicationHost _appHost;
@@ -113,24 +95,18 @@ namespace MediaBrowser.WebDashboard.Api
/// </summary>
private readonly IServerConfigurationManager _serverConfigurationManager;
- private readonly ISessionManager _sessionManager;
- private readonly IDtoService _dtoService;
private readonly IFileSystem _fileSystem;
/// <summary>
/// Initializes a new instance of the <see cref="DashboardService" /> class.
/// </summary>
- /// <param name="taskManager">The task manager.</param>
/// <param name="appHost">The app host.</param>
/// <param name="serverConfigurationManager">The server configuration manager.</param>
- /// <param name="sessionManager">The session manager.</param>
- public DashboardService(ITaskManager taskManager, IServerApplicationHost appHost, IServerConfigurationManager serverConfigurationManager, ISessionManager sessionManager, IDtoService dtoService, IFileSystem fileSystem)
+ /// <param name="fileSystem">The file system.</param>
+ public DashboardService(IServerApplicationHost appHost, IServerConfigurationManager serverConfigurationManager, IFileSystem fileSystem)
{
- _taskManager = taskManager;
_appHost = appHost;
_serverConfigurationManager = serverConfigurationManager;
- _sessionManager = sessionManager;
- _dtoService = dtoService;
_fileSystem = fileSystem;
}
@@ -168,45 +144,6 @@ namespace MediaBrowser.WebDashboard.Api
/// </summary>
/// <param name="request">The request.</param>
/// <returns>System.Object.</returns>
- public object Get(GetDashboardInfo request)
- {
- var result = GetDashboardInfo(_appHost, _taskManager, _sessionManager, _dtoService);
-
- return ResultFactory.GetOptimizedResult(Request, result);
- }
-
- /// <summary>
- /// Gets the dashboard info.
- /// </summary>
- /// <param name="appHost">The app host.</param>
- /// <param name="taskManager">The task manager.</param>
- /// <param name="connectionManager">The connection manager.</param>
- /// <returns>DashboardInfo.</returns>
- public static DashboardInfo GetDashboardInfo(IServerApplicationHost appHost,
- ITaskManager taskManager,
- ISessionManager connectionManager, IDtoService dtoService)
- {
- var connections = connectionManager.Sessions.Where(i => i.IsActive).ToList();
-
- return new DashboardInfo
- {
- SystemInfo = appHost.GetSystemInfo(),
-
- RunningTasks = taskManager.ScheduledTasks.Where(i => i.State == TaskState.Running || i.State == TaskState.Cancelling)
- .Select(ScheduledTaskHelpers.GetTaskInfo)
- .ToList(),
-
- ApplicationUpdateTaskId = taskManager.ScheduledTasks.First(t => t.ScheduledTask.GetType().Name.Equals("SystemUpdateTask", StringComparison.OrdinalIgnoreCase)).Id,
-
- ActiveConnections = connections.Select(dtoService.GetSessionInfoDto).ToList()
- };
- }
-
- /// <summary>
- /// Gets the specified request.
- /// </summary>
- /// <param name="request">The request.</param>
- /// <returns>System.Object.</returns>
public object Get(GetDashboardConfigurationPage request)
{
var page = ServerEntryPoint.Instance.PluginConfigurationPages.First(p => p.Name.Equals(request.Name, StringComparison.OrdinalIgnoreCase));
@@ -473,6 +410,7 @@ namespace MediaBrowser.WebDashboard.Api
"alphapicker.js",
"addpluginpage.js",
"advancedconfigurationpage.js",
+ "advancedpaths.js",
"advancedserversettings.js",
"metadataadvanced.js",
"appsplayback.js",
@@ -484,6 +422,8 @@ namespace MediaBrowser.WebDashboard.Api
"dashboardinfo.js",
"dashboardpage.js",
"directorybrowser.js",
+ "dlnaprofile.js",
+ "dlnaprofiles.js",
"dlnasettings.js",
"editcollectionitems.js",
"edititemmetadata.js",
diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
index a0dbae3d4..6a8cc49b1 100644
--- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
+++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
@@ -63,9 +63,7 @@
<Link>Properties\SharedVersion.cs</Link>
</Compile>
<Compile Include="Api\ConfigurationPageInfo.cs" />
- <Compile Include="Api\DashboardInfo.cs" />
<Compile Include="Api\DashboardService.cs" />
- <Compile Include="Api\DashboardInfoWebSocketListener.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ServerEntryPoint.cs" />
</ItemGroup>
@@ -85,6 +83,9 @@
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="ApiClient.js" />
+ <Content Include="dashboard-ui\advancedpaths.html">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
<Content Include="dashboard-ui\advancedserversettings.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -202,8 +203,12 @@
<Content Include="dashboard-ui\css\images\items\list\remotesearch.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\css\images\media\pause.png" />
- <Content Include="dashboard-ui\css\images\media\play.png" />
+ <Content Include="dashboard-ui\css\images\media\pause.png">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="dashboard-ui\css\images\media\play.png">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
<Content Include="dashboard-ui\css\images\media\tvflyout.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -219,6 +224,12 @@
<Content Include="dashboard-ui\dashboardinfopage.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
+ <Content Include="dashboard-ui\dlnaprofile.html">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="dashboard-ui\dlnaprofiles.html">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
<Content Include="dashboard-ui\dlnasettings.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -483,6 +494,9 @@
<Content Include="dashboard-ui\livetvrecordings.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
+ <Content Include="dashboard-ui\scripts\advancedpaths.js">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
<Content Include="dashboard-ui\scripts\advancedserversettings.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -504,6 +518,12 @@
<Content Include="dashboard-ui\scripts\dashboardinfo.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
+ <Content Include="dashboard-ui\scripts\dlnaprofile.js">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="dashboard-ui\scripts\dlnaprofiles.js">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
<Content Include="dashboard-ui\scripts\dlnasettings.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>