Skip to content

Commit

Permalink
Merge pull request #3055 from MediaBrowser/beta
Browse files Browse the repository at this point in the history
Beta
  • Loading branch information
LukePulverenti authored Dec 5, 2017
2 parents eaecd97 + 30e8efd commit 50b88c5
Show file tree
Hide file tree
Showing 367 changed files with 3,767 additions and 2,325 deletions.
3 changes: 2 additions & 1 deletion Emby.Dlna/Main/DlnaEntryPoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
using MediaBrowser.Model.Threading;
using Rssdp;
using Rssdp.Infrastructure;
using System.Threading;

namespace Emby.Dlna.Main
{
Expand Down Expand Up @@ -252,7 +253,7 @@ private async Task RegisterServerEndpoints()
var cacheLength = _config.GetDlnaConfiguration().BlastAliveMessageIntervalSeconds;
_Publisher.SupportPnpRootDevice = false;

var addresses = (await _appHost.GetLocalIpAddresses().ConfigureAwait(false)).ToList();
var addresses = (await _appHost.GetLocalIpAddresses(CancellationToken.None).ConfigureAwait(false)).ToList();

var udn = CreateUuid(_appHost.SystemId);

Expand Down
16 changes: 8 additions & 8 deletions Emby.Dlna/PlayTo/Device.cs
Original file line number Diff line number Diff line change
Expand Up @@ -831,7 +831,7 @@ private static string[] GetProtocolInfo(XElement container)

#region From XML

private async Task GetAVProtocolAsync()
private async Task GetAVProtocolAsync(CancellationToken cancellationToken)
{
if (_disposed)
{
Expand All @@ -845,12 +845,12 @@ private async Task GetAVProtocolAsync()
string url = NormalizeUrl(Properties.BaseUrl, avService.ScpdUrl);

var httpClient = new SsdpHttpClient(_httpClient, _config);
var document = await httpClient.GetDataAsync(url).ConfigureAwait(false);
var document = await httpClient.GetDataAsync(url, cancellationToken).ConfigureAwait(false);

AvCommands = TransportCommands.Create(document);
}

private async Task GetRenderingProtocolAsync()
private async Task GetRenderingProtocolAsync(CancellationToken cancellationToken)
{
if (_disposed)
{
Expand All @@ -864,7 +864,7 @@ private async Task GetRenderingProtocolAsync()
string url = NormalizeUrl(Properties.BaseUrl, avService.ScpdUrl);

var httpClient = new SsdpHttpClient(_httpClient, _config);
var document = await httpClient.GetDataAsync(url).ConfigureAwait(false);
var document = await httpClient.GetDataAsync(url, cancellationToken).ConfigureAwait(false);

RendererCommands = TransportCommands.Create(document);
}
Expand Down Expand Up @@ -897,11 +897,11 @@ internal TransportCommands RendererCommands
set;
}

public static async Task<Device> CreateuPnpDeviceAsync(Uri url, IHttpClient httpClient, IServerConfigurationManager config, ILogger logger, ITimerFactory timerFactory)
public static async Task<Device> CreateuPnpDeviceAsync(Uri url, IHttpClient httpClient, IServerConfigurationManager config, ILogger logger, ITimerFactory timerFactory, CancellationToken cancellationToken)
{
var ssdpHttpClient = new SsdpHttpClient(httpClient, config);

var document = await ssdpHttpClient.GetDataAsync(url.ToString()).ConfigureAwait(false);
var document = await ssdpHttpClient.GetDataAsync(url.ToString(), cancellationToken).ConfigureAwait(false);

var deviceProperties = new DeviceInfo();

Expand Down Expand Up @@ -987,8 +987,8 @@ public static async Task<Device> CreateuPnpDeviceAsync(Uri url, IHttpClient http

if (device.GetAvTransportService() != null)
{
await device.GetRenderingProtocolAsync().ConfigureAwait(false);
await device.GetAVProtocolAsync().ConfigureAwait(false);
await device.GetRenderingProtocolAsync(cancellationToken).ConfigureAwait(false);
await device.GetAVProtocolAsync(cancellationToken).ConfigureAwait(false);
}

return device;
Expand Down
8 changes: 7 additions & 1 deletion Emby.Dlna/PlayTo/PlayToController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,12 @@ public async Task SendPlayCommand(PlayRequest command, CancellationToken cancell
AddItemFromId(Guid.Parse(id), items);
}

var startIndex = command.StartIndex ?? 0;
if (startIndex > 0)
{
items = items.Skip(startIndex).ToList();
}

var playlist = new List<PlaylistItem>();
var isFirst = true;

Expand Down Expand Up @@ -424,7 +430,7 @@ public Task SendUserDataChangeInfo(UserDataChangeInfo info, CancellationToken ca
return Task.FromResult(true);
}

public Task SendRestartRequiredNotification(SystemInfo info, CancellationToken cancellationToken)
public Task SendRestartRequiredNotification(CancellationToken cancellationToken)
{
return Task.FromResult(true);
}
Expand Down
196 changes: 106 additions & 90 deletions Emby.Dlna/PlayTo/PlayToManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Net;
using MediaBrowser.Model.Threading;
using System.Threading;

namespace Emby.Dlna.PlayTo
{
Expand All @@ -44,6 +45,8 @@ class PlayToManager : IDisposable
private readonly List<string> _nonRendererUrls = new List<string>();
private DateTime _lastRendererClear;
private bool _disposed;
private SemaphoreSlim _sessionLock = new SemaphoreSlim(1, 1);
private CancellationTokenSource _disposeCancellationTokenSource = new CancellationTokenSource();

public PlayToManager(ILogger logger, ISessionManager sessionManager, ILibraryManager libraryManager, IUserManager userManager, IDlnaManager dlnaManager, IServerApplicationHost appHost, IImageProcessor imageProcessor, IDeviceDiscovery deviceDiscovery, IHttpClient httpClient, IServerConfigurationManager config, IUserDataManager userDataManager, ILocalizationManager localization, IMediaSourceManager mediaSourceManager, IMediaEncoder mediaEncoder, ITimerFactory timerFactory)
{
Expand Down Expand Up @@ -90,6 +93,7 @@ async void _deviceDiscovery_DeviceDiscovered(object sender, GenericEventArgs<Upn
if (usn.IndexOf("MediaRenderer:", StringComparison.OrdinalIgnoreCase) == -1 &&
nt.IndexOf("MediaRenderer:", StringComparison.OrdinalIgnoreCase) == -1)
{
//_logger.Debug("Upnp device {0} does not contain a MediaRenderer device (0).", location);
return;
}

Expand All @@ -98,92 +102,105 @@ async void _deviceDiscovery_DeviceDiscovered(object sender, GenericEventArgs<Upn
return;
}

var cancellationToken = _disposeCancellationTokenSource.Token;

await _sessionLock.WaitAsync(cancellationToken).ConfigureAwait(false);

try
{
lock (_nonRendererUrls)
if (_disposed)
{
if ((DateTime.UtcNow - _lastRendererClear).TotalMinutes >= 10)
{
_nonRendererUrls.Clear();
_lastRendererClear = DateTime.UtcNow;
}

if (_nonRendererUrls.Contains(location, StringComparer.OrdinalIgnoreCase))
{
return;
}
return;
}

var uri = info.Location;
_logger.Debug("Attempting to create PlayToController from location {0}", location);
var device = await Device.CreateuPnpDeviceAsync(uri, _httpClient, _config, _logger, _timerFactory).ConfigureAwait(false);
await AddDevice(info, location, cancellationToken).ConfigureAwait(false);
}
catch (OperationCanceledException)
{

}
catch (Exception ex)
{
_logger.ErrorException("Error creating PlayTo device.", ex);

_nonRendererUrls.Add(location);
}
finally
{
_sessionLock.Release();
}
}

private async Task AddDevice(UpnpDeviceInfo info, string location, CancellationToken cancellationToken)
{
if ((DateTime.UtcNow - _lastRendererClear).TotalMinutes >= 10)
{
_nonRendererUrls.Clear();
_lastRendererClear = DateTime.UtcNow;
}

if (_nonRendererUrls.Contains(location, StringComparer.OrdinalIgnoreCase))
{
return;
}

var uri = info.Location;
_logger.Debug("Attempting to create PlayToController from location {0}", location);
var device = await Device.CreateuPnpDeviceAsync(uri, _httpClient, _config, _logger, _timerFactory, cancellationToken).ConfigureAwait(false);

if (device.RendererCommands == null)
{
//_logger.Debug("Upnp device {0} does not contain a MediaRenderer device (1).", location);
_nonRendererUrls.Add(location);
return;
}

_logger.Debug("Logging session activity from location {0}", location);
var sessionInfo = await _sessionManager.LogSessionActivity(device.Properties.ClientType, _appHost.ApplicationVersion.ToString(), device.Properties.UUID, device.Properties.Name, uri.OriginalString, null).ConfigureAwait(false);

var controller = sessionInfo.SessionController as PlayToController;

if (device.RendererCommands == null)
if (controller == null)
{
string serverAddress;
if (info.LocalIpAddress == null || info.LocalIpAddress.Equals(IpAddressInfo.Any) || info.LocalIpAddress.Equals(IpAddressInfo.IPv6Loopback))
{
lock (_nonRendererUrls)
{
_nonRendererUrls.Add(location);
return;
}
serverAddress = await GetServerAddress(null, cancellationToken).ConfigureAwait(false);
}

if (_disposed)
else
{
return;
serverAddress = await GetServerAddress(info.LocalIpAddress, cancellationToken).ConfigureAwait(false);
}

_logger.Debug("Logging session activity from location {0}", location);
var sessionInfo = await _sessionManager.LogSessionActivity(device.Properties.ClientType, _appHost.ApplicationVersion.ToString(), device.Properties.UUID, device.Properties.Name, uri.OriginalString, null)
.ConfigureAwait(false);

var controller = sessionInfo.SessionController as PlayToController;

if (controller == null)
string accessToken = null;

sessionInfo.SessionController = controller = new PlayToController(sessionInfo,
_sessionManager,
_libraryManager,
_logger,
_dlnaManager,
_userManager,
_imageProcessor,
serverAddress,
accessToken,
_deviceDiscovery,
_userDataManager,
_localization,
_mediaSourceManager,
_config,
_mediaEncoder);

controller.Init(device);

var profile = _dlnaManager.GetProfile(device.Properties.ToDeviceIdentification()) ??
_dlnaManager.GetDefaultProfile();

_sessionManager.ReportCapabilities(sessionInfo.Id, new ClientCapabilities
{
if (_disposed)
{
return;
}
PlayableMediaTypes = profile.GetSupportedMediaTypes(),

string serverAddress;
if (info.LocalIpAddress == null || info.LocalIpAddress.Equals(IpAddressInfo.Any) || info.LocalIpAddress.Equals(IpAddressInfo.IPv6Loopback))
SupportedCommands = new string[]
{
serverAddress = await GetServerAddress(null).ConfigureAwait(false);
}
else
{
serverAddress = await GetServerAddress(info.LocalIpAddress).ConfigureAwait(false);
}

string accessToken = null;

sessionInfo.SessionController = controller = new PlayToController(sessionInfo,
_sessionManager,
_libraryManager,
_logger,
_dlnaManager,
_userManager,
_imageProcessor,
serverAddress,
accessToken,
_deviceDiscovery,
_userDataManager,
_localization,
_mediaSourceManager,
_config,
_mediaEncoder);

controller.Init(device);

var profile = _dlnaManager.GetProfile(device.Properties.ToDeviceIdentification()) ??
_dlnaManager.GetDefaultProfile();

_sessionManager.ReportCapabilities(sessionInfo.Id, new ClientCapabilities
{
PlayableMediaTypes = profile.GetSupportedMediaTypes(),

SupportedCommands = new string[]
{
GeneralCommandType.VolumeDown.ToString(),
GeneralCommandType.VolumeUp.ToString(),
GeneralCommandType.Mute.ToString(),
Expand All @@ -192,40 +209,39 @@ async void _deviceDiscovery_DeviceDiscovered(object sender, GenericEventArgs<Upn
GeneralCommandType.SetVolume.ToString(),
GeneralCommandType.SetAudioStreamIndex.ToString(),
GeneralCommandType.SetSubtitleStreamIndex.ToString()
},
},

SupportsMediaControl = true,
SupportsMediaControl = true,

// xbox one creates a new uuid everytime it restarts
SupportsPersistentIdentifier = (device.Properties.ModelName ?? string.Empty).IndexOf("xbox", StringComparison.OrdinalIgnoreCase) == -1
});
// xbox one creates a new uuid everytime it restarts
SupportsPersistentIdentifier = (device.Properties.ModelName ?? string.Empty).IndexOf("xbox", StringComparison.OrdinalIgnoreCase) == -1
});

_logger.Info("DLNA Session created for {0} - {1}", device.Properties.Name, device.Properties.ModelName);
}
}
catch (Exception ex)
{
_logger.ErrorException("Error creating PlayTo device.", ex);

lock (_nonRendererUrls)
{
_nonRendererUrls.Add(location);
}
_logger.Info("DLNA Session created for {0} - {1}", device.Properties.Name, device.Properties.ModelName);
}
}

private Task<string> GetServerAddress(IpAddressInfo address)
private Task<string> GetServerAddress(IpAddressInfo address, CancellationToken cancellationToken)
{
if (address == null)
{
return _appHost.GetLocalApiUrl();
return _appHost.GetLocalApiUrl(cancellationToken);
}

return Task.FromResult(_appHost.GetLocalApiUrl(address));
}

public void Dispose()
{
try
{
_disposeCancellationTokenSource.Cancel();
}
catch
{

}

_disposed = true;
_deviceDiscovery.DeviceDiscovered -= _deviceDiscovery_DeviceDiscovered;
GC.SuppressFinalize(this);
Expand Down
7 changes: 5 additions & 2 deletions Emby.Dlna/PlayTo/SsdpHttpClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using System.Threading;

namespace Emby.Dlna.PlayTo
{
Expand Down Expand Up @@ -89,7 +90,7 @@ public async Task SubscribeAsync(string url,
}
}

public async Task<XDocument> GetDataAsync(string url)
public async Task<XDocument> GetDataAsync(string url, CancellationToken cancellationToken)
{
var options = new HttpRequestOptions
{
Expand All @@ -99,7 +100,9 @@ public async Task<XDocument> GetDataAsync(string url)
BufferContent = false,

// The periodic requests may keep some devices awake
LogRequestAsDebug = true
LogRequestAsDebug = true,

CancellationToken = cancellationToken
};

options.RequestHeaders["FriendlyName.DLNA.ORG"] = FriendlyName;
Expand Down
2 changes: 1 addition & 1 deletion Emby.Dlna/Profiles/DishHopperJoeyProfile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ public DishHopperJoeyProfile()
{
new ResponseProfile
{
Container = "mkv,ts",
Container = "mkv,ts,mpegts",
Type = DlnaProfileType.Video,
MimeType = "video/mp4"
}
Expand Down
Loading

0 comments on commit 50b88c5

Please sign in to comment.