expand on dlna profiles

pull/702/head
Luke Pulverenti 10 years ago
parent bd53ddc67c
commit 0db3588529

@ -0,0 +1,25 @@

namespace MediaBrowser.Controller.Dlna
{
public class DirectPlayProfile
{
public string[] Containers { get; set; }
public string[] AudioCodecs { get; set; }
public string[] VideoCodecs { get; set; }
public string MimeType { get; set; }
public DlnaProfileType Type { get; set; }
public DirectPlayProfile()
{
Containers = new string[] { };
AudioCodecs = new string[] { };
VideoCodecs = new string[] { };
}
}
public enum DlnaProfileType
{
Audio = 0,
Video = 1
}
}

@ -0,0 +1,54 @@

namespace MediaBrowser.Controller.Dlna
{
public class DlnaProfile
{
/// <summary>
/// Gets or sets the name.
/// </summary>
/// <value>The name.</value>
public string Name { get; set; }
/// <summary>
/// Gets or sets the type of the client.
/// </summary>
/// <value>The type of the client.</value>
public string ClientType { get; set; }
/// <summary>
/// Gets or sets the name of the friendly.
/// </summary>
/// <value>The name of the friendly.</value>
public string FriendlyName { get; set; }
/// <summary>
/// Gets or sets the model number.
/// </summary>
/// <value>The model number.</value>
public string ModelNumber { get; set; }
/// <summary>
/// Gets or sets the name of the model.
/// </summary>
/// <value>The name of the model.</value>
public string ModelName { get; set; }
/// <summary>
/// Gets or sets the transcoding profiles.
/// </summary>
/// <value>The transcoding profiles.</value>
public TranscodingProfile[] TranscodingProfiles { get; set; }
/// <summary>
/// Gets or sets the direct play profiles.
/// </summary>
/// <value>The direct play profiles.</value>
public DirectPlayProfile[] DirectPlayProfiles { get; set; }
public DlnaProfile()
{
DirectPlayProfiles = new DirectPlayProfile[] { };
TranscodingProfiles = new TranscodingProfile[] { };
}
}
}

@ -0,0 +1,28 @@
using System.Collections.Generic;
namespace MediaBrowser.Controller.Dlna
{
public interface IDlnaManager
{
/// <summary>
/// Gets the dlna profiles.
/// </summary>
/// <returns>IEnumerable{DlnaProfile}.</returns>
IEnumerable<DlnaProfile> GetProfiles();
/// <summary>
/// Gets the default profile.
/// </summary>
/// <returns>DlnaProfile.</returns>
DlnaProfile GetDefaultProfile();
/// <summary>
/// Gets the profile.
/// </summary>
/// <param name="friendlyName">Name of the friendly.</param>
/// <param name="modelName">Name of the model.</param>
/// <param name="modelNumber">The model number.</param>
/// <returns>DlnaProfile.</returns>
DlnaProfile GetProfile(string friendlyName, string modelName, string modelNumber);
}
}

@ -0,0 +1,16 @@

namespace MediaBrowser.Controller.Dlna
{
public class TranscodingProfile
{
public string Container { get; set; }
public DlnaProfileType Type { get; set; }
public string MimeType { get; set; }
public string VideoCodec { get; set; }
public string AudioCodec { get; set; }
}
}

@ -1332,6 +1332,11 @@ namespace MediaBrowser.Controller.Entities
return ImageInfos.Where(i => i.Type == imageType);
}
public bool AddImages(ImageType imageType, IEnumerable<FileInfo> images)
{
return AddImages(imageType, images.Cast<FileSystemInfo>());
}
/// <summary>
/// Adds the images.
/// </summary>

@ -73,6 +73,10 @@
<Compile Include="Channels\IChannelManager.cs" />
<Compile Include="Collections\CollectionCreationOptions.cs" />
<Compile Include="Collections\ICollectionManager.cs" />
<Compile Include="Dlna\DirectPlayProfile.cs" />
<Compile Include="Dlna\IDlnaManager.cs" />
<Compile Include="Dlna\DlnaProfile.cs" />
<Compile Include="Dlna\TranscodingProfile.cs" />
<Compile Include="Drawing\IImageProcessor.cs" />
<Compile Include="Drawing\ImageFormat.cs" />
<Compile Include="Drawing\ImageProcessingOptions.cs" />

@ -0,0 +1,202 @@
using MediaBrowser.Controller.Dlna;
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace MediaBrowser.Dlna
{
public class DlnaManager : IDlnaManager
{
public IEnumerable<DlnaProfile> GetProfiles()
{
var profile0 = new DlnaProfile
{
Name = "Samsung TV (B Series) [Profile]",
ClientType = "DLNA",
FriendlyName = "^TV$",
ModelNumber = @"1\.0",
ModelName = "Samsung DTV DMR",
TranscodingProfiles = new[]
{
new TranscodingProfile
{
Container = "mp3",
Type = DlnaProfileType.Audio
}
},
DirectPlayProfiles = new[]
{
new DirectPlayProfile
{
Containers = new[]{"mkv"},
MimeType = "x-mkv",
Type = DlnaProfileType.Video
}
}
};
var profile1 = new DlnaProfile
{
Name = "Samsung TV (E/F-series) [Profile]",
ClientType = "DLNA",
FriendlyName = @"(^\[TV\][A-Z]{2}\d{2}(E|F)[A-Z]?\d{3,4}.*)|^\[TV\] Samsung",
ModelNumber = @"(1\.0)|(AllShare1\.0)",
TranscodingProfiles = new[]
{
new TranscodingProfile
{
Container = "mp3",
Type = DlnaProfileType.Audio
}
},
DirectPlayProfiles = new[]
{
new DirectPlayProfile
{
Containers = new[]{"mkv"},
MimeType = "x-mkv",
Type = DlnaProfileType.Video
}
}
};
var profile2 = new DlnaProfile
{
Name = "Samsung TV (C/D-series) [Profile]",
ClientType = "DLNA",
FriendlyName = @"(^TV-\d{2}C\d{3}.*)|(^\[TV\][A-Z]{2}\d{2}(D)[A-Z]?\d{3,4}.*)|^\[TV\] Samsung",
ModelNumber = @"(1\.0)|(AllShare1\.0)",
TranscodingProfiles = new[]
{
new TranscodingProfile
{
Container = "mp3",
Type = DlnaProfileType.Audio
}
},
DirectPlayProfiles = new[]
{
new DirectPlayProfile
{
Containers = new[]{"mkv"},
MimeType = "x-mkv",
Type = DlnaProfileType.Video
}
}
};
var profile3 = new DlnaProfile
{
Name = "Xbox 360 [Profile]",
ClientType = "DLNA",
ModelName = "Xbox 360",
TranscodingProfiles = new[]
{
new TranscodingProfile
{
Container = "mp3",
Type = DlnaProfileType.Audio
},
new TranscodingProfile
{
Container = "ts",
Type = DlnaProfileType.Video
}
}
};
var profile4 = new DlnaProfile
{
Name = "Xbox One [Profile]",
ModelName = "Xbox One",
ClientType = "DLNA",
FriendlyName = "Xbox-SystemOS",
TranscodingProfiles = new[]
{
new TranscodingProfile
{
Container = "mp3",
Type = DlnaProfileType.Audio
},
new TranscodingProfile
{
Container = "ts",
Type = DlnaProfileType.Video
}
}
};
var profile5 = new DlnaProfile
{
Name = "Sony Bravia TV (2012)",
ClientType = "TV",
FriendlyName = @"BRAVIA KDL-\d{2}[A-Z]X\d5(\d|G).*"
};
//WDTV does not need any transcoding of the formats we support statically
var profile6 = new DlnaProfile
{
Name = "WDTV Live [Profile]",
ClientType = "DLNA",
ModelName = "WD TV HD Live"
};
var profile7 = new DlnaProfile
{
//Linksys DMA2100us does not need any transcoding of the formats we support statically
Name = "Linksys DMA2100 [Profile]",
ClientType = "DLNA",
ModelName = "DMA2100us"
};
return new[]
{
profile0,
profile1,
profile2,
profile3,
profile4,
profile5,
profile6,
profile7
};
}
public DlnaProfile GetDefaultProfile()
{
return new DlnaProfile();
}
public DlnaProfile GetProfile(string friendlyName, string modelName, string modelNumber)
{
foreach (var profile in GetProfiles())
{
if (!string.IsNullOrEmpty(profile.FriendlyName))
{
if (!Regex.IsMatch(friendlyName, profile.FriendlyName))
continue;
}
if (!string.IsNullOrEmpty(profile.ModelNumber))
{
if (!Regex.IsMatch(modelNumber, profile.ModelNumber))
continue;
}
if (!string.IsNullOrEmpty(profile.ModelName))
{
if (!Regex.IsMatch(modelName, profile.ModelName))
continue;
}
return profile;
}
return GetDefaultProfile();
}
}
}

@ -51,15 +51,14 @@
<Compile Include="..\SharedVersion.cs">
<Link>Properties\SharedVersion.cs</Link>
</Compile>
<Compile Include="DlnaManager.cs" />
<Compile Include="PlayTo\Argument.cs" />
<Compile Include="PlayTo\Configuration\DlnaProfile.cs" />
<Compile Include="PlayTo\Configuration\PlayToConfiguration.cs" />
<Compile Include="PlayTo\Configuration\TranscodeSetting.cs" />
<Compile Include="PlayTo\CurrentIdEventArgs.cs" />
<Compile Include="PlayTo\Device.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="PlayTo\DeviceProperties.cs" />
<Compile Include="PlayTo\DeviceInfo.cs" />
<Compile Include="PlayTo\DeviceService.cs" />
<Compile Include="PlayTo\DidlBuilder.cs" />
<Compile Include="PlayTo\DlnaController.cs" />
<Compile Include="PlayTo\DlnaControllerFactory.cs" />
@ -81,7 +80,6 @@
<Compile Include="PlayTo\uIcon.cs" />
<Compile Include="PlayTo\uParser.cs" />
<Compile Include="PlayTo\uPnpNamespaces.cs" />
<Compile Include="PlayTo\uService.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>

@ -1,53 +0,0 @@
namespace MediaBrowser.Dlna.PlayTo.Configuration
{
public class DlnaProfile
{
/// <summary>
/// Gets or sets the name to be displayed.
/// </summary>
/// <value>
/// The name.
/// </value>
public string Name { get; set; }
/// <summary>
/// Gets or sets the type of the client.
/// </summary>
/// <value>
/// The type of the client.
/// </value>
public string ClientType { get; set; }
/// <summary>
/// Gets or sets the name of the friendly.
/// </summary>
/// <value>
/// The name of the friendly.
/// </value>
public string FriendlyName { get; set; }
/// <summary>
/// Gets or sets the model number.
/// </summary>
/// <value>
/// The model number.
/// </value>
public string ModelNumber { get; set; }
/// <summary>
/// Gets or sets the name of the model.
/// </summary>
/// <value>
/// The name of the model.
/// </value>
public string ModelName { get; set; }
/// <summary>
/// Gets or sets the transcode settings.
/// </summary>
/// <value>
/// The transcode settings.
/// </value>
public TranscodeSetting[] TranscodeSettings { get; set; }
}
}

@ -1,198 +0,0 @@
using MediaBrowser.Model.Logging;
using System;
using System.IO;
using System.Xml.Serialization;
namespace MediaBrowser.Dlna.PlayTo.Configuration
{
public class PlayToConfiguration
{
[XmlIgnore]
public static PlayToConfiguration Instance
{
get;
private set;
}
private static readonly string[] _supportedStaticFormats = { "mp3", "flac", "m4a", "wma", "avi", "mp4", "mkv", "ts" };
[XmlIgnore]
public string[] SupportedStaticFormats
{
get
{
return _supportedStaticFormats;
}
}
public DlnaProfile[] Profiles
{ get; set; }
public static DlnaProfile[] GetDefaultProfiles()
{
var profile0 = new DlnaProfile
{
Name = "Samsung TV (B Series) [Profile]",
ClientType = "DLNA",
FriendlyName = "^TV$",
ModelNumber = @"1\.0",
ModelName = "Samsung DTV DMR",
TranscodeSettings = new[]
{
new TranscodeSetting {Container = "mkv", MimeType = "x-mkv"},
new TranscodeSetting {Container = "flac", TargetContainer = "mp3"},
new TranscodeSetting {Container = "m4a", TargetContainer = "mp3"}
}
};
var profile1 = new DlnaProfile
{
Name = "Samsung TV (E/F-series) [Profile]",
ClientType = "DLNA",
FriendlyName = @"(^\[TV\][A-Z]{2}\d{2}(E|F)[A-Z]?\d{3,4}.*)|^\[TV\] Samsung",
ModelNumber = @"(1\.0)|(AllShare1\.0)",
TranscodeSettings = new[]
{
new TranscodeSetting {Container = "mkv", MimeType = "x-mkv"},
new TranscodeSetting {Container = "flac", TargetContainer = "mp3"},
new TranscodeSetting {Container = "m4a", TargetContainer = "mp3"}
}
};
var profile2 = new DlnaProfile
{
Name = "Samsung TV (C/D-series) [Profile]",
ClientType = "DLNA",
FriendlyName = @"(^TV-\d{2}C\d{3}.*)|(^\[TV\][A-Z]{2}\d{2}(D)[A-Z]?\d{3,4}.*)|^\[TV\] Samsung",
ModelNumber = @"(1\.0)|(AllShare1\.0)",
TranscodeSettings = new[]
{
new TranscodeSetting {Container = "mkv", MimeType = "x-mkv"},
new TranscodeSetting {Container = "flac", TargetContainer = "mp3"},
new TranscodeSetting {Container = "m4a", TargetContainer = "mp3"}
}
};
var profile3 = new DlnaProfile
{
Name = "Xbox 360 [Profile]",
ClientType = "DLNA",
ModelName = "Xbox 360",
TranscodeSettings = new[]
{
new TranscodeSetting {Container = "mkv", TargetContainer = "ts"},
new TranscodeSetting {Container = "flac", TargetContainer = "mp3"},
new TranscodeSetting {Container = "m4a", TargetContainer = "mp3"}
}
};
var profile4 = new DlnaProfile
{
Name = "Xbox One [Profile]",
ModelName = "Xbox One",
ClientType = "DLNA",
FriendlyName = "Xbox-SystemOS",
TranscodeSettings = new[]
{
new TranscodeSetting {Container = "mkv", TargetContainer = "ts"},
new TranscodeSetting {Container = "flac", TargetContainer = "mp3"},
new TranscodeSetting {Container = "m4a", TargetContainer = "mp3"}
}
};
var profile5 = new DlnaProfile
{
Name = "Sony Bravia TV (2012)",
ClientType = "TV",
FriendlyName = @"BRAVIA KDL-\d{2}[A-Z]X\d5(\d|G).*",
TranscodeSettings = TranscodeSetting.GetDefaultTranscodingSettings()
};
//WDTV does not need any transcoding of the formats we support statically
var profile6 = new DlnaProfile
{
Name = "WDTV Live [Profile]",
ClientType = "DLNA",
ModelName = "WD TV HD Live",
TranscodeSettings = new TranscodeSetting[] { }
};
var profile7 = new DlnaProfile
{
//Linksys DMA2100us does not need any transcoding of the formats we support statically
Name = "Linksys DMA2100 [Profile]",
ClientType = "DLNA",
ModelName = "DMA2100us",
TranscodeSettings = new TranscodeSetting[] { }
};
return new[]
{
profile0,
profile1,
profile2,
profile3,
profile4,
profile5,
profile6,
profile7
};
}
public static void Load(string path, ILogger logger)
{
if (!File.Exists(path))
{
Instance = CreateNewSettingsFile(path, logger);
}
else
{
try
{
XmlSerializer deserializer = new XmlSerializer(typeof(PlayToConfiguration));
using (var textReader = new StreamReader(path))
{
var configuration = (PlayToConfiguration)deserializer.Deserialize(textReader);
Instance = configuration;
textReader.Close();
}
}
catch (Exception e)
{
// Something went wrong with the loading of the file
// Maybe a user created a faulty config?
// Delete the file and use default settings
logger.ErrorException("Error loading PlayTo configuration", e);
Instance = CreateNewSettingsFile(path, logger);
}
}
}
private static PlayToConfiguration CreateNewSettingsFile(string path, ILogger logger)
{
var defaultConfig = new PlayToConfiguration();
defaultConfig.Profiles = PlayToConfiguration.GetDefaultProfiles();
try
{
if (File.Exists(path))
File.Delete(path);
XmlSerializer serializer = new XmlSerializer(typeof(PlayToConfiguration));
using (var fileStream = new StreamWriter(path))
{
serializer.Serialize(fileStream, defaultConfig);
fileStream.Close();
}
}
catch(Exception e)
{
//Something went wrong deleting or creating the file, Log and continue with the default profile unsaved
logger.ErrorException("Error creating default PlayTo configuration", e);
}
return defaultConfig;
}
}
}

@ -1,86 +0,0 @@
using System;
using System.Text.RegularExpressions;
namespace MediaBrowser.Dlna.PlayTo.Configuration
{
public class TranscodeSetting
{
/// <summary>
/// Gets or sets the container.
/// </summary>
/// <value>
/// The container.
/// </value>
public string Container { get; set; }
/// <summary>
/// Gets or sets the target container.
/// </summary>
/// <value>
/// The target container.
/// </value>
public string TargetContainer { get; set; }
/// <summary>
/// Gets or sets the Mimetype to enforce
/// </summary>
/// <value>
/// The MimeType.
/// </value>
public string MimeType { get; set; }
/// <summary>
/// The default transcoding settings
/// </summary>
private static readonly TranscodeSetting[] DefaultTranscodingSettings =
{
new TranscodeSetting { Container = "mkv", TargetContainer = "ts" },
new TranscodeSetting { Container = "flac", TargetContainer = "mp3" },
new TranscodeSetting { Container = "m4a", TargetContainer = "mp3" }
};
public static TranscodeSetting[] GetDefaultTranscodingSettings()
{
return DefaultTranscodingSettings;
}
/// <summary>
/// Gets the profile settings.
/// </summary>
/// <param name="deviceProperties">The device properties.</param>
/// <returns>The TranscodeSettings for the device</returns>
public static TranscodeSetting[] GetProfileSettings(DeviceProperties deviceProperties)
{
foreach (var profile in PlayToConfiguration.Instance.Profiles)
{
if (!string.IsNullOrEmpty(profile.FriendlyName))
{
if (!Regex.IsMatch(deviceProperties.Name, profile.FriendlyName))
continue;
}
if (!string.IsNullOrEmpty(profile.ModelNumber))
{
if (!Regex.IsMatch(deviceProperties.ModelNumber, profile.ModelNumber))
continue;
}
if (!string.IsNullOrEmpty(profile.ModelName))
{
if (!Regex.IsMatch(deviceProperties.ModelName, profile.ModelName))
continue;
}
deviceProperties.DisplayName = profile.Name;
deviceProperties.ClientType = profile.ClientType;
return profile.TranscodeSettings;
}
// Since we don't have alot of info about different devices we go down the safe
// route abd use the default transcoding settings if no profile exist
return GetDefaultTranscodingSettings();
}
}
}

@ -18,7 +18,7 @@ namespace MediaBrowser.Dlna.PlayTo
private Timer _timer;
public DeviceProperties Properties { get; set; }
public DeviceInfo Properties { get; set; }
private int _muteVol;
public bool IsMuted
@ -120,7 +120,7 @@ namespace MediaBrowser.Dlna.PlayTo
private readonly IHttpClient _httpClient;
private readonly ILogger _logger;
public Device(DeviceProperties deviceProperties, IHttpClient httpClient, ILogger logger)
public Device(DeviceInfo deviceProperties, IHttpClient httpClient, ILogger logger)
{
Properties = deviceProperties;
_httpClient = httpClient;
@ -599,7 +599,7 @@ namespace MediaBrowser.Dlna.PlayTo
if (avService == null)
return;
var url = avService.SCPDURL;
var url = avService.ScpdUrl;
if (!url.Contains("/"))
url = "/dmr/" + url;
if (!url.StartsWith("/"))
@ -617,7 +617,7 @@ namespace MediaBrowser.Dlna.PlayTo
if (avService == null)
return;
string url = avService.SCPDURL;
string url = avService.ScpdUrl;
if (!url.Contains("/"))
url = "/dmr/" + url;
if (!url.StartsWith("/"))
@ -647,7 +647,7 @@ namespace MediaBrowser.Dlna.PlayTo
var document = await ssdpHttpClient.GetDataAsync(url).ConfigureAwait(false);
var deviceProperties = new DeviceProperties();
var deviceProperties = new DeviceInfo();
var name = document.Descendants(uPnpNamespaces.ud.GetName("friendlyName")).FirstOrDefault();
if (name != null)
@ -705,7 +705,7 @@ namespace MediaBrowser.Dlna.PlayTo
foreach (var element in servicesList)
{
var service = uService.Create(element);
var service = Create(element);
if (service != null)
{
@ -734,6 +734,17 @@ namespace MediaBrowser.Dlna.PlayTo
#endregion
private static DeviceService Create(XElement element)
{
var type = element.GetDescendantValue(uPnpNamespaces.ud.GetName("serviceType"));
var id = element.GetDescendantValue(uPnpNamespaces.ud.GetName("serviceId"));
var scpdUrl = element.GetDescendantValue(uPnpNamespaces.ud.GetName("SCPDURL"));
var controlURL = element.GetDescendantValue(uPnpNamespaces.ud.GetName("controlURL"));
var eventSubURL = element.GetDescendantValue(uPnpNamespaces.ud.GetName("eventSubURL"));
return new DeviceService(type, id, scpdUrl, controlURL, eventSubURL);
}
#region Events
public event EventHandler<TransportStateEventArgs> PlaybackChanged;

@ -0,0 +1,49 @@
using System.Collections.Generic;
namespace MediaBrowser.Dlna.PlayTo
{
public class DeviceInfo
{
public string UUID { get; set; }
public string Name { get; set; }
public string ClientType { get; set; }
public string DisplayName { get; set; }
public string ModelName { get; set; }
public string ModelNumber { get; set; }
public string Manufacturer { get; set; }
public string ManufacturerUrl { get; set; }
public string PresentationUrl { get; set; }
private string _baseUrl = string.Empty;
public string BaseUrl
{
get
{
return _baseUrl;
}
set
{
_baseUrl = value;
}
}
public uIcon Icon { get; set; }
private readonly List<DeviceService> _services = new List<DeviceService>();
public List<DeviceService> Services
{
get
{
return _services;
}
}
}
}

@ -1,176 +0,0 @@
using System.Collections.Generic;
namespace MediaBrowser.Dlna.PlayTo
{
public class DeviceProperties
{
private string _uuid = string.Empty;
public string UUID
{
get
{
return _uuid;
}
set
{
_uuid = value;
}
}
private string _name = "PlayTo 1.0.0.0";
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
private string _clientType = "DLNA";
public string ClientType
{
get
{
return _clientType;
}
set
{
_clientType = value;
}
}
private string _displayName = string.Empty;
public string DisplayName
{
get
{
return string.IsNullOrEmpty(_displayName) ? _name : _displayName;
}
set
{
_displayName = value;
}
}
private string _modelName = string.Empty;
public string ModelName
{
get
{
return _modelName;
}
set
{
_modelName = value;
}
}
private string _modelNumber = string.Empty;
public string ModelNumber
{
get
{
return _modelNumber;
}
set
{
_modelNumber = value;
}
}
private string _manufacturer = string.Empty;
public string Manufacturer
{
get
{
return _manufacturer;
}
set
{
_manufacturer = value;
}
}
private string _manufacturerUrl = string.Empty;
public string ManufacturerUrl
{
get
{
return _manufacturerUrl;
}
set
{
_manufacturerUrl = value;
}
}
private string _presentationUrl = string.Empty;
public string PresentationUrl
{
get
{
return _presentationUrl;
}
set
{
_presentationUrl = value;
}
}
private string _baseUrl = string.Empty;
public string BaseUrl
{
get
{
return _baseUrl;
}
set
{
_baseUrl = value;
}
}
private uIcon _icon;
public uIcon Icon
{
get
{
return _icon;
}
set
{
_icon = value;
}
}
private string _iconUrl;
public string IconUrl
{
get
{
if (string.IsNullOrWhiteSpace(_iconUrl) && _icon != null)
{
if (!_icon.Url.StartsWith("/"))
_iconUrl = _baseUrl + "/" + _icon.Url;
else
_iconUrl = _baseUrl + _icon.Url;
}
return _iconUrl;
}
}
private readonly List<uService> _services = new List<uService>();
public List<uService> Services
{
get
{
return _services;
}
}
}
}

@ -0,0 +1,30 @@

namespace MediaBrowser.Dlna.PlayTo
{
public class DeviceService
{
public string ServiceType { get; set; }
public string ServiceId { get; set; }
public string ScpdUrl { get; set; }
public string ControlUrl { get; set; }
public string EventSubUrl { get; set; }
public DeviceService(string serviceType, string serviceId, string scpdUrl, string controlUrl, string eventSubUrl)
{
ServiceType = serviceType;
ServiceId = serviceId;
ScpdUrl = scpdUrl;
ControlUrl = controlUrl;
EventSubUrl = eventSubUrl;
}
public override string ToString()
{
return string.Format("{0}", ServiceId);
}
}
}

@ -1,9 +1,9 @@
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Session;
using MediaBrowser.Dlna.PlayTo.Configuration;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Session;
@ -21,13 +21,13 @@ namespace MediaBrowser.Dlna.PlayTo
{
private Device _device;
private BaseItem _currentItem = null;
private TranscodeSetting[] _transcodeSettings;
private readonly SessionInfo _session;
private readonly ISessionManager _sessionManager;
private readonly IItemRepository _itemRepository;
private readonly ILibraryManager _libraryManager;
private readonly INetworkManager _networkManager;
private readonly ILogger _logger;
private readonly IDlnaManager _dlnaManager;
private bool _playbackStarted = false;
public bool SupportsMediaRemoteControl
@ -56,9 +56,8 @@ namespace MediaBrowser.Dlna.PlayTo
_logger = logger;
}
public void Init(Device device, TranscodeSetting[] transcodeSettings)
public void Init(Device device)
{
_transcodeSettings = transcodeSettings;
_device = device;
_device.PlaybackChanged += Device_PlaybackChanged;
_device.CurrentIdChanged += Device_CurrentIdChanged;
@ -384,7 +383,9 @@ namespace MediaBrowser.Dlna.PlayTo
{
var streams = _itemRepository.GetMediaStreams(new MediaStreamQuery { ItemId = item.Id }).ToList();
var playlistItem = PlaylistItem.GetBasicConfig(item, _transcodeSettings);
var deviceInfo = _device.Properties;
var playlistItem = PlaylistItem.Create(item, _dlnaManager.GetProfile(deviceInfo.Name, deviceInfo.ModelName, deviceInfo.ModelNumber));
playlistItem.StartPositionTicks = startPostionTicks;
if (playlistItem.IsAudio)

@ -1,10 +1,10 @@
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Session;
using MediaBrowser.Dlna.PlayTo.Configuration;
using MediaBrowser.Model.Logging;
using System;
using System.Collections.Concurrent;
@ -16,7 +16,6 @@ using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace MediaBrowser.Dlna.PlayTo
{
@ -33,8 +32,9 @@ namespace MediaBrowser.Dlna.PlayTo
private readonly ILibraryManager _libraryManager;
private readonly INetworkManager _networkManager;
private readonly IUserManager _userManager;
private readonly IDlnaManager _dlnaManager;
public PlayToManager(ILogger logger,IServerConfigurationManager config, ISessionManager sessionManager, IHttpClient httpClient, IItemRepository itemRepository, ILibraryManager libraryManager, INetworkManager networkManager, IUserManager userManager)
public PlayToManager(ILogger logger,IServerConfigurationManager config, ISessionManager sessionManager, IHttpClient httpClient, IItemRepository itemRepository, ILibraryManager libraryManager, INetworkManager networkManager, IUserManager userManager, IDlnaManager dlnaManager)
{
_locations = new ConcurrentDictionary<string, DateTime>();
_tokenSource = new CancellationTokenSource();
@ -46,10 +46,9 @@ namespace MediaBrowser.Dlna.PlayTo
_libraryManager = libraryManager;
_networkManager = networkManager;
_userManager = userManager;
_dlnaManager = dlnaManager;
var path = Path.Combine(config.CommonApplicationPaths.ConfigurationDirectoryPath, "DlnaProfiles.xml");
PlayToConfiguration.Load(path, logger);
}
public async void Start()
@ -221,7 +220,7 @@ namespace MediaBrowser.Dlna.PlayTo
if (device != null && device.RendererCommands != null && !_sessionManager.Sessions.Any(s => string.Equals(s.DeviceId, device.Properties.UUID) && s.IsActive))
{
var transcodeProfiles = TranscodeSetting.GetProfileSettings(device.Properties);
GetProfileSettings(device.Properties);
var sessionInfo = await _sessionManager.LogSessionActivity(device.Properties.ClientType, device.Properties.Name, device.Properties.UUID, device.Properties.DisplayName, uri.OriginalString, null)
.ConfigureAwait(false);
@ -233,27 +232,24 @@ namespace MediaBrowser.Dlna.PlayTo
sessionInfo.SessionController = controller = new PlayToController(sessionInfo, _sessionManager, _itemRepository, _libraryManager, _logger, _networkManager);
}
controller.Init(device, transcodeProfiles);
controller.Init(device);
_logger.Info("DLNA Session created for {0} - {1}", device.Properties.Name, device.Properties.ModelName);
}
}
const string DefaultUser = "Play To";
private async Task<User> GetPlayToUser()
/// <summary>
/// Gets the profile settings.
/// </summary>
/// <param name="deviceProperties">The device properties.</param>
/// <returns>The TranscodeSettings for the device</returns>
private void GetProfileSettings(DeviceInfo deviceProperties)
{
var user = _userManager.Users.FirstOrDefault(u => string.Equals(DefaultUser, u.Name, StringComparison.OrdinalIgnoreCase));
if (user == null)
{
user = await _userManager.CreateUser(DefaultUser);
user.Configuration.IsHidden = true;
user.Configuration.IsAdministrator = false;
user.SaveConfiguration();
}
var profile = _dlnaManager.GetProfile(deviceProperties.DisplayName, deviceProperties.ModelName,
deviceProperties.ModelNumber);
return user;
deviceProperties.DisplayName = profile.Name;
deviceProperties.ClientType = profile.ClientType;
}
/// <summary>

@ -1,5 +1,6 @@
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Plugins;
@ -11,7 +12,7 @@ namespace MediaBrowser.Dlna.PlayTo
{
public class PlayToServerEntryPoint : IServerEntryPoint
{
private PlayToManager _manager;
private PlayToManager _manager;
private readonly IServerConfigurationManager _config;
private readonly ILogger _logger;
private readonly ISessionManager _sessionManager;
@ -20,8 +21,9 @@ namespace MediaBrowser.Dlna.PlayTo
private readonly ILibraryManager _libraryManager;
private readonly INetworkManager _networkManager;
private readonly IUserManager _userManager;
private readonly IDlnaManager _dlnaManager;
public PlayToServerEntryPoint(ILogManager logManager, IServerConfigurationManager config, ISessionManager sessionManager, IHttpClient httpClient, IItemRepository itemRepo, ILibraryManager libraryManager, INetworkManager networkManager, IUserManager userManager)
public PlayToServerEntryPoint(ILogManager logManager, IServerConfigurationManager config, ISessionManager sessionManager, IHttpClient httpClient, IItemRepository itemRepo, ILibraryManager libraryManager, INetworkManager networkManager, IUserManager userManager, IDlnaManager dlnaManager)
{
_config = config;
_sessionManager = sessionManager;
@ -30,6 +32,7 @@ namespace MediaBrowser.Dlna.PlayTo
_libraryManager = libraryManager;
_networkManager = networkManager;
_userManager = userManager;
_dlnaManager = dlnaManager;
_logger = logManager.GetLogger("PlayTo");
}
@ -66,7 +69,7 @@ namespace MediaBrowser.Dlna.PlayTo
{
try
{
_manager = new PlayToManager(_logger, _config, _sessionManager, _httpClient, _itemRepo, _libraryManager, _networkManager, _userManager);
_manager = new PlayToManager(_logger, _config, _sessionManager, _httpClient, _itemRepo, _libraryManager, _networkManager, _userManager, _dlnaManager);
_manager.Start();
}
catch (Exception ex)
@ -96,13 +99,9 @@ namespace MediaBrowser.Dlna.PlayTo
}
}
#region Dispose
public void Dispose()
{
DisposePlayToManager();
}
#endregion
}
}

@ -1,6 +1,9 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Dlna.PlayTo.Configuration;
using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Entities;
using System;
using System.IO;
using System.Linq;
namespace MediaBrowser.Dlna.PlayTo
{
@ -28,84 +31,69 @@ namespace MediaBrowser.Dlna.PlayTo
public long StartPositionTicks { get; set; }
public static PlaylistItem GetBasicConfig(BaseItem item, TranscodeSetting[] profileTranscodings)
public static PlaylistItem Create(BaseItem item, DlnaProfile profile)
{
var playlistItem = new PlaylistItem
{
ItemId = item.Id.ToString()
};
var playlistItem = new PlaylistItem();
playlistItem.ItemId = item.Id.ToString();
if (string.Equals(item.MediaType, Model.Entities.MediaType.Video, StringComparison.OrdinalIgnoreCase))
DlnaProfileType profileType;
if (string.Equals(item.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase))
{
playlistItem.IsVideo = true;
profileType = DlnaProfileType.Video;
}
else
{
playlistItem.IsAudio = true;
profileType = DlnaProfileType.Audio;
}
var path = item.Path;
var path = item.Path.ToLower();
var directPlay = profile.DirectPlayProfiles.FirstOrDefault(i => i.Type == profileType && IsSupported(i, path));
//Check the DlnaProfile associated with the renderer
if (profileTranscodings != null)
if (directPlay != null)
{
foreach (TranscodeSetting transcodeSetting in profileTranscodings)
{
if (string.IsNullOrWhiteSpace(transcodeSetting.Container))
continue;
if (path.EndsWith(transcodeSetting.Container) && !string.IsNullOrWhiteSpace(transcodeSetting.TargetContainer))
{
playlistItem.Transcode = true;
playlistItem.FileFormat = transcodeSetting.TargetContainer;
if (string.IsNullOrWhiteSpace(transcodeSetting.MimeType))
playlistItem.MimeType = transcodeSetting.MimeType;
return playlistItem;
}
if (path.EndsWith(transcodeSetting.Container) && !string.IsNullOrWhiteSpace(transcodeSetting.MimeType))
{
playlistItem.Transcode = false;
playlistItem.FileFormat = transcodeSetting.Container;
playlistItem.MimeType = transcodeSetting.MimeType;
return playlistItem;
}
}
playlistItem.Transcode = false;
playlistItem.FileFormat = Path.GetExtension(path).TrimStart('.');
return playlistItem;
}
if (playlistItem.IsVideo)
{
//Check to see if we support serving the format statically
foreach (string supported in PlayToConfiguration.Instance.SupportedStaticFormats)
{
if (path.EndsWith(supported))
{
playlistItem.Transcode = false;
playlistItem.FileFormat = supported;
return playlistItem;
}
}
var transcodingProfile = profile.TranscodingProfiles.FirstOrDefault(i => i.Type == profileType && IsSupported(profile, i, path));
playlistItem.Transcode = true;
playlistItem.FileFormat = "ts";
}
else
if (transcodingProfile != null)
{
foreach (string supported in PlayToConfiguration.Instance.SupportedStaticFormats)
{
if (path.EndsWith(supported))
{
playlistItem.Transcode = false;
playlistItem.FileFormat = supported;
return playlistItem;
}
}
playlistItem.Transcode = true;
playlistItem.FileFormat = "mp3";
playlistItem.FileFormat = transcodingProfile.Container;
playlistItem.MimeType = transcodingProfile.MimeType;
}
return playlistItem;
}
private static bool IsSupported(DirectPlayProfile profile, string path)
{
// TODO: Support codec list as additional restriction
var mediaContainer = Path.GetExtension(path).TrimStart('.');
if (!profile.Containers.Any(i => string.Equals("." + i.TrimStart('.'), mediaContainer, StringComparison.OrdinalIgnoreCase)))
{
return false;
}
// Placeholder for future conditions
return true;
}
private static bool IsSupported(DlnaProfile profile, TranscodingProfile transcodingProfile, string path)
{
// Placeholder for future conditions
return true;
}
}
}

@ -22,9 +22,9 @@ namespace MediaBrowser.Dlna.PlayTo
_httpClient = httpClient;
}
public async Task<XDocument> SendCommandAsync(string baseUrl, uService service, string command, string postData, string header = null)
public async Task<XDocument> SendCommandAsync(string baseUrl, DeviceService service, string command, string postData, string header = null)
{
var serviceUrl = service.ControlURL;
var serviceUrl = service.ControlUrl;
if (!serviceUrl.StartsWith("/"))
serviceUrl = "/" + serviceUrl;

@ -94,7 +94,7 @@ namespace MediaBrowser.Dlna.PlayTo
/// <param name="streams">The streams.</param>
/// <param name="serverAddress">The server address.</param>
/// <returns>The url to send to the device</returns>
internal static string GetVideoUrl(DeviceProperties deviceProperties, PlaylistItem item, List<MediaStream> streams, string serverAddress)
internal static string GetVideoUrl(DeviceInfo deviceProperties, PlaylistItem item, List<MediaStream> streams, string serverAddress)
{
string dlnaCommand = string.Empty;
if (!item.Transcode)

@ -1,42 +0,0 @@
using System.Xml.Linq;
namespace MediaBrowser.Dlna.PlayTo
{
public class uService
{
public string ServiceType { get; set; }
public string ServiceId { get; set; }
public string SCPDURL { get; set; }
public string ControlURL { get; set; }
public string EventSubURL { get; set; }
public uService(string serviceType, string serviceId, string scpdUrl, string controlUrl, string eventSubUrl)
{
ServiceType = serviceType;
ServiceId = serviceId;
SCPDURL = scpdUrl;
ControlURL = controlUrl;
EventSubURL = eventSubUrl;
}
public static uService Create(XElement element)
{
var type = element.GetDescendantValue(uPnpNamespaces.ud.GetName("serviceType"));
var id = element.GetDescendantValue(uPnpNamespaces.ud.GetName("serviceId"));
var scpdUrl = element.GetDescendantValue(uPnpNamespaces.ud.GetName("SCPDURL"));
var controlURL = element.GetDescendantValue(uPnpNamespaces.ud.GetName("controlURL"));
var eventSubURL = element.GetDescendantValue(uPnpNamespaces.ud.GetName("eventSubURL"));
return new uService(type, id, scpdUrl, controlURL, eventSubURL);
}
public override string ToString()
{
return string.Format("{0}", ServiceId);
}
}
}

@ -57,8 +57,6 @@ namespace MediaBrowser.Model.Configuration
public UnratedItem[] BlockUnratedItems { get; set; }
public bool DisplayMovieFormatRibbons { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="UserConfiguration" /> class.
/// </summary>

@ -11,6 +11,7 @@ using MediaBrowser.Common.Progress;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Collections;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
@ -29,6 +30,7 @@ using MediaBrowser.Controller.Resolvers;
using MediaBrowser.Controller.Session;
using MediaBrowser.Controller.Sorting;
using MediaBrowser.Controller.Themes;
using MediaBrowser.Dlna;
using MediaBrowser.Dlna.PlayTo;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.MediaInfo;
@ -490,6 +492,9 @@ namespace MediaBrowser.ServerApplication
var appThemeManager = new AppThemeManager(ApplicationPaths, FileSystemManager, JsonSerializer, Logger);
RegisterSingleInstance<IAppThemeManager>(appThemeManager);
var dlnaManager = new DlnaManager();
RegisterSingleInstance<IDlnaManager>(dlnaManager);
var collectionManager = new CollectionManager(LibraryManager, FileSystemManager, LibraryMonitor);
RegisterSingleInstance<ICollectionManager>(collectionManager);

Loading…
Cancel
Save