jellyfin-server/MediaBrowser.Dlna/PlayTo/PlayToManager.cs

195 lines
7.4 KiB
C#
Raw Normal View History

2014-07-22 01:29:06 +00:00
using MediaBrowser.Common.Net;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
2014-03-13 19:08:02 +00:00
using MediaBrowser.Controller.Dlna;
2014-04-23 16:29:21 +00:00
using MediaBrowser.Controller.Drawing;
2014-02-27 02:44:00 +00:00
using MediaBrowser.Controller.Library;
2014-09-24 01:44:05 +00:00
using MediaBrowser.Controller.Localization;
2014-02-27 02:44:00 +00:00
using MediaBrowser.Controller.Session;
2014-03-25 05:25:03 +00:00
using MediaBrowser.Dlna.Ssdp;
2014-02-27 02:44:00 +00:00
using MediaBrowser.Model.Logging;
2014-03-23 06:07:43 +00:00
using MediaBrowser.Model.Session;
2014-02-27 02:44:00 +00:00
using System;
2014-03-25 05:25:03 +00:00
using System.Collections.Generic;
2014-02-27 02:44:00 +00:00
using System.Linq;
using System.Net;
2015-04-29 19:48:46 +00:00
using System.Threading;
2014-02-27 02:44:00 +00:00
namespace MediaBrowser.Dlna.PlayTo
{
class PlayToManager : IDisposable
{
private readonly ILogger _logger;
private readonly ISessionManager _sessionManager;
private readonly ILibraryManager _libraryManager;
2014-03-13 14:54:11 +00:00
private readonly IUserManager _userManager;
2014-03-13 19:08:02 +00:00
private readonly IDlnaManager _dlnaManager;
2014-03-17 04:25:11 +00:00
private readonly IServerApplicationHost _appHost;
2014-04-23 16:29:21 +00:00
private readonly IImageProcessor _imageProcessor;
2014-07-22 01:29:06 +00:00
private readonly IHttpClient _httpClient;
private readonly IServerConfigurationManager _config;
private readonly IUserDataManager _userDataManager;
2014-09-24 01:44:05 +00:00
private readonly ILocalizationManager _localization;
2014-02-27 18:00:49 +00:00
private readonly DeviceDiscovery _deviceDiscovery;
2015-03-07 22:43:53 +00:00
private readonly IMediaSourceManager _mediaSourceManager;
2015-04-29 19:48:46 +00:00
private readonly List<string> _nonRendererUrls = new List<string>();
private Timer _clearNonRenderersTimer;
2015-03-07 22:43:53 +00:00
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)
2014-02-27 02:44:00 +00:00
{
_logger = logger;
_sessionManager = sessionManager;
_libraryManager = libraryManager;
2014-02-27 18:00:49 +00:00
_userManager = userManager;
2014-03-13 19:08:02 +00:00
_dlnaManager = dlnaManager;
2014-03-17 04:25:11 +00:00
_appHost = appHost;
2014-04-23 16:29:21 +00:00
_imageProcessor = imageProcessor;
_deviceDiscovery = deviceDiscovery;
2014-07-22 01:29:06 +00:00
_httpClient = httpClient;
_config = config;
_userDataManager = userDataManager;
2014-09-24 01:44:05 +00:00
_localization = localization;
2015-03-07 22:43:53 +00:00
_mediaSourceManager = mediaSourceManager;
2014-02-27 02:44:00 +00:00
}
2014-03-23 06:07:43 +00:00
public void Start()
2014-02-27 02:44:00 +00:00
{
2015-04-29 19:48:46 +00:00
_clearNonRenderersTimer = new Timer(OnClearUrlTimerCallback, null, TimeSpan.FromMinutes(10), TimeSpan.FromMinutes(10));
_deviceDiscovery.DeviceDiscovered += _deviceDiscovery_DeviceDiscovered;
2014-04-08 04:17:18 +00:00
}
2015-04-29 19:48:46 +00:00
private void OnClearUrlTimerCallback(object state)
{
lock (_nonRendererUrls)
{
_nonRendererUrls.Clear();
}
}
2014-07-22 01:29:06 +00:00
async void _deviceDiscovery_DeviceDiscovered(object sender, SsdpMessageEventArgs e)
2014-02-27 02:44:00 +00:00
{
2014-07-22 01:29:06 +00:00
var localIp = e.LocalIp;
2014-02-27 02:44:00 +00:00
2014-07-22 01:29:06 +00:00
string usn;
if (!e.Headers.TryGetValue("USN", out usn)) usn = string.Empty;
2014-04-27 03:42:05 +00:00
2014-07-22 01:29:06 +00:00
string nt;
if (!e.Headers.TryGetValue("NT", out nt)) nt = string.Empty;
string location;
if (!e.Headers.TryGetValue("Location", out location)) location = string.Empty;
2015-04-29 19:48:46 +00:00
2014-04-27 03:42:05 +00:00
// It has to report that it's a media renderer
if (usn.IndexOf("MediaRenderer:", StringComparison.OrdinalIgnoreCase) == -1 &&
nt.IndexOf("MediaRenderer:", StringComparison.OrdinalIgnoreCase) == -1)
{
return;
}
if (_sessionManager.Sessions.Any(i => usn.IndexOf(i.DeviceId, StringComparison.OrdinalIgnoreCase) != -1))
2014-03-25 05:25:03 +00:00
{
return;
2014-07-22 01:29:06 +00:00
}
2014-07-30 03:31:35 +00:00
try
2014-02-27 02:44:00 +00:00
{
2014-07-30 03:31:35 +00:00
var uri = new Uri(location);
2014-02-27 02:44:00 +00:00
2015-04-29 19:48:46 +00:00
lock (_nonRendererUrls)
{
if (_nonRendererUrls.Contains(location, StringComparer.OrdinalIgnoreCase))
{
return;
}
}
2014-07-30 03:31:35 +00:00
var device = await Device.CreateuPnpDeviceAsync(uri, _httpClient, _config, _logger).ConfigureAwait(false);
2014-02-27 02:44:00 +00:00
2015-04-29 19:48:46 +00:00
if (device.RendererCommands == null)
2014-02-27 02:44:00 +00:00
{
2015-04-29 19:48:46 +00:00
lock (_nonRendererUrls)
{
_nonRendererUrls.Add(location);
return;
}
}
var sessionInfo = await _sessionManager.LogSessionActivity(device.Properties.ClientType, _appHost.ApplicationVersion.ToString(), device.Properties.UUID, device.Properties.Name, uri.OriginalString, null)
.ConfigureAwait(false);
2014-04-30 15:07:02 +00:00
2015-04-29 19:48:46 +00:00
var controller = sessionInfo.SessionController as PlayToController;
2014-03-14 17:09:22 +00:00
2015-04-29 19:48:46 +00:00
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
2014-07-30 03:31:35 +00:00
{
2015-04-29 19:48:46 +00:00
PlayableMediaTypes = profile.GetSupportedMediaTypes(),
SupportedCommands = new List<string>
2014-07-30 03:31:35 +00:00
{
2015-04-29 19:48:46 +00:00
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);
2014-03-25 05:25:03 +00:00
}
2014-03-13 21:29:25 +00:00
}
2014-07-30 03:31:35 +00:00
catch (Exception ex)
{
_logger.ErrorException("Error creating PlayTo device.", ex);
}
2014-02-27 18:00:49 +00:00
}
2014-04-30 15:07:02 +00:00
private string GetServerAddress(IPAddress localIp)
{
2015-02-10 05:54:58 +00:00
return _appHost.GetLocalApiUrl(localIp.ToString());
2014-04-30 15:07:02 +00:00
}
2014-02-27 02:44:00 +00:00
public void Dispose()
{
_deviceDiscovery.DeviceDiscovered -= _deviceDiscovery_DeviceDiscovered;
2015-04-29 19:48:46 +00:00
if (_clearNonRenderersTimer != null)
{
_clearNonRenderersTimer.Dispose();
_clearNonRenderersTimer = null;
}
2014-02-27 02:44:00 +00:00
}
}
}