reduce upnp traffic

This commit is contained in:
Luke Pulverenti 2015-04-29 15:48:46 -04:00
parent 053609ab76
commit 2f57a96568
4 changed files with 86 additions and 69 deletions

View File

@ -18,16 +18,6 @@ using System.Threading.Tasks;
namespace MediaBrowser.Api.Playback namespace MediaBrowser.Api.Playback
{ {
[Route("/Items/{Id}/MediaInfo", "GET", Summary = "Gets live playback media info for an item")]
public class GetLiveMediaInfo : IReturn<PlaybackInfoResponse>
{
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Id { get; set; }
[ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
public string UserId { get; set; }
}
[Route("/Items/{Id}/PlaybackInfo", "GET", Summary = "Gets live playback media info for an item")] [Route("/Items/{Id}/PlaybackInfo", "GET", Summary = "Gets live playback media info for an item")]
public class GetPlaybackInfo : IReturn<PlaybackInfoResponse> public class GetPlaybackInfo : IReturn<PlaybackInfoResponse>
{ {
@ -79,12 +69,6 @@ namespace MediaBrowser.Api.Playback
return ToOptimizedResult(result); return ToOptimizedResult(result);
} }
public async Task<object> Get(GetLiveMediaInfo request)
{
var result = await GetPlaybackInfo(request.Id, request.UserId, new[] { MediaType.Audio, MediaType.Video }).ConfigureAwait(false);
return ToOptimizedResult(result);
}
public async Task<object> Post(OpenMediaSource request) public async Task<object> Post(OpenMediaSource request)
{ {
var authInfo = AuthorizationContext.GetAuthorizationInfo(Request); var authInfo = AuthorizationContext.GetAuthorizationInfo(Request);

View File

@ -13,6 +13,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using System.Threading;
namespace MediaBrowser.Dlna.PlayTo namespace MediaBrowser.Dlna.PlayTo
{ {
@ -34,6 +35,9 @@ namespace MediaBrowser.Dlna.PlayTo
private readonly DeviceDiscovery _deviceDiscovery; private readonly DeviceDiscovery _deviceDiscovery;
private readonly IMediaSourceManager _mediaSourceManager; private readonly IMediaSourceManager _mediaSourceManager;
private readonly List<string> _nonRendererUrls = new List<string>();
private Timer _clearNonRenderersTimer;
public PlayToManager(ILogger logger, ISessionManager sessionManager, ILibraryManager libraryManager, IUserManager userManager, IDlnaManager dlnaManager, IServerApplicationHost appHost, IImageProcessor imageProcessor, DeviceDiscovery deviceDiscovery, IHttpClient httpClient, IServerConfigurationManager config, IUserDataManager userDataManager, ILocalizationManager localization, IMediaSourceManager mediaSourceManager) public PlayToManager(ILogger logger, ISessionManager sessionManager, ILibraryManager libraryManager, IUserManager userManager, IDlnaManager dlnaManager, IServerApplicationHost appHost, IImageProcessor imageProcessor, DeviceDiscovery deviceDiscovery, IHttpClient httpClient, IServerConfigurationManager config, IUserDataManager userDataManager, ILocalizationManager localization, IMediaSourceManager mediaSourceManager)
{ {
_logger = logger; _logger = logger;
@ -53,9 +57,19 @@ namespace MediaBrowser.Dlna.PlayTo
public void Start() public void Start()
{ {
_clearNonRenderersTimer = new Timer(OnClearUrlTimerCallback, null, TimeSpan.FromMinutes(10), TimeSpan.FromMinutes(10));
_deviceDiscovery.DeviceDiscovered += _deviceDiscovery_DeviceDiscovered; _deviceDiscovery.DeviceDiscovered += _deviceDiscovery_DeviceDiscovered;
} }
private void OnClearUrlTimerCallback(object state)
{
lock (_nonRendererUrls)
{
_nonRendererUrls.Clear();
}
}
async void _deviceDiscovery_DeviceDiscovered(object sender, SsdpMessageEventArgs e) async void _deviceDiscovery_DeviceDiscovered(object sender, SsdpMessageEventArgs e)
{ {
var localIp = e.LocalIp; var localIp = e.LocalIp;
@ -68,7 +82,7 @@ namespace MediaBrowser.Dlna.PlayTo
string location; string location;
if (!e.Headers.TryGetValue("Location", out location)) location = string.Empty; if (!e.Headers.TryGetValue("Location", out location)) location = string.Empty;
// It has to report that it's a media renderer // It has to report that it's a media renderer
if (usn.IndexOf("MediaRenderer:", StringComparison.OrdinalIgnoreCase) == -1 && if (usn.IndexOf("MediaRenderer:", StringComparison.OrdinalIgnoreCase) == -1 &&
nt.IndexOf("MediaRenderer:", StringComparison.OrdinalIgnoreCase) == -1) nt.IndexOf("MediaRenderer:", StringComparison.OrdinalIgnoreCase) == -1)
@ -85,62 +99,75 @@ namespace MediaBrowser.Dlna.PlayTo
{ {
var uri = new Uri(location); var uri = new Uri(location);
// TODO: Cache list of non-renderers by url to avoid repeating calls lock (_nonRendererUrls)
{
if (_nonRendererUrls.Contains(location, StringComparer.OrdinalIgnoreCase))
{
return;
}
}
var device = await Device.CreateuPnpDeviceAsync(uri, _httpClient, _config, _logger).ConfigureAwait(false); var device = await Device.CreateuPnpDeviceAsync(uri, _httpClient, _config, _logger).ConfigureAwait(false);
if (device.RendererCommands != null) if (device.RendererCommands == null)
{ {
var sessionInfo = await _sessionManager.LogSessionActivity(device.Properties.ClientType, _appHost.ApplicationVersion.ToString(), device.Properties.UUID, device.Properties.Name, uri.OriginalString, null) lock (_nonRendererUrls)
.ConfigureAwait(false);
var controller = sessionInfo.SessionController as PlayToController;
if (controller == null)
{ {
var serverAddress = GetServerAddress(localIp); _nonRendererUrls.Add(location);
string accessToken = null; return;
sessionInfo.SessionController = controller = new PlayToController(sessionInfo,
_sessionManager,
_libraryManager,
_logger,
_dlnaManager,
_userManager,
_imageProcessor,
serverAddress,
accessToken,
_deviceDiscovery,
_userDataManager,
_localization,
_mediaSourceManager);
controller.Init(device);
var profile = _dlnaManager.GetProfile(device.Properties.ToDeviceIdentification()) ??
_dlnaManager.GetDefaultProfile();
_sessionManager.ReportCapabilities(sessionInfo.Id, new ClientCapabilities
{
PlayableMediaTypes = profile.GetSupportedMediaTypes(),
SupportedCommands = new List<string>
{
GeneralCommandType.VolumeDown.ToString(),
GeneralCommandType.VolumeUp.ToString(),
GeneralCommandType.Mute.ToString(),
GeneralCommandType.Unmute.ToString(),
GeneralCommandType.ToggleMute.ToString(),
GeneralCommandType.SetVolume.ToString(),
GeneralCommandType.SetAudioStreamIndex.ToString(),
GeneralCommandType.SetSubtitleStreamIndex.ToString()
},
SupportsMediaControl = true
});
_logger.Info("DLNA Session created for {0} - {1}", device.Properties.Name, device.Properties.ModelName);
} }
} }
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)
{
var serverAddress = GetServerAddress(localIp);
string accessToken = null;
sessionInfo.SessionController = controller = new PlayToController(sessionInfo,
_sessionManager,
_libraryManager,
_logger,
_dlnaManager,
_userManager,
_imageProcessor,
serverAddress,
accessToken,
_deviceDiscovery,
_userDataManager,
_localization,
_mediaSourceManager);
controller.Init(device);
var profile = _dlnaManager.GetProfile(device.Properties.ToDeviceIdentification()) ??
_dlnaManager.GetDefaultProfile();
_sessionManager.ReportCapabilities(sessionInfo.Id, new ClientCapabilities
{
PlayableMediaTypes = profile.GetSupportedMediaTypes(),
SupportedCommands = new List<string>
{
GeneralCommandType.VolumeDown.ToString(),
GeneralCommandType.VolumeUp.ToString(),
GeneralCommandType.Mute.ToString(),
GeneralCommandType.Unmute.ToString(),
GeneralCommandType.ToggleMute.ToString(),
GeneralCommandType.SetVolume.ToString(),
GeneralCommandType.SetAudioStreamIndex.ToString(),
GeneralCommandType.SetSubtitleStreamIndex.ToString()
},
SupportsMediaControl = true
});
_logger.Info("DLNA Session created for {0} - {1}", device.Properties.Name, device.Properties.ModelName);
}
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -156,6 +183,12 @@ namespace MediaBrowser.Dlna.PlayTo
public void Dispose() public void Dispose()
{ {
_deviceDiscovery.DeviceDiscovered -= _deviceDiscovery_DeviceDiscovered; _deviceDiscovery.DeviceDiscovered -= _deviceDiscovery_DeviceDiscovered;
if (_clearNonRenderersTimer != null)
{
_clearNonRenderersTimer.Dispose();
_clearNonRenderersTimer = null;
}
} }
} }
} }

View File

@ -145,7 +145,7 @@ namespace MediaBrowser.Dlna.Ssdp
values["MX"] = "3"; values["MX"] = "3";
// UDP is unreliable, so send 3 requests at a time (per Upnp spec, sec 1.1.2) // UDP is unreliable, so send 3 requests at a time (per Upnp spec, sec 1.1.2)
SendDatagram("M-SEARCH * HTTP/1.1", values, localIp, 1); SendDatagram("M-SEARCH * HTTP/1.1", values, localIp, 2);
} }
public void SendDatagram(string header, public void SendDatagram(string header,

View File

@ -436,7 +436,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
_shrinkMemoryTimer = null; _shrinkMemoryTimer = null;
} }
//_writeLock.Wait(); _writeLock.Wait();
if (_connection != null) if (_connection != null)
{ {