jellyfin/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs

366 lines
12 KiB
C#
Raw Normal View History

2014-06-29 17:35:05 +00:00
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Extensions;
2014-04-10 15:06:54 +00:00
using MediaBrowser.Common.Net;
2014-04-27 03:42:05 +00:00
using MediaBrowser.Controller;
2014-03-24 12:47:39 +00:00
using MediaBrowser.Controller.Configuration;
2014-04-27 03:42:05 +00:00
using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Library;
2014-09-24 01:44:05 +00:00
using MediaBrowser.Controller.Localization;
2014-03-24 12:47:39 +00:00
using MediaBrowser.Controller.Plugins;
2014-04-27 03:42:05 +00:00
using MediaBrowser.Controller.Session;
using MediaBrowser.Dlna.PlayTo;
2014-04-25 17:30:41 +00:00
using MediaBrowser.Dlna.Ssdp;
2014-03-24 12:47:39 +00:00
using MediaBrowser.Model.Logging;
using System;
2014-04-25 17:30:41 +00:00
using System.Collections.Generic;
2016-09-11 07:33:53 +00:00
using System.Linq;
2016-09-16 02:42:28 +00:00
using System.Net;
2016-06-19 06:18:29 +00:00
using System.Threading.Tasks;
using MediaBrowser.Controller.MediaEncoding;
2016-09-11 07:33:53 +00:00
using Rssdp;
2014-03-24 12:47:39 +00:00
2014-04-25 17:30:41 +00:00
namespace MediaBrowser.Dlna.Main
2014-03-24 12:47:39 +00:00
{
2014-04-25 17:30:41 +00:00
public class DlnaEntryPoint : IServerEntryPoint
2014-03-24 12:47:39 +00:00
{
private readonly IServerConfigurationManager _config;
private readonly ILogger _logger;
2014-04-27 03:42:05 +00:00
private readonly IServerApplicationHost _appHost;
2014-04-10 15:06:54 +00:00
private readonly INetworkManager _network;
2014-03-24 12:47:39 +00:00
2014-04-27 03:42:05 +00:00
private PlayToManager _manager;
private readonly ISessionManager _sessionManager;
private readonly IHttpClient _httpClient;
private readonly ILibraryManager _libraryManager;
private readonly IUserManager _userManager;
private readonly IDlnaManager _dlnaManager;
private readonly IImageProcessor _imageProcessor;
private readonly IUserDataManager _userDataManager;
2014-09-24 01:44:05 +00:00
private readonly ILocalizationManager _localization;
2015-03-07 22:43:53 +00:00
private readonly IMediaSourceManager _mediaSourceManager;
private readonly IMediaEncoder _mediaEncoder;
2015-07-23 16:32:34 +00:00
private readonly IDeviceDiscovery _deviceDiscovery;
2014-04-18 05:03:01 +00:00
private bool _ssdpHandlerStarted;
2014-04-25 17:30:41 +00:00
private bool _dlnaServerStarted;
2016-09-11 07:33:53 +00:00
private SsdpDevicePublisher _Publisher;
2014-04-18 05:03:01 +00:00
2015-12-29 03:39:38 +00:00
public DlnaEntryPoint(IServerConfigurationManager config,
ILogManager logManager,
IServerApplicationHost appHost,
INetworkManager network,
ISessionManager sessionManager,
IHttpClient httpClient,
ILibraryManager libraryManager,
IUserManager userManager,
IDlnaManager dlnaManager,
IImageProcessor imageProcessor,
IUserDataManager userDataManager,
ILocalizationManager localization,
IMediaSourceManager mediaSourceManager,
2016-09-11 07:33:53 +00:00
IDeviceDiscovery deviceDiscovery, IMediaEncoder mediaEncoder)
2014-04-25 17:30:41 +00:00
{
2014-03-24 12:47:39 +00:00
_config = config;
_appHost = appHost;
2014-04-10 15:06:54 +00:00
_network = network;
2014-04-27 03:42:05 +00:00
_sessionManager = sessionManager;
_httpClient = httpClient;
_libraryManager = libraryManager;
_userManager = userManager;
_dlnaManager = dlnaManager;
_imageProcessor = imageProcessor;
_userDataManager = userDataManager;
2014-09-24 01:44:05 +00:00
_localization = localization;
2015-03-07 22:43:53 +00:00
_mediaSourceManager = mediaSourceManager;
2015-07-23 16:32:34 +00:00
_deviceDiscovery = deviceDiscovery;
_mediaEncoder = mediaEncoder;
2014-04-25 17:30:41 +00:00
_logger = logManager.GetLogger("Dlna");
2014-03-24 12:47:39 +00:00
}
public void Run()
{
((DlnaManager)_dlnaManager).InitProfiles();
2014-04-25 17:30:41 +00:00
ReloadComponents();
2014-03-24 12:47:39 +00:00
_config.ConfigurationUpdated += _config_ConfigurationUpdated;
2014-06-29 17:35:05 +00:00
_config.NamedConfigurationUpdated += _config_NamedConfigurationUpdated;
2014-03-24 12:47:39 +00:00
}
2016-05-14 16:06:01 +00:00
private bool _lastEnableUpnP;
void _config_ConfigurationUpdated(object sender, EventArgs e)
{
2016-05-14 16:06:01 +00:00
if (_lastEnableUpnP != _config.Configuration.EnableUPnP)
{
ReloadComponents();
}
2016-05-14 16:06:01 +00:00
_lastEnableUpnP = _config.Configuration.EnableUPnP;
}
2014-06-29 17:35:05 +00:00
void _config_NamedConfigurationUpdated(object sender, ConfigurationUpdateEventArgs e)
2014-03-24 12:47:39 +00:00
{
2014-06-29 17:35:05 +00:00
if (string.Equals(e.Key, "dlna", StringComparison.OrdinalIgnoreCase))
{
ReloadComponents();
}
2014-03-24 12:47:39 +00:00
}
2016-06-19 06:18:29 +00:00
private async void ReloadComponents()
2014-03-24 12:47:39 +00:00
{
2014-06-29 17:35:05 +00:00
var options = _config.GetDlnaConfiguration();
if (!_ssdpHandlerStarted)
{
StartSsdpHandler();
}
var isServerStarted = _dlnaServerStarted;
2014-06-29 17:35:05 +00:00
if (options.EnableServer && !isServerStarted)
2014-03-24 12:47:39 +00:00
{
2016-06-19 06:18:29 +00:00
await StartDlnaServer().ConfigureAwait(false);
2014-03-24 12:47:39 +00:00
}
2014-06-29 17:35:05 +00:00
else if (!options.EnableServer && isServerStarted)
2014-03-24 12:47:39 +00:00
{
2014-04-25 17:30:41 +00:00
DisposeDlnaServer();
2014-03-24 12:47:39 +00:00
}
2014-04-27 03:42:05 +00:00
var isPlayToStarted = _manager != null;
2014-06-29 17:35:05 +00:00
if (options.EnablePlayTo && !isPlayToStarted)
2014-04-27 03:42:05 +00:00
{
StartPlayToManager();
}
2014-06-29 17:35:05 +00:00
else if (!options.EnablePlayTo && isPlayToStarted)
2014-04-27 03:42:05 +00:00
{
DisposePlayToManager();
}
2014-03-24 12:47:39 +00:00
}
2014-04-25 17:30:41 +00:00
private void StartSsdpHandler()
2014-03-24 12:47:39 +00:00
{
2014-04-25 17:30:41 +00:00
try
{
2016-09-11 07:33:53 +00:00
StartPublishing();
2016-05-14 16:06:01 +00:00
_ssdpHandlerStarted = true;
StartDeviceDiscovery();
}
catch (Exception ex)
{
_logger.ErrorException("Error starting ssdp handlers", ex);
}
}
2016-09-11 07:33:53 +00:00
private void StartPublishing()
{
_Publisher = new SsdpDevicePublisher();
}
2016-05-14 16:06:01 +00:00
private void StartDeviceDiscovery()
{
try
{
2016-09-11 07:33:53 +00:00
((DeviceDiscovery)_deviceDiscovery).Start();
2016-05-14 16:06:01 +00:00
}
catch (Exception ex)
{
_logger.ErrorException("Error starting device discovery", ex);
}
}
2016-05-14 16:06:01 +00:00
private void DisposeDeviceDiscovery()
{
try
{
((DeviceDiscovery)_deviceDiscovery).Dispose();
2014-04-25 17:30:41 +00:00
}
catch (Exception ex)
2014-03-24 12:47:39 +00:00
{
2016-05-14 16:06:01 +00:00
_logger.ErrorException("Error stopping device discovery", ex);
2014-04-25 17:30:41 +00:00
}
}
2014-04-10 15:06:54 +00:00
2016-05-14 16:06:01 +00:00
private void DisposeSsdpHandler()
{
2016-05-14 16:06:01 +00:00
DisposeDeviceDiscovery();
try
{
((DeviceDiscovery)_deviceDiscovery).Dispose();
_ssdpHandlerStarted = false;
}
catch (Exception ex)
{
_logger.ErrorException("Error stopping ssdp handlers", ex);
}
}
2016-06-19 06:18:29 +00:00
public async Task StartDlnaServer()
2014-04-25 17:30:41 +00:00
{
try
{
2016-06-19 06:18:29 +00:00
await RegisterServerEndpoints().ConfigureAwait(false);
2014-04-25 17:30:41 +00:00
_dlnaServerStarted = true;
}
catch (Exception ex)
{
_logger.ErrorException("Error registering endpoint", ex);
}
}
2016-06-19 06:18:29 +00:00
private async Task RegisterServerEndpoints()
2014-04-10 15:06:54 +00:00
{
2016-09-11 07:33:53 +00:00
if (!_config.GetDlnaConfiguration().BlastAliveMessages)
{
return;
}
2016-09-15 20:32:49 +00:00
var cacheLength = _config.GetDlnaConfiguration().BlastAliveMessageIntervalSeconds * 2;
2016-09-16 02:42:28 +00:00
_Publisher.SupportPnpRootDevice = false;
2016-09-11 07:33:53 +00:00
2016-09-16 02:42:28 +00:00
var addresses = (await _appHost.GetLocalIpAddresses().ConfigureAwait(false)).ToList();
foreach (var address in addresses)
2014-04-10 15:06:54 +00:00
{
2015-12-29 03:39:38 +00:00
//if (IPAddress.IsLoopback(address))
//{
// // Should we allow this?
// continue;
//}
var addressString = address.ToString();
2014-04-10 15:06:54 +00:00
2014-04-25 17:30:41 +00:00
var services = new List<string>
{
"urn:schemas-upnp-org:device:MediaServer:1",
"urn:schemas-upnp-org:service:ContentDirectory:1",
2015-01-31 23:12:22 +00:00
"urn:schemas-upnp-org:service:ConnectionManager:1",
2016-09-11 07:33:53 +00:00
"urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:1"
2014-04-25 17:30:41 +00:00
};
2015-12-29 03:39:38 +00:00
2016-09-11 07:33:53 +00:00
var udn = (addressString).GetMD5().ToString("N");
foreach (var fullService in services)
{
2016-09-15 06:23:39 +00:00
_logger.Info("Registering publisher for {0} on {1}", fullService, addressString);
2016-09-11 07:33:53 +00:00
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);
2014-04-18 05:03:01 +00:00
2016-09-11 07:33:53 +00:00
var serviceParts = service.Split(':');
var deviceTypeNamespace = serviceParts[0].Replace('.', '-');
2016-09-17 17:12:21 +00:00
var device = new SsdpRootDevice
2016-09-11 07:33:53 +00:00
{
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",
2016-09-17 17:12:21 +00:00
Uuid = udn
// This must be a globally unique value that survives reboots etc. Get from storage or embedded hardware etc.
};
_Publisher.AddDevice(device);
2016-09-11 07:33:53 +00:00
}
2014-03-24 12:47:39 +00:00
}
}
2014-04-27 03:42:05 +00:00
private readonly object _syncLock = new object();
private void StartPlayToManager()
{
lock (_syncLock)
{
try
{
_manager = new PlayToManager(_logger,
_sessionManager,
_libraryManager,
_userManager,
_dlnaManager,
_appHost,
_imageProcessor,
2014-07-22 01:29:06 +00:00
_deviceDiscovery,
_httpClient,
_config,
2014-09-24 01:44:05 +00:00
_userDataManager,
2015-03-07 22:43:53 +00:00
_localization,
_mediaSourceManager,
_mediaEncoder);
2014-04-27 03:42:05 +00:00
_manager.Start();
}
catch (Exception ex)
{
_logger.ErrorException("Error starting PlayTo manager", ex);
}
}
}
private void DisposePlayToManager()
{
lock (_syncLock)
{
if (_manager != null)
{
try
{
_manager.Dispose();
}
catch (Exception ex)
{
_logger.ErrorException("Error disposing PlayTo manager", ex);
}
_manager = null;
}
}
}
2014-03-24 12:47:39 +00:00
public void Dispose()
{
2014-04-25 17:30:41 +00:00
DisposeDlnaServer();
2014-04-27 03:42:05 +00:00
DisposePlayToManager();
2016-05-14 16:06:01 +00:00
DisposeSsdpHandler();
2014-04-25 17:30:41 +00:00
}
public void DisposeDlnaServer()
{
2016-09-11 07:33:53 +00:00
if (_Publisher != null)
2014-04-25 17:30:41 +00:00
{
2016-09-11 07:33:53 +00:00
var devices = _Publisher.Devices.ToList();
2016-09-12 18:10:09 +00:00
2016-09-16 02:42:28 +00:00
foreach (var device in devices)
2014-04-25 17:30:41 +00:00
{
2016-09-16 02:42:28 +00:00
var task = _Publisher.RemoveDevice(device);
Task.WaitAll(task);
}
2016-09-12 18:10:09 +00:00
//foreach (var device in devices)
//{
// try
// {
// _Publisher.RemoveDevice(device);
// }
// catch (Exception ex)
// {
// _logger.ErrorException("Error sending bye bye", ex);
// }
//}
2016-09-11 07:33:53 +00:00
_Publisher.Dispose();
2014-04-25 17:30:41 +00:00
}
_dlnaServerStarted = false;
2014-03-24 12:47:39 +00:00
}
}
}