aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Dlna
diff options
context:
space:
mode:
authorhatharry <hatharry@hotmail.com>2016-10-11 17:21:21 +1300
committerhatharry <hatharry@hotmail.com>2016-10-11 17:21:21 +1300
commitd6862cefd83e3733a7a459ffd7cec616db006c22 (patch)
treea712bbef2227b60d8d870898e4205328fbf02484 /MediaBrowser.Dlna
parent91225bc9688327e89224c91651dcec7eafa05234 (diff)
parent9b0ac4bde5beb74703a258d582f477c6411ec6ec (diff)
Merge branch 'dev' of https://github.com/hatharry/Emby.git
Diffstat (limited to 'MediaBrowser.Dlna')
-rw-r--r--MediaBrowser.Dlna/ContentDirectory/ContentDirectoryBrowser.cs3
-rw-r--r--MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs61
-rw-r--r--MediaBrowser.Dlna/Didl/DidlBuilder.cs6
-rw-r--r--MediaBrowser.Dlna/Eventing/EventManager.cs4
-rw-r--r--MediaBrowser.Dlna/Main/DlnaEntryPoint.cs113
-rw-r--r--MediaBrowser.Dlna/MediaBrowser.Dlna.csproj15
-rw-r--r--MediaBrowser.Dlna/PlayTo/Device.cs4
-rw-r--r--MediaBrowser.Dlna/PlayTo/PlayToController.cs23
-rw-r--r--MediaBrowser.Dlna/PlayTo/PlayToManager.cs26
-rw-r--r--MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs9
-rw-r--r--MediaBrowser.Dlna/Profiles/PanasonicVieraProfile.cs2
-rw-r--r--MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs6
-rw-r--r--MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2013.cs2
-rw-r--r--MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2014.cs2
-rw-r--r--MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2015.cs2
-rw-r--r--MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2016.cs2
-rw-r--r--MediaBrowser.Dlna/Profiles/WdtvLiveProfile.cs10
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml2
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml6
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml2
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2014.xml2
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2015.xml2
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2016.xml2
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml10
-rw-r--r--MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs217
-rw-r--r--MediaBrowser.Dlna/Ssdp/SsdpHandler.cs383
-rw-r--r--MediaBrowser.Dlna/Ssdp/SsdpHelper.cs45
27 files changed, 219 insertions, 742 deletions
diff --git a/MediaBrowser.Dlna/ContentDirectory/ContentDirectoryBrowser.cs b/MediaBrowser.Dlna/ContentDirectory/ContentDirectoryBrowser.cs
index 77b0a70fd0..2618873669 100644
--- a/MediaBrowser.Dlna/ContentDirectory/ContentDirectoryBrowser.cs
+++ b/MediaBrowser.Dlna/ContentDirectory/ContentDirectoryBrowser.cs
@@ -34,7 +34,8 @@ namespace MediaBrowser.Dlna.ContentDirectory
UserAgent = "Emby",
RequestContentType = "text/xml; charset=\"utf-8\"",
LogErrorResponseBody = true,
- Url = request.ContentDirectoryUrl
+ Url = request.ContentDirectoryUrl,
+ BufferContent = false
};
options.RequestHeaders["SOAPACTION"] = "urn:schemas-upnp-org:service:ContentDirectory:1#Browse";
diff --git a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs
index 9b5030325a..3d1e073f8e 100644
--- a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs
+++ b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs
@@ -428,14 +428,6 @@ namespace MediaBrowser.Dlna.ContentDirectory
return ApplyPaging(result, startIndex, limit);
}
- if (stubType.Value == StubType.Folder)
- {
- var movie = item as Movie;
- if (movie != null)
- {
- return ApplyPaging(await GetMovieItems(movie).ConfigureAwait(false), startIndex, limit);
- }
- }
var person = item as Person;
if (person != null)
@@ -468,14 +460,11 @@ namespace MediaBrowser.Dlna.ContentDirectory
}).ConfigureAwait(false);
- var options = _config.GetDlnaConfiguration();
-
var serverItems = queryResult
.Items
.Select(i => new ServerItem
{
- Item = i,
- StubType = GetDisplayStubType(i, item, options)
+ Item = i
})
.ToArray();
@@ -519,29 +508,6 @@ namespace MediaBrowser.Dlna.ContentDirectory
return result;
}
- private StubType? GetDisplayStubType(BaseItem item, BaseItem context, DlnaOptions options)
- {
- if (context == null || context.IsFolder)
- {
- var movie = item as Movie;
- if (movie != null && options.EnableMovieFolders)
- {
- if (movie.GetTrailerIds().Count > 0 ||
- movie.SpecialFeatureIds.Count > 0)
- {
- return StubType.Folder;
- }
-
- if (EnablePeopleDisplay(item))
- {
- return StubType.Folder;
- }
- }
- }
-
- return null;
- }
-
private bool EnablePeopleDisplay(BaseItem item)
{
if (_libraryManager.GetPeopleNames(new InternalPeopleQuery
@@ -556,31 +522,6 @@ namespace MediaBrowser.Dlna.ContentDirectory
return false;
}
- private Task<QueryResult<ServerItem>> GetMovieItems(Movie item)
- {
- var list = new List<BaseItem>();
-
- list.Add(item);
-
- list.AddRange(item.GetTrailerIds().Select(i => _libraryManager.GetItemById(i)).Where(i => i != null));
- list.AddRange(item.SpecialFeatureIds.Select(i => _libraryManager.GetItemById(i)).Where(i => i != null));
-
- var serverItems = list.Select(i => new ServerItem { Item = i, StubType = null })
- .ToList();
-
- serverItems.Add(new ServerItem
- {
- Item = item,
- StubType = StubType.People
- });
-
- return Task.FromResult(new QueryResult<ServerItem>
- {
- Items = serverItems.ToArray(),
- TotalRecordCount = serverItems.Count
- });
- }
-
private ServerItem GetItemFromObjectId(string id, User user)
{
return DidlBuilder.IsIdRoot(id)
diff --git a/MediaBrowser.Dlna/Didl/DidlBuilder.cs b/MediaBrowser.Dlna/Didl/DidlBuilder.cs
index 84c1b3bdee..f53dec3bff 100644
--- a/MediaBrowser.Dlna/Didl/DidlBuilder.cs
+++ b/MediaBrowser.Dlna/Didl/DidlBuilder.cs
@@ -177,7 +177,8 @@ namespace MediaBrowser.Dlna.Didl
streamInfo.TargetRefFrames,
streamInfo.TargetVideoStreamCount,
streamInfo.TargetAudioStreamCount,
- streamInfo.TargetVideoCodecTag);
+ streamInfo.TargetVideoCodecTag,
+ streamInfo.IsTargetAVC);
foreach (var contentFeature in contentFeatureList)
{
@@ -322,7 +323,8 @@ namespace MediaBrowser.Dlna.Didl
streamInfo.TargetRefFrames,
streamInfo.TargetVideoStreamCount,
streamInfo.TargetAudioStreamCount,
- streamInfo.TargetVideoCodecTag);
+ streamInfo.TargetVideoCodecTag,
+ streamInfo.IsTargetAVC);
var filename = url.Substring(0, url.IndexOf('?'));
diff --git a/MediaBrowser.Dlna/Eventing/EventManager.cs b/MediaBrowser.Dlna/Eventing/EventManager.cs
index 65e742d498..51c8d2d919 100644
--- a/MediaBrowser.Dlna/Eventing/EventManager.cs
+++ b/MediaBrowser.Dlna/Eventing/EventManager.cs
@@ -141,7 +141,8 @@ namespace MediaBrowser.Dlna.Eventing
{
RequestContent = builder.ToString(),
RequestContentType = "text/xml",
- Url = subscription.CallbackUrl
+ Url = subscription.CallbackUrl,
+ BufferContent = false
};
options.RequestHeaders.Add("NT", subscription.NotificationType);
@@ -155,7 +156,6 @@ namespace MediaBrowser.Dlna.Eventing
}
catch (OperationCanceledException)
{
- throw;
}
catch
{
diff --git a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs
index 9f2726b315..a8aedaed87 100644
--- a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs
+++ b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs
@@ -14,8 +14,11 @@ using MediaBrowser.Dlna.Ssdp;
using MediaBrowser.Model.Logging;
using System;
using System.Collections.Generic;
+using System.Linq;
+using System.Net;
using System.Threading.Tasks;
using MediaBrowser.Controller.MediaEncoding;
+using Rssdp;
namespace MediaBrowser.Dlna.Main
{
@@ -38,12 +41,11 @@ namespace MediaBrowser.Dlna.Main
private readonly IMediaSourceManager _mediaSourceManager;
private readonly IMediaEncoder _mediaEncoder;
- private readonly SsdpHandler _ssdpHandler;
private readonly IDeviceDiscovery _deviceDiscovery;
- private readonly List<string> _registeredServerIds = new List<string>();
private bool _ssdpHandlerStarted;
private bool _dlnaServerStarted;
+ private SsdpDevicePublisher _Publisher;
public DlnaEntryPoint(IServerConfigurationManager config,
ILogManager logManager,
@@ -58,7 +60,7 @@ namespace MediaBrowser.Dlna.Main
IUserDataManager userDataManager,
ILocalizationManager localization,
IMediaSourceManager mediaSourceManager,
- ISsdpHandler ssdpHandler, IDeviceDiscovery deviceDiscovery, IMediaEncoder mediaEncoder)
+ IDeviceDiscovery deviceDiscovery, IMediaEncoder mediaEncoder)
{
_config = config;
_appHost = appHost;
@@ -74,7 +76,6 @@ namespace MediaBrowser.Dlna.Main
_mediaSourceManager = mediaSourceManager;
_deviceDiscovery = deviceDiscovery;
_mediaEncoder = mediaEncoder;
- _ssdpHandler = (SsdpHandler)ssdpHandler;
_logger = logManager.GetLogger("Dlna");
}
@@ -110,18 +111,6 @@ namespace MediaBrowser.Dlna.Main
{
var options = _config.GetDlnaConfiguration();
- if (!options.EnableServer && !options.EnablePlayTo && !_config.Configuration.EnableUPnP)
- {
- if (_ssdpHandlerStarted)
- {
- // Sat/ip live tv depends on device discovery, as well as hd homerun detection
- // In order to allow this to be disabled, we need a modular way of knowing if there are
- // any parts of the system that are dependant on it
- // DisposeSsdpHandler();
- }
- return;
- }
-
if (!_ssdpHandlerStarted)
{
StartSsdpHandler();
@@ -154,7 +143,7 @@ namespace MediaBrowser.Dlna.Main
{
try
{
- _ssdpHandler.Start();
+ StartPublishing();
_ssdpHandlerStarted = true;
StartDeviceDiscovery();
@@ -165,13 +154,16 @@ namespace MediaBrowser.Dlna.Main
}
}
+ private void StartPublishing()
+ {
+ _Publisher = new SsdpDevicePublisher();
+ }
+
private void StartDeviceDiscovery()
{
try
{
- ((DeviceDiscovery)_deviceDiscovery).Start(_ssdpHandler);
-
- //DlnaChannel.Current.Start(() => _registeredServerIds.ToList());
+ ((DeviceDiscovery)_deviceDiscovery).Start();
}
catch (Exception ex)
{
@@ -199,8 +191,6 @@ namespace MediaBrowser.Dlna.Main
{
((DeviceDiscovery)_deviceDiscovery).Dispose();
- _ssdpHandler.Dispose();
-
_ssdpHandlerStarted = false;
}
catch (Exception ex)
@@ -225,7 +215,17 @@ namespace MediaBrowser.Dlna.Main
private async Task RegisterServerEndpoints()
{
- foreach (var address in await _appHost.GetLocalIpAddresses().ConfigureAwait(false))
+ if (!_config.GetDlnaConfiguration().BlastAliveMessages)
+ {
+ return;
+ }
+
+ var cacheLength = _config.GetDlnaConfiguration().BlastAliveMessageIntervalSeconds;
+ _Publisher.SupportPnpRootDevice = false;
+
+ var addresses = (await _appHost.GetLocalIpAddresses().ConfigureAwait(false)).ToList();
+
+ foreach (var address in addresses)
{
//if (IPAddress.IsLoopback(address))
//{
@@ -234,25 +234,46 @@ namespace MediaBrowser.Dlna.Main
//}
var addressString = address.ToString();
- var udn = addressString.GetMD5().ToString("N");
-
- var descriptorURI = "/dlna/" + udn + "/description.xml";
- var uri = new Uri(_appHost.GetLocalApiUrl(address) + descriptorURI);
+ var udn = (addressString).GetMD5().ToString("N");
var services = new List<string>
{
- "upnp:rootdevice",
"urn:schemas-upnp-org:device:MediaServer:1",
"urn:schemas-upnp-org:service:ContentDirectory:1",
"urn:schemas-upnp-org:service:ConnectionManager:1",
- "urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:1",
- "uuid:" + udn
+ "urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:1"
};
- _ssdpHandler.RegisterNotification(udn, uri, address, services);
+ foreach (var fullService in services)
+ {
+ _logger.Info("Registering publisher for {0} on {1}", fullService, addressString);
+
+ var descriptorURI = "/dlna/" + udn + "/description.xml";
+ var uri = new Uri(_appHost.GetLocalApiUrl(address) + descriptorURI);
+
+ var service = fullService.Replace("urn:", string.Empty).Replace(":1", string.Empty);
+
+ var serviceParts = service.Split(':');
+
+ var deviceTypeNamespace = serviceParts[0].Replace('.', '-');
- _registeredServerIds.Add(udn);
+ var device = new SsdpRootDevice
+ {
+ CacheLifetime = TimeSpan.FromSeconds(cacheLength), //How long SSDP clients can cache this info.
+ Location = uri, // Must point to the URL that serves your devices UPnP description document.
+ DeviceTypeNamespace = deviceTypeNamespace,
+ DeviceClass = serviceParts[1],
+ DeviceType = serviceParts[2],
+ FriendlyName = "Emby Server",
+ Manufacturer = "Emby",
+ ModelName = "Emby Server",
+ Uuid = udn
+ // This must be a globally unique value that survives reboots etc. Get from storage or embedded hardware etc.
+ };
+
+ _Publisher.AddDevice(device);
+ }
}
}
@@ -315,19 +336,25 @@ namespace MediaBrowser.Dlna.Main
public void DisposeDlnaServer()
{
- foreach (var id in _registeredServerIds)
+ if (_Publisher != null)
{
- try
- {
- _ssdpHandler.UnregisterNotification(id);
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error unregistering server", ex);
- }
- }
+ var devices = _Publisher.Devices.ToList();
+ var tasks = devices.Select(i => _Publisher.RemoveDevice(i)).ToArray();
- _registeredServerIds.Clear();
+ Task.WaitAll(tasks);
+ //foreach (var device in devices)
+ //{
+ // try
+ // {
+ // _Publisher.RemoveDevice(device);
+ // }
+ // catch (Exception ex)
+ // {
+ // _logger.ErrorException("Error sending bye bye", ex);
+ // }
+ //}
+ _Publisher.Dispose();
+ }
_dlnaServerStarted = false;
}
diff --git a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj
index d10a5f7b5a..ef60be227f 100644
--- a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj
+++ b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -14,6 +14,7 @@
<SchemaVersion>2.0</SchemaVersion>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
+ <TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -23,7 +24,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
- <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
@@ -32,7 +33,7 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
- <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release Mono|AnyCPU' ">
<Optimize>false</Optimize>
@@ -50,8 +51,15 @@
<Reference Include="Patterns.Logging">
<HintPath>..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll</HintPath>
</Reference>
+ <Reference Include="Rssdp.NetFx40">
+ <HintPath>..\ThirdParty\rssdp\Rssdp.NetFx40.dll</HintPath>
+ </Reference>
+ <Reference Include="Rssdp.Portable">
+ <HintPath>..\ThirdParty\rssdp\Rssdp.Portable.dll</HintPath>
+ </Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
+ <Reference Include="System.Net.Http" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
@@ -125,7 +133,6 @@
<Compile Include="Ssdp\Datagram.cs" />
<Compile Include="Server\DescriptionXmlBuilder.cs" />
<Compile Include="Ssdp\DeviceDiscovery.cs" />
- <Compile Include="Ssdp\SsdpHelper.cs" />
<Compile Include="PlayTo\SsdpHttpClient.cs" />
<Compile Include="Common\StateVariable.cs" />
<Compile Include="PlayTo\TransportCommands.cs" />
diff --git a/MediaBrowser.Dlna/PlayTo/Device.cs b/MediaBrowser.Dlna/PlayTo/Device.cs
index 174ca871a4..b656bc66ec 100644
--- a/MediaBrowser.Dlna/PlayTo/Device.cs
+++ b/MediaBrowser.Dlna/PlayTo/Device.cs
@@ -474,7 +474,7 @@ namespace MediaBrowser.Dlna.PlayTo
if (_disposed)
return;
- _logger.ErrorException("Error updating device info for {0}", ex, Properties.Name);
+ //_logger.ErrorException("Error updating device info for {0}", ex, Properties.Name);
_successiveStopCount++;
_connectFailureCount++;
@@ -483,7 +483,9 @@ namespace MediaBrowser.Dlna.PlayTo
{
if (OnDeviceUnavailable != null)
{
+ _logger.Debug("Disposing device due to loss of connection");
OnDeviceUnavailable();
+ return;
}
}
if (_successiveStopCount >= maxSuccessiveStopReturns)
diff --git a/MediaBrowser.Dlna/PlayTo/PlayToController.cs b/MediaBrowser.Dlna/PlayTo/PlayToController.cs
index 5622885fc7..f6b24e6157 100644
--- a/MediaBrowser.Dlna/PlayTo/PlayToController.cs
+++ b/MediaBrowser.Dlna/PlayTo/PlayToController.cs
@@ -19,6 +19,7 @@ using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.MediaEncoding;
+using MediaBrowser.Model.Events;
namespace MediaBrowser.Dlna.PlayTo
{
@@ -122,16 +123,18 @@ namespace MediaBrowser.Dlna.PlayTo
}
}
- void _deviceDiscovery_DeviceLeft(object sender, SsdpMessageEventArgs e)
+ void _deviceDiscovery_DeviceLeft(object sender, GenericEventArgs<UpnpDeviceInfo> e)
{
+ var info = e.Argument;
+
string nts;
- e.Headers.TryGetValue("NTS", out nts);
+ info.Headers.TryGetValue("NTS", out nts);
string usn;
- if (!e.Headers.TryGetValue("USN", out usn)) usn = String.Empty;
+ if (!info.Headers.TryGetValue("USN", out usn)) usn = String.Empty;
string nt;
- if (!e.Headers.TryGetValue("NT", out nt)) nt = String.Empty;
+ if (!info.Headers.TryGetValue("NT", out nt)) nt = String.Empty;
if (usn.IndexOf(_device.Properties.UUID, StringComparison.OrdinalIgnoreCase) != -1 &&
!_disposed)
@@ -537,7 +540,8 @@ namespace MediaBrowser.Dlna.PlayTo
streamInfo.TargetRefFrames,
streamInfo.TargetVideoStreamCount,
streamInfo.TargetAudioStreamCount,
- streamInfo.TargetVideoCodecTag);
+ streamInfo.TargetVideoCodecTag,
+ streamInfo.IsTargetAVC);
return list.FirstOrDefault();
}
@@ -653,7 +657,7 @@ namespace MediaBrowser.Dlna.PlayTo
_device.PlaybackProgress -= _device_PlaybackProgress;
_device.PlaybackStopped -= _device_PlaybackStopped;
_device.MediaChanged -= _device_MediaChanged;
- _deviceDiscovery.DeviceLeft -= _deviceDiscovery_DeviceLeft;
+ //_deviceDiscovery.DeviceLeft -= _deviceDiscovery_DeviceLeft;
_device.OnDeviceUnavailable = null;
_device.Dispose();
@@ -824,6 +828,7 @@ namespace MediaBrowser.Dlna.PlayTo
public string DeviceId { get; set; }
public string MediaSourceId { get; set; }
+ public string LiveStreamId { get; set; }
public BaseItem Item { get; set; }
public MediaSourceInfo MediaSource { get; set; }
@@ -907,6 +912,10 @@ namespace MediaBrowser.Dlna.PlayTo
{
request.StartPositionTicks = long.Parse(val, CultureInfo.InvariantCulture);
}
+ else if (i == 22)
+ {
+ request.LiveStreamId = val;
+ }
}
request.Item = string.IsNullOrWhiteSpace(request.ItemId)
@@ -917,7 +926,7 @@ namespace MediaBrowser.Dlna.PlayTo
request.MediaSource = hasMediaSources == null
? null
- : (await mediaSourceManager.GetMediaSource(hasMediaSources, request.MediaSourceId, false).ConfigureAwait(false));
+ : (await mediaSourceManager.GetMediaSource(hasMediaSources, request.MediaSourceId, request.LiveStreamId, false, CancellationToken.None).ConfigureAwait(false));
return request;
}
diff --git a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs
index cd9a7b1f0c..6d6986f017 100644
--- a/MediaBrowser.Dlna/PlayTo/PlayToManager.cs
+++ b/MediaBrowser.Dlna/PlayTo/PlayToManager.cs
@@ -12,7 +12,9 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
+using System.Threading.Tasks;
using MediaBrowser.Controller.MediaEncoding;
+using MediaBrowser.Model.Events;
namespace MediaBrowser.Dlna.PlayTo
{
@@ -61,16 +63,17 @@ namespace MediaBrowser.Dlna.PlayTo
_deviceDiscovery.DeviceDiscovered += _deviceDiscovery_DeviceDiscovered;
}
- async void _deviceDiscovery_DeviceDiscovered(object sender, SsdpMessageEventArgs e)
+ async void _deviceDiscovery_DeviceDiscovered(object sender, GenericEventArgs<UpnpDeviceInfo> e)
{
+ var info = e.Argument;
+
string usn;
- if (!e.Headers.TryGetValue("USN", out usn)) usn = string.Empty;
+ if (!info.Headers.TryGetValue("USN", out usn)) usn = string.Empty;
string nt;
- if (!e.Headers.TryGetValue("NT", out nt)) nt = string.Empty;
+ if (!info.Headers.TryGetValue("NT", out nt)) nt = string.Empty;
- string location;
- if (!e.Headers.TryGetValue("Location", out location)) location = string.Empty;
+ string location = info.Location.ToString();
// It has to report that it's a media renderer
if (usn.IndexOf("MediaRenderer:", StringComparison.OrdinalIgnoreCase) == -1 &&
@@ -100,7 +103,7 @@ namespace MediaBrowser.Dlna.PlayTo
}
}
- var uri = new Uri(location);
+ var uri = info.Location;
_logger.Debug("Attempting to create PlayToController from location {0}", location);
var device = await Device.CreateuPnpDeviceAsync(uri, _httpClient, _config, _logger).ConfigureAwait(false);
@@ -121,7 +124,7 @@ namespace MediaBrowser.Dlna.PlayTo
if (controller == null)
{
- var serverAddress = GetServerAddress(e.LocalEndPoint.Address);
+ var serverAddress = await GetServerAddress(info.LocalEndPoint == null ? null : info.LocalEndPoint.Address).ConfigureAwait(false);
string accessToken = null;
sessionInfo.SessionController = controller = new PlayToController(sessionInfo,
@@ -173,9 +176,14 @@ namespace MediaBrowser.Dlna.PlayTo
}
}
- private string GetServerAddress(IPAddress localIp)
+ private Task<string> GetServerAddress(IPAddress localIp)
{
- return _appHost.GetLocalApiUrl(localIp);
+ if (localIp == null)
+ {
+ return _appHost.GetLocalApiUrl();
+ }
+
+ return Task.FromResult(_appHost.GetLocalApiUrl(localIp));
}
public void Dispose()
diff --git a/MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs b/MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs
index ff4223c72c..a1eb19d9aa 100644
--- a/MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs
+++ b/MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs
@@ -70,7 +70,8 @@ namespace MediaBrowser.Dlna.PlayTo
{
Url = url,
UserAgent = USERAGENT,
- LogErrorResponseBody = true
+ LogErrorResponseBody = true,
+ BufferContent = false
};
options.RequestHeaders["HOST"] = ip + ":" + port.ToString(_usCulture);
@@ -87,7 +88,8 @@ namespace MediaBrowser.Dlna.PlayTo
{
Url = url,
UserAgent = USERAGENT,
- LogErrorResponseBody = true
+ LogErrorResponseBody = true,
+ BufferContent = false
};
options.RequestHeaders["FriendlyName.DLNA.ORG"] = FriendlyName;
@@ -115,7 +117,8 @@ namespace MediaBrowser.Dlna.PlayTo
Url = url,
UserAgent = USERAGENT,
LogRequest = logRequest || _config.GetDlnaConfiguration().EnableDebugLog,
- LogErrorResponseBody = true
+ LogErrorResponseBody = true,
+ BufferContent = false
};
options.RequestHeaders["SOAPAction"] = soapAction;
diff --git a/MediaBrowser.Dlna/Profiles/PanasonicVieraProfile.cs b/MediaBrowser.Dlna/Profiles/PanasonicVieraProfile.cs
index 7b0f18fa68..5edf3afbfe 100644
--- a/MediaBrowser.Dlna/Profiles/PanasonicVieraProfile.cs
+++ b/MediaBrowser.Dlna/Profiles/PanasonicVieraProfile.cs
@@ -66,7 +66,7 @@ namespace MediaBrowser.Dlna.Profiles
{
Container = "mkv",
VideoCodec = "h264,mpeg2video",
- AudioCodec = "aac,ac3,dca,mp3,mp2,pcm",
+ AudioCodec = "aac,ac3,dca,mp3,mp2,pcm,dts",
Type = DlnaProfileType.Video
},
diff --git a/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs b/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs
index 63fcf60ecc..aae520d6f0 100644
--- a/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs
+++ b/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs
@@ -65,14 +65,14 @@ namespace MediaBrowser.Dlna.Profiles
{
Container = "avi",
VideoCodec = "h264,mpeg4,mjpeg",
- AudioCodec = "mp3,ac3,dca",
+ AudioCodec = "mp3,ac3,dca,dts",
Type = DlnaProfileType.Video
},
new DirectPlayProfile
{
Container = "mkv",
VideoCodec = "h264,mpeg4,mjpeg4",
- AudioCodec = "mp3,ac3,dca,aac",
+ AudioCodec = "mp3,ac3,dca,aac,dts",
Type = DlnaProfileType.Video
},
new DirectPlayProfile
@@ -300,7 +300,7 @@ namespace MediaBrowser.Dlna.Profiles
new CodecProfile
{
Type = CodecType.VideoAudio,
- Codec = "ac3,wmav2,dca,aac,mp3",
+ Codec = "ac3,wmav2,dca,aac,mp3,dts",
Conditions = new[]
{
diff --git a/MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2013.cs b/MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2013.cs
index bbdf370b8b..fefb961171 100644
--- a/MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2013.cs
+++ b/MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2013.cs
@@ -115,7 +115,7 @@ namespace MediaBrowser.Dlna.Profiles
{
Container = "mkv",
VideoCodec = "mpeg4,h264",
- AudioCodec = "ac3,dca,aac,mp3,pcm",
+ AudioCodec = "ac3,dca,aac,mp3,pcm,dts",
Type = DlnaProfileType.Video
},
new DirectPlayProfile
diff --git a/MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2014.cs b/MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2014.cs
index 1eed398edb..4f2ff3ad15 100644
--- a/MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2014.cs
+++ b/MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2014.cs
@@ -115,7 +115,7 @@ namespace MediaBrowser.Dlna.Profiles
{
Container = "mkv",
VideoCodec = "mpeg4,h264",
- AudioCodec = "ac3,dca,aac,mp3,pcm",
+ AudioCodec = "ac3,dca,aac,mp3,pcm,dts",
Type = DlnaProfileType.Video
},
new DirectPlayProfile
diff --git a/MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2015.cs b/MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2015.cs
index 563c2db7b5..57cd5dad67 100644
--- a/MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2015.cs
+++ b/MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2015.cs
@@ -103,7 +103,7 @@ namespace MediaBrowser.Dlna.Profiles
{
Container = "mkv",
VideoCodec = "mpeg4,h264",
- AudioCodec = "ac3,dca,aac,mp3,pcm",
+ AudioCodec = "ac3,dca,aac,mp3,pcm,dts",
Type = DlnaProfileType.Video
},
new DirectPlayProfile
diff --git a/MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2016.cs b/MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2016.cs
index 21e0c092cd..f504820d14 100644
--- a/MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2016.cs
+++ b/MediaBrowser.Dlna/Profiles/SonyBlurayPlayer2016.cs
@@ -103,7 +103,7 @@ namespace MediaBrowser.Dlna.Profiles
{
Container = "mkv",
VideoCodec = "mpeg4,h264",
- AudioCodec = "ac3,dca,aac,mp3,pcm",
+ AudioCodec = "ac3,dca,aac,mp3,pcm,dts",
Type = DlnaProfileType.Video
},
new DirectPlayProfile
diff --git a/MediaBrowser.Dlna/Profiles/WdtvLiveProfile.cs b/MediaBrowser.Dlna/Profiles/WdtvLiveProfile.cs
index 1c0c7d2979..5f9e30318f 100644
--- a/MediaBrowser.Dlna/Profiles/WdtvLiveProfile.cs
+++ b/MediaBrowser.Dlna/Profiles/WdtvLiveProfile.cs
@@ -58,7 +58,7 @@ namespace MediaBrowser.Dlna.Profiles
Container = "avi",
Type = DlnaProfileType.Video,
VideoCodec = "mpeg1video,mpeg2video,mpeg4,h264,vc1",
- AudioCodec = "ac3,dca,mp2,mp3,pcm,dca"
+ AudioCodec = "ac3,dca,mp2,mp3,pcm,dts"
},
new DirectPlayProfile
@@ -66,7 +66,7 @@ namespace MediaBrowser.Dlna.Profiles
Container = "mpeg",
Type = DlnaProfileType.Video,
VideoCodec = "mpeg1video,mpeg2video",
- AudioCodec = "ac3,dca,mp2,mp3,pcm,dca"
+ AudioCodec = "ac3,dca,mp2,mp3,pcm,dts"
},
new DirectPlayProfile
@@ -74,7 +74,7 @@ namespace MediaBrowser.Dlna.Profiles
Container = "mkv",
Type = DlnaProfileType.Video,
VideoCodec = "mpeg1video,mpeg2video,mpeg4,h264,vc1",
- AudioCodec = "ac3,dca,aac,mp2,mp3,pcm,dca"
+ AudioCodec = "ac3,dca,aac,mp2,mp3,pcm,dts"
},
new DirectPlayProfile
@@ -82,7 +82,7 @@ namespace MediaBrowser.Dlna.Profiles
Container = "ts,m2ts",
Type = DlnaProfileType.Video,
VideoCodec = "mpeg1video,mpeg2video,h264,vc1",
- AudioCodec = "ac3,dca,mp2,mp3,aac,dca"
+ AudioCodec = "ac3,dca,mp2,mp3,aac,dts"
},
new DirectPlayProfile
@@ -90,7 +90,7 @@ namespace MediaBrowser.Dlna.Profiles
Container = "mp4,mov",
Type = DlnaProfileType.Video,
VideoCodec = "h264,mpeg4",
- AudioCodec = "ac3,aac,mp2,mp3,dca"
+ AudioCodec = "ac3,aac,mp2,mp3,dca,dts"
},
new DirectPlayProfile
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml b/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml
index 865449cb69..d26346ff63 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml
@@ -39,7 +39,7 @@
</XmlRootAttributes>
<DirectPlayProfiles>
<DirectPlayProfile container="mpeg,mpg" audioCodec="ac3,mp3,pcm_dvd" videoCodec="mpeg2video,mpeg4" type="Video" />
- <DirectPlayProfile container="mkv" audioCodec="aac,ac3,dca,mp3,mp2,pcm" videoCodec="h264,mpeg2video" type="Video" />
+ <DirectPlayProfile container="mkv" audioCodec="aac,ac3,dca,mp3,mp2,pcm,dts" videoCodec="h264,mpeg2video" type="Video" />
<DirectPlayProfile container="ts" audioCodec="aac,mp3,mp2" videoCodec="h264,mpeg2video" type="Video" />
<DirectPlayProfile container="mp4" audioCodec="aac,ac3,mp3,pcm" videoCodec="h264" type="Video" />
<DirectPlayProfile container="mov" audioCodec="aac,pcm" videoCodec="h264" type="Video" />
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml b/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml
index 77fa928cca..1918c02976 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml
@@ -38,8 +38,8 @@
</XmlRootAttributes>
<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="avi" audioCodec="mp3,ac3,dca,dts" videoCodec="h264,mpeg4,mjpeg" type="Video" />
+ <DirectPlayProfile container="mkv" audioCodec="mp3,ac3,dca,aac,dts" videoCodec="h264,mpeg4,mjpeg4" type="Video" />
<DirectPlayProfile container="mp4" audioCodec="mp3,aac" videoCodec="h264,mpeg4" type="Video" />
<DirectPlayProfile container="3gp" audioCodec="aac,he-aac" videoCodec="h264,mpeg4" type="Video" />
<DirectPlayProfile container="mpg,mpeg" audioCodec="ac3,mp2,mp3,aac" videoCodec="mpeg1video,mpeg2video,h264" type="Video" />
@@ -100,7 +100,7 @@
</Conditions>
<ApplyConditions />
</CodecProfile>
- <CodecProfile type="VideoAudio" codec="ac3,wmav2,dca,aac,mp3">
+ <CodecProfile type="VideoAudio" codec="ac3,wmav2,dca,aac,mp3,dts">
<Conditions>
<ProfileCondition condition="LessThanEqual" property="AudioChannels" value="6" isRequired="true" />
</Conditions>
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml
index 1c626d3d55..f8b583b50f 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml
@@ -45,7 +45,7 @@
<DirectPlayProfile container="mpeg,mpg" audioCodec="ac3,mp3,mp2,pcm" videoCodec="mpeg1video,mpeg2video" type="Video" />
<DirectPlayProfile container="mp4,m4v" 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="mkv" audioCodec="ac3,dca,aac,mp3,pcm,dts" videoCodec="mpeg4,h264" type="Video" />
<DirectPlayProfile container="m2ts,mts" audioCodec="aac,mp3,ac3,dca,dts" videoCodec="h264,mpeg4,vc1" type="Video" />
<DirectPlayProfile container="wmv,asf" type="Video" />
<DirectPlayProfile container="mp3,m4a,wma,wav" type="Audio" />
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2014.xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2014.xml
index bb55a1a806..eaa37c6205 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2014.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2014.xml
@@ -45,7 +45,7 @@
<DirectPlayProfile container="mpeg,mpg" audioCodec="ac3,mp3,mp2,pcm" videoCodec="mpeg1video,mpeg2video" type="Video" />
<DirectPlayProfile container="mp4,m4v" 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="mkv" audioCodec="ac3,dca,aac,mp3,pcm,dts" videoCodec="mpeg4,h264" type="Video" />
<DirectPlayProfile container="m2ts,mts" audioCodec="aac,mp3,ac3,dca,dts" videoCodec="h264,mpeg4,vc1" type="Video" />
<DirectPlayProfile container="wmv,asf" type="Video" />
<DirectPlayProfile container="mp3,m4a,wma,wav" type="Audio" />
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2015.xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2015.xml
index 804770a597..368e892ff2 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2015.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2015.xml
@@ -43,7 +43,7 @@
<DirectPlayProfile container="mpeg,mpg" audioCodec="ac3,mp3,mp2,pcm" videoCodec="mpeg1video,mpeg2video" type="Video" />
<DirectPlayProfile container="mp4,m4v" 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="mkv" audioCodec="ac3,dca,aac,mp3,pcm,dts" videoCodec="mpeg4,h264" type="Video" />
<DirectPlayProfile container="m2ts,mts" audioCodec="aac,mp3,ac3,dca,dts" videoCodec="h264,mpeg4,vc1" type="Video" />
<DirectPlayProfile container="wmv,asf" type="Video" />
<DirectPlayProfile container="mp3,m4a,wma,wav" type="Audio" />
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2016.xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2016.xml
index 920b6ccfa2..9ec096b7f4 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2016.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2016.xml
@@ -43,7 +43,7 @@
<DirectPlayProfile container="mpeg,mpg" audioCodec="ac3,mp3,mp2,pcm" videoCodec="mpeg1video,mpeg2video" type="Video" />
<DirectPlayProfile container="mp4,m4v" 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="mkv" audioCodec="ac3,dca,aac,mp3,pcm,dts" videoCodec="mpeg4,h264" type="Video" />
<DirectPlayProfile container="m2ts,mts" audioCodec="aac,mp3,ac3,dca,dts" videoCodec="h264,mpeg4,vc1" type="Video" />
<DirectPlayProfile container="wmv,asf" type="Video" />
<DirectPlayProfile container="mp3,m4a,wma,wav" type="Audio" />
diff --git a/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml b/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml
index ef8fa57578..ebd4eb9b58 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml
@@ -36,11 +36,11 @@
<IgnoreTranscodeByteRangeRequests>true</IgnoreTranscodeByteRangeRequests>
<XmlRootAttributes />
<DirectPlayProfiles>
- <DirectPlayProfile container="avi" audioCodec="ac3,dca,mp2,mp3,pcm,dca" videoCodec="mpeg1video,mpeg2video,mpeg4,h264,vc1" type="Video" />
- <DirectPlayProfile container="mpeg" audioCodec="ac3,dca,mp2,mp3,pcm,dca" videoCodec="mpeg1video,mpeg2video" type="Video" />
- <DirectPlayProfile container="mkv" audioCodec="ac3,dca,aac,mp2,mp3,pcm,dca" videoCodec="mpeg1video,mpeg2video,mpeg4,h264,vc1" type="Video" />
- <DirectPlayProfile container="ts,m2ts" audioCodec="ac3,dca,mp2,mp3,aac,dca" videoCodec="mpeg1video,mpeg2video,h264,vc1" type="Video" />
- <DirectPlayProfile container="mp4,mov" audioCodec="ac3,aac,mp2,mp3,dca" videoCodec="h264,mpeg4" type="Video" />
+ <DirectPlayProfile container="avi" audioCodec="ac3,dca,mp2,mp3,pcm,dts" videoCodec="mpeg1video,mpeg2video,mpeg4,h264,vc1" type="Video" />
+ <DirectPlayProfile container="mpeg" audioCodec="ac3,dca,mp2,mp3,pcm,dts" videoCodec="mpeg1video,mpeg2video" type="Video" />
+ <DirectPlayProfile container="mkv" audioCodec="ac3,dca,aac,mp2,mp3,pcm,dts" videoCodec="mpeg1video,mpeg2video,mpeg4,h264,vc1" type="Video" />
+ <DirectPlayProfile container="ts,m2ts" audioCodec="ac3,dca,mp2,mp3,aac,dts" videoCodec="mpeg1video,mpeg2video,h264,vc1" type="Video" />
+ <DirectPlayProfile container="mp4,mov" audioCodec="ac3,aac,mp2,mp3,dca,dts" 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" />
diff --git a/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs b/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs
index 68768745e8..c9bba526a5 100644
--- a/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs
+++ b/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs
@@ -11,6 +11,8 @@ using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common.Net;
+using MediaBrowser.Model.Events;
+using Rssdp;
namespace MediaBrowser.Dlna.Ssdp
{
@@ -20,211 +22,114 @@ namespace MediaBrowser.Dlna.Ssdp
private readonly ILogger _logger;
private readonly IServerConfigurationManager _config;
- private SsdpHandler _ssdpHandler;
private readonly CancellationTokenSource _tokenSource;
- private readonly IServerApplicationHost _appHost;
- public event EventHandler<SsdpMessageEventArgs> DeviceDiscovered;
- public event EventHandler<SsdpMessageEventArgs> DeviceLeft;
- private readonly INetworkManager _networkManager;
+ public event EventHandler<GenericEventArgs<UpnpDeviceInfo>> DeviceDiscovered;
+ public event EventHandler<GenericEventArgs<UpnpDeviceInfo>> DeviceLeft;
- public DeviceDiscovery(ILogger logger, IServerConfigurationManager config, IServerApplicationHost appHost, INetworkManager networkManager)
+ private SsdpDeviceLocator _DeviceLocator;
+
+ public DeviceDiscovery(ILogger logger, IServerConfigurationManager config)
{
_tokenSource = new CancellationTokenSource();
_logger = logger;
_config = config;
- _appHost = appHost;
- _networkManager = networkManager;
}
- private List<IPAddress> GetLocalIpAddresses()
- {
- return _networkManager.GetLocalIpAddresses().ToList();
- }
-
- public void Start(SsdpHandler ssdpHandler)
+ // Call this method from somewhere in your code to start the search.
+ public void BeginSearch()
{
- _ssdpHandler = ssdpHandler;
- _ssdpHandler.MessageReceived += _ssdpHandler_MessageReceived;
-
- foreach (var localIp in GetLocalIpAddresses())
- {
- try
- {
- CreateListener(localIp);
- }
- catch (Exception e)
- {
- _logger.ErrorException("Failed to Initilize Socket", e);
- }
- }
- }
+ _DeviceLocator = new SsdpDeviceLocator();
- async void _ssdpHandler_MessageReceived(object sender, SsdpMessageEventArgs e)
- {
- string nts;
- e.Headers.TryGetValue("NTS", out nts);
+ // (Optional) Set the filter so we only see notifications for devices we care about
+ // (can be any search target value i.e device type, uuid value etc - any value that appears in the
+ // DiscoverdSsdpDevice.NotificationType property or that is used with the searchTarget parameter of the Search method).
+ //_DeviceLocator.NotificationFilter = "upnp:rootdevice";
- if (String.Equals(e.Method, "NOTIFY", StringComparison.OrdinalIgnoreCase) &&
- String.Equals(nts, "ssdp:byebye", StringComparison.OrdinalIgnoreCase) &&
- !_disposed)
- {
- EventHelper.FireEventIfNotNull(DeviceLeft, this, e, _logger);
- return;
- }
+ // Connect our event handler so we process devices as they are found
+ _DeviceLocator.DeviceAvailable += deviceLocator_DeviceAvailable;
+ _DeviceLocator.DeviceUnavailable += _DeviceLocator_DeviceUnavailable;
- try
- {
- if (e.LocalEndPoint == null)
- {
- var ip = (await _appHost.GetLocalIpAddresses().ConfigureAwait(false)).FirstOrDefault(i => !IPAddress.IsLoopback(i));
- if (ip != null)
- {
- e.LocalEndPoint = new IPEndPoint(ip, 0);
- }
- }
-
- if (e.LocalEndPoint != null)
- {
- TryCreateDevice(e);
- }
- }
- catch (OperationCanceledException)
- {
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error creating play to controller", ex);
- }
+ // Perform a search so we don't have to wait for devices to broadcast notifications
+ // again to get any results right away (notifications are broadcast periodically).
+ StartAsyncSearch();
}
- private void CreateListener(IPAddress localIp)
+ private void StartAsyncSearch()
{
Task.Factory.StartNew(async (o) =>
{
- try
+ while (!_tokenSource.IsCancellationRequested)
{
- _logger.Info("Creating SSDP listener on {0}", localIp);
-
- var endPoint = new IPEndPoint(localIp, 1900);
-
- using (var socket = GetMulticastSocket(localIp, endPoint))
+ try
{
- var receiveBuffer = new byte[64000];
-
- CreateNotifier(localIp);
-
- while (!_tokenSource.IsCancellationRequested)
- {
- var receivedBytes = await socket.ReceiveAsync(receiveBuffer, 0, 64000);
+ // Enable listening for notifications (optional)
+ _DeviceLocator.StartListeningForNotifications();
- if (receivedBytes > 0)
- {
- var args = SsdpHelper.ParseSsdpResponse(receiveBuffer);
- args.EndPoint = endPoint;
- args.LocalEndPoint = new IPEndPoint(localIp, 0);
-
- _ssdpHandler.LogMessageReceived(args, true);
-
- TryCreateDevice(args);
- }
- }
+ await _DeviceLocator.SearchAsync().ConfigureAwait(false);
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error searching for devices", ex);
}
- _logger.Info("SSDP listener - Task completed");
- }
- catch (OperationCanceledException)
- {
- }
- catch (Exception e)
- {
- _logger.ErrorException("Error in listener", e);
+ var delay = _config.GetDlnaConfiguration().ClientDiscoveryIntervalSeconds * 1000;
+
+ await Task.Delay(delay, _tokenSource.Token).ConfigureAwait(false);
}
- }, _tokenSource.Token, TaskCreationOptions.LongRunning);
+ }, CancellationToken.None, TaskCreationOptions.LongRunning);
}
- private void CreateNotifier(IPAddress localIp)
+ // Process each found device in the event handler
+ void deviceLocator_DeviceAvailable(object sender, DeviceAvailableEventArgs e)
{
- Task.Factory.StartNew(async (o) =>
- {
- try
- {
- while (true)
- {
- _ssdpHandler.SendSearchMessage(new IPEndPoint(localIp, 1900));
+ var originalHeaders = e.DiscoveredDevice.ResponseHeaders;
- var delay = _config.GetDlnaConfiguration().ClientDiscoveryIntervalSeconds * 1000;
+ var headerDict = originalHeaders == null ? new Dictionary<string, KeyValuePair<string, IEnumerable<string>>>() : originalHeaders.ToDictionary(i => i.Key, StringComparer.OrdinalIgnoreCase);
- await Task.Delay(delay, _tokenSource.Token).ConfigureAwait(false);
- }
- }
- catch (OperationCanceledException)
- {
- }
- catch (Exception ex)
+ var headers = headerDict.ToDictionary(i => i.Key, i => i.Value.Value.FirstOrDefault(), StringComparer.OrdinalIgnoreCase);
+
+ var args = new GenericEventArgs<UpnpDeviceInfo>
+ {
+ Argument = new UpnpDeviceInfo
{
- _logger.ErrorException("Error in notifier", ex);
+ Location = e.DiscoveredDevice.DescriptionLocation,
+ Headers = headers
}
+ };
- }, _tokenSource.Token, TaskCreationOptions.LongRunning);
+ EventHelper.FireEventIfNotNull(DeviceDiscovered, this, args, _logger);
}
- private Socket GetMulticastSocket(IPAddress localIpAddress, EndPoint localEndpoint)
+ private void _DeviceLocator_DeviceUnavailable(object sender, DeviceUnavailableEventArgs e)
{
- var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
- socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
- socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(IPAddress.Parse("239.255.255.250"), localIpAddress));
- socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 4);
-
- socket.Bind(localEndpoint);
+ var originalHeaders = e.DiscoveredDevice.ResponseHeaders;
- return socket;
- }
+ var headerDict = originalHeaders == null ? new Dictionary<string, KeyValuePair<string, IEnumerable<string>>>() : originalHeaders.ToDictionary(i => i.Key, StringComparer.OrdinalIgnoreCase);
- private void TryCreateDevice(SsdpMessageEventArgs args)
- {
- string nts;
- args.Headers.TryGetValue("NTS", out nts);
+ var headers = headerDict.ToDictionary(i => i.Key, i => i.Value.Value.FirstOrDefault(), StringComparer.OrdinalIgnoreCase);
- if (String.Equals(nts, "ssdp:byebye", StringComparison.OrdinalIgnoreCase))
+ var args = new GenericEventArgs<UpnpDeviceInfo>
{
- if (String.Equals(args.Method, "NOTIFY", StringComparison.OrdinalIgnoreCase))
+ Argument = new UpnpDeviceInfo
{
- if (!_disposed)
- {
- EventHelper.FireEventIfNotNull(DeviceLeft, this, args, _logger);
- }
+ Location = e.DiscoveredDevice.DescriptionLocation,
+ Headers = headers
}
+ };
- return;
- }
-
- string usn;
- if (!args.Headers.TryGetValue("USN", out usn)) usn = string.Empty;
-
- string nt;
- if (!args.Headers.TryGetValue("NT", out nt)) nt = string.Empty;
-
- // Need to be able to download device description
- string location;
- if (!args.Headers.TryGetValue("Location", out location) ||
- string.IsNullOrEmpty(location))
- {
- return;
- }
+ EventHelper.FireEventIfNotNull(DeviceLeft, this, args, _logger);
+ }
- EventHelper.FireEventIfNotNull(DeviceDiscovered, this, args, _logger);
+ public void Start()
+ {
+ BeginSearch();
}
public void Dispose()
{
- if (_ssdpHandler != null)
- {
- _ssdpHandler.MessageReceived -= _ssdpHandler_MessageReceived;
- }
-
if (!_disposed)
{
_disposed = true;
diff --git a/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs b/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs
index 720ea71a08..0d0ca98a28 100644
--- a/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs
+++ b/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs
@@ -83,90 +83,6 @@ namespace MediaBrowser.Dlna.Ssdp
}
}
- public event EventHandler<SsdpMessageEventArgs> MessageReceived;
-
- private async void OnMessageReceived(SsdpMessageEventArgs args, bool isMulticast)
- {
- if (IgnoreMessage(args, isMulticast))
- {
- return;
- }
-
- LogMessageReceived(args, isMulticast);
-
- var headers = args.Headers;
- string st;
-
- if (string.Equals(args.Method, "M-SEARCH", StringComparison.OrdinalIgnoreCase) && headers.TryGetValue("st", out st))
- {
- TimeSpan delay = GetSearchDelay(headers);
-
- if (_config.GetDlnaConfiguration().EnableDebugLog)
- {
- _logger.Debug("Delaying search response by {0} seconds", delay.TotalSeconds);
- }
-
- await Task.Delay(delay).ConfigureAwait(false);
-
- RespondToSearch(args.EndPoint, st);
- }
-
- EventHelper.FireEventIfNotNull(MessageReceived, this, args, _logger);
- }
-
- internal void LogMessageReceived(SsdpMessageEventArgs args, bool isMulticast)
- {
- var enableDebugLogging = _config.GetDlnaConfiguration().EnableDebugLog;
-
- if (enableDebugLogging)
- {
- var headerTexts = args.Headers.Select(i => string.Format("{0}={1}", i.Key, i.Value));
- var headerText = string.Join(",", headerTexts.ToArray());
-
- var protocol = isMulticast ? "Multicast" : "Unicast";
- var localEndPointString = args.LocalEndPoint == null ? "null" : args.LocalEndPoint.ToString();
- _logger.Debug("{0} message received from {1} on {3}. Protocol: {4} Headers: {2}", args.Method, args.EndPoint, headerText, localEndPointString, protocol);
- }
- }
-
- internal bool IgnoreMessage(SsdpMessageEventArgs args, bool isMulticast)
- {
- string usn;
- if (args.Headers.TryGetValue("USN", out usn))
- {
- // USN=uuid:b67df29b5c379445fde78c3774ab518d::urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:1
- if (RegisteredDevices.Any(i => string.Equals(i.USN, usn, StringComparison.OrdinalIgnoreCase)))
- {
- //var headerTexts = args.Headers.Select(i => string.Format("{0}={1}", i.Key, i.Value));
- //var headerText = string.Join(",", headerTexts.ToArray());
-
- //var protocol = isMulticast ? "Multicast" : "Unicast";
- //var localEndPointString = args.LocalEndPoint == null ? "null" : args.LocalEndPoint.ToString();
- //_logger.Debug("IGNORING {0} message received from {1} on {3}. Protocol: {4} Headers: {2}", args.Method, args.EndPoint, headerText, localEndPointString, protocol);
-
- return true;
- }
- }
-
- string serverId;
- if (args.Headers.TryGetValue("X-EMBY-SERVERID", out serverId))
- {
- if (string.Equals(serverId, _appHost.SystemId, StringComparison.OrdinalIgnoreCase))
- {
- //var headerTexts = args.Headers.Select(i => string.Format("{0}={1}", i.Key, i.Value));
- //var headerText = string.Join(",", headerTexts.ToArray());
-
- //var protocol = isMulticast ? "Multicast" : "Unicast";
- //var localEndPointString = args.LocalEndPoint == null ? "null" : args.LocalEndPoint.ToString();
- //_logger.Debug("IGNORING {0} message received from {1} on {3}. Protocol: {4} Headers: {2}", args.Method, args.EndPoint, headerText, localEndPointString, protocol);
-
- return true;
- }
- }
-
- return false;
- }
-
public IEnumerable<UpnpDevice> RegisteredDevices
{
get
@@ -188,8 +104,6 @@ namespace MediaBrowser.Dlna.Ssdp
RestartSocketListener();
ReloadAliveNotifier();
- CreateUnicastClient();
-
SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged;
SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
}
@@ -202,32 +116,6 @@ namespace MediaBrowser.Dlna.Ssdp
}
}
- public void SendSearchMessage(EndPoint localIp)
- {
- var values = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
-
- values["HOST"] = "239.255.255.250:1900";
- values["USER-AGENT"] = "UPnP/1.0 DLNADOC/1.50 Platinum/1.0.4.2";
- values["X-EMBY-SERVERID"] = _appHost.SystemId;
-
- values["MAN"] = "\"ssdp:discover\"";
-
- // Search target
- values["ST"] = "ssdp:all";
-
- // Seconds to delay response
- values["MX"] = "3";
-
- var header = "M-SEARCH * HTTP/1.1";
-
- var msg = new SsdpMessageBuilder().BuildMessage(header, values);
-
- // UDP is unreliable, so send 3 requests at a time (per Upnp spec, sec 1.1.2)
- SendDatagram(msg, _ssdpEndp, localIp, true);
-
- SendUnicastRequest(msg);
- }
-
public async void SendDatagram(string msg,
EndPoint endpoint,
EndPoint localAddress,
@@ -248,75 +136,6 @@ namespace MediaBrowser.Dlna.Ssdp
}
}
- /// <summary>
- /// According to the spec: http://www.upnp.org/specs/arch/UPnP-arch-DeviceArchitecture-v1.0-20080424.pdf
- /// Device responses should be delayed a random duration between 0 and this many seconds to balance
- /// load for the control point when it processes responses. In my testing kodi times out after mx
- /// so we will generate from mx - 1
- /// </summary>
- /// <param name="headers">The mx headers</param>
- /// <returns>A timepsan for the amount to delay before returning search result.</returns>
- private TimeSpan GetSearchDelay(Dictionary<string, string> headers)
- {
- string mx;
- headers.TryGetValue("mx", out mx);
- int delaySeconds = 0;
- if (!string.IsNullOrWhiteSpace(mx)
- && int.TryParse(mx, NumberStyles.Any, CultureInfo.InvariantCulture, out delaySeconds)
- && delaySeconds > 1)
- {
- delaySeconds = new Random().Next(delaySeconds - 1);
- }
-
- return TimeSpan.FromSeconds(delaySeconds);
- }
-
- private void RespondToSearch(EndPoint endpoint, string deviceType)
- {
- var enableDebugLogging = _config.GetDlnaConfiguration().EnableDebugLog;
-
- var isLogged = false;
-
- const string header = "HTTP/1.1 200 OK";
-
- foreach (var d in RegisteredDevices)
- {
- if (string.Equals(deviceType, "ssdp:all", StringComparison.OrdinalIgnoreCase) ||
- string.Equals(deviceType, d.Type, StringComparison.OrdinalIgnoreCase))
- {
- if (!isLogged)
- {
- if (enableDebugLogging)
- {
- _logger.Debug("Responding to search from {0} for {1}", endpoint, deviceType);
- }
- isLogged = true;
- }
-
- var values = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
-
- values["CACHE-CONTROL"] = "max-age = 600";
- values["DATE"] = DateTime.Now.ToString("R");
- values["EXT"] = "";
- values["LOCATION"] = d.Descriptor.ToString();
- values["SERVER"] = _serverSignature;
- values["ST"] = d.Type;
- values["USN"] = d.USN;
-
- var msg = new SsdpMessageBuilder().BuildMessage(header, values);
-
- SendDatagram(msg, endpoint, null, false, 2);
- SendDatagram(msg, endpoint, new IPEndPoint(d.Address, 0), false, 2);
- //SendDatagram(header, values, endpoint, null, true);
-
- if (enableDebugLogging)
- {
- _logger.Debug("{1} - Responded to a {0} request to {2}", d.Type, endpoint, d.Address.ToString());
- }
- }
- }
- }
-
private void RestartSocketListener()
{
if (_isDisposed)
@@ -329,8 +148,6 @@ namespace MediaBrowser.Dlna.Ssdp
_multicastSocket = CreateMulticastSocket();
_logger.Info("MultiCast socket created");
-
- Receive();
}
catch (Exception ex)
{
@@ -339,74 +156,6 @@ namespace MediaBrowser.Dlna.Ssdp
}
}
- private void Receive()
- {
- try
- {
- var buffer = new byte[1024];
-
- EndPoint endpoint = new IPEndPoint(IPAddress.Any, SSDPPort);
-
- _multicastSocket.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref endpoint, ReceiveCallback, buffer);
- }
- catch (ObjectDisposedException)
- {
- if (!_isDisposed)
- {
- //StartSocketRetryTimer();
- }
- }
- catch (Exception ex)
- {
- _logger.Debug("Error in BeginReceiveFrom", ex);
- }
- }
-
- private void ReceiveCallback(IAsyncResult result)
- {
- if (_isDisposed)
- {
- return;
- }
-
- try
- {
- EndPoint endpoint = new IPEndPoint(IPAddress.Any, SSDPPort);
-
- var length = _multicastSocket.EndReceiveFrom(result, ref endpoint);
-
- var received = (byte[])result.AsyncState;
-
- var enableDebugLogging = _config.GetDlnaConfiguration().EnableDebugLog;
-
- if (enableDebugLogging)
- {
- _logger.Debug(Encoding.ASCII.GetString(received));
- }
-
- var args = SsdpHelper.ParseSsdpResponse(received);
- args.EndPoint = endpoint;
-
- OnMessageReceived(args, true);
- }
- catch (ObjectDisposedException)
- {
- if (!_isDisposed)
- {
- //StartSocketRetryTimer();
- }
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Failed to read SSDP message", ex);
- }
-
- if (_multicastSocket != null)
- {
- Receive();
- }
- }
-
public void Dispose()
{
_config.NamedConfigurationUpdated -= _config_ConfigurationUpdated;
@@ -414,7 +163,6 @@ namespace MediaBrowser.Dlna.Ssdp
_isDisposed = true;
- DisposeUnicastClient();
DisposeSocket();
StopAliveNotifier();
}
@@ -523,137 +271,6 @@ namespace MediaBrowser.Dlna.Ssdp
}
}
- private void CreateUnicastClient()
- {
- if (_unicastClient == null)
- {
- try
- {
- _unicastClient = new UdpClient(_unicastPort);
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error creating unicast client", ex);
- }
-
- UnicastSetBeginReceive();
- }
- }
-
- private void DisposeUnicastClient()
- {
- if (_unicastClient != null)
- {
- try
- {
- _unicastClient.Close();
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error closing unicast client", ex);
- }
-
- _unicastClient = null;
- }
- }
-
- /// <summary>
- /// Listen for Unicast SSDP Responses
- /// </summary>
- private void UnicastSetBeginReceive()
- {
- try
- {
- var ipRxEnd = new IPEndPoint(IPAddress.Any, _unicastPort);
- var udpListener = new UdpState { EndPoint = ipRxEnd };
-
- udpListener.UdpClient = _unicastClient;
- _unicastClient.BeginReceive(UnicastReceiveCallback, udpListener);
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error in UnicastSetBeginReceive", ex);
- }
- }
-
- /// <summary>
- /// The UnicastReceiveCallback receives Http Responses
- /// and Fired the SatIpDeviceFound Event for adding the SatIpDevice
- /// </summary>
- /// <param name="ar"></param>
- private void UnicastReceiveCallback(IAsyncResult ar)
- {
- var udpClient = ((UdpState)(ar.AsyncState)).UdpClient;
- var endpoint = ((UdpState)(ar.AsyncState)).EndPoint;
- if (udpClient.Client != null)
- {
- try
- {
- var responseBytes = udpClient.EndReceive(ar, ref endpoint);
- var args = SsdpHelper.ParseSsdpResponse(responseBytes);
-
- args.EndPoint = endpoint;
-
- OnMessageReceived(args, false);
-
- UnicastSetBeginReceive();
- }
- catch (ObjectDisposedException)
- {
-
- }
- catch (SocketException)
- {
-
- }
- catch (Exception)
- {
- // If called while shutting down, seeing a NullReferenceException inside EndReceive
- }
- }
- }
-
- private void SendUnicastRequest(string request, int sendCount = 3)
- {
- if (_unicastClient == null)
- {
- return;
- }
-
- var ipSsdp = IPAddress.Parse(SSDPAddr);
- var ipTxEnd = new IPEndPoint(ipSsdp, SSDPPort);
-
- SendUnicastRequest(request, ipTxEnd, sendCount);
- }
-
- private async void SendUnicastRequest(string request, IPEndPoint toEndPoint, int sendCount = 3)
- {
- if (_unicastClient == null)
- {
- return;
- }
-
- //_logger.Debug("Sending unicast request");
-
- byte[] req = Encoding.ASCII.GetBytes(request);
-
- try
- {
- for (var i = 0; i < sendCount; i++)
- {
- if (i > 0)
- {
- await Task.Delay(50).ConfigureAwait(false);
- }
- _unicastClient.Send(req, req.Length, toEndPoint);
- }
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error in SendUnicastRequest", ex);
- }
- }
-
private readonly object _notificationTimerSyncLock = new object();
private int _aliveNotifierIntervalMs;
private void ReloadAliveNotifier()
diff --git a/MediaBrowser.Dlna/Ssdp/SsdpHelper.cs b/MediaBrowser.Dlna/Ssdp/SsdpHelper.cs
deleted file mode 100644
index d196e98518..0000000000
--- a/MediaBrowser.Dlna/Ssdp/SsdpHelper.cs
+++ /dev/null
@@ -1,45 +0,0 @@
-using MediaBrowser.Controller.Dlna;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-
-namespace MediaBrowser.Dlna.Ssdp
-{
- public class SsdpHelper
- {
- public static SsdpMessageEventArgs ParseSsdpResponse(byte[] data)
- {
- using (var ms = new MemoryStream(data))
- {
- using (var reader = new StreamReader(ms, Encoding.ASCII))
- {
- var proto = (reader.ReadLine() ?? string.Empty).Trim();
- var method = proto.Split(new[] { ' ' }, 2)[0];
- var headers = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
- for (var line = reader.ReadLine(); line != null; line = reader.ReadLine())
- {
- line = line.Trim();
- if (string.IsNullOrEmpty(line))
- {
- break;
- }
- var parts = line.Split(new[] { ':' }, 2);
-
- if (parts.Length >= 2)
- {
- headers[parts[0]] = parts[1].Trim();
- }
- }
-
- return new SsdpMessageEventArgs
- {
- Method = method,
- Headers = headers,
- Message = data
- };
- }
- }
- }
- }
-}