/// <summary> /// Opens the dashboard page. /// </summary> /// <param name="page">The page.</param> /// <param name="appHost">The app host.</param> /// <param name="logger">The logger.</param> public static void OpenDashboardPage(string page, IServerApplicationHost appHost, ILogger logger) { var url = appHost.GetLocalApiUrl("localhost") + "/web/" + page; OpenUrl(url, logger); }
public override async Task Open(CancellationToken openCancellationToken) { LiveStreamCancellationTokenSource.Token.ThrowIfCancellationRequested(); var mediaSource = OriginalMediaSource; var url = mediaSource.Path; Directory.CreateDirectory(Path.GetDirectoryName(TempFilePath)); var typeName = GetType().Name; Logger.LogInformation("Opening " + typeName + " Live stream from {0}", url); var httpRequestOptions = new HttpRequestOptions { Url = url, CancellationToken = CancellationToken.None, BufferContent = false, // Increase a little bit TimeoutMs = 30000, EnableHttpCompression = false, LogResponse = true, LogResponseHeaders = true }; foreach (var header in mediaSource.RequiredHttpHeaders) { httpRequestOptions.RequestHeaders[header.Key] = header.Value; } var response = await _httpClient.SendAsync(httpRequestOptions, "GET").ConfigureAwait(false); var extension = "ts"; var requiresRemux = false; var contentType = response.ContentType ?? string.Empty; if (contentType.IndexOf("matroska", StringComparison.OrdinalIgnoreCase) != -1) { requiresRemux = true; } else if (contentType.IndexOf("mp4", StringComparison.OrdinalIgnoreCase) != -1 || contentType.IndexOf("dash", StringComparison.OrdinalIgnoreCase) != -1 || contentType.IndexOf("mpegURL", StringComparison.OrdinalIgnoreCase) != -1 || contentType.IndexOf("text/", StringComparison.OrdinalIgnoreCase) != -1) { requiresRemux = true; } // Close the stream without any sharing features if (requiresRemux) { using (response) { return; } } SetTempFilePath(extension); var taskCompletionSource = new TaskCompletionSource <bool>(); var now = DateTime.UtcNow; var _ = StartStreaming(response, taskCompletionSource, LiveStreamCancellationTokenSource.Token); //OpenedMediaSource.Protocol = MediaProtocol.File; //OpenedMediaSource.Path = tempFile; //OpenedMediaSource.ReadAtNativeFramerate = true; MediaSource.Path = _appHost.GetLocalApiUrl("127.0.0.1") + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts"; MediaSource.Protocol = MediaProtocol.Http; //OpenedMediaSource.Path = TempFilePath; //OpenedMediaSource.Protocol = MediaProtocol.File; //OpenedMediaSource.Path = _tempFilePath; //OpenedMediaSource.Protocol = MediaProtocol.File; //OpenedMediaSource.SupportsDirectPlay = false; //OpenedMediaSource.SupportsDirectStream = true; //OpenedMediaSource.SupportsTranscoding = true; await taskCompletionSource.Task.ConfigureAwait(false); }
private async Task AddDevice(UpnpDeviceInfo info, string location, CancellationToken cancellationToken) { 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); _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 serverAddress; if (info.LocalIpAddress == null || info.LocalIpAddress.Equals(IpAddressInfo.Any) || info.LocalIpAddress.Equals(IpAddressInfo.IPv6Any)) { serverAddress = await _appHost.GetLocalApiUrl(cancellationToken).ConfigureAwait(false); } else { serverAddress = _appHost.GetLocalApiUrl(info.LocalIpAddress); } 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(), GeneralCommandType.Unmute.ToString(), GeneralCommandType.ToggleMute.ToString(), GeneralCommandType.SetVolume.ToString(), GeneralCommandType.SetAudioStreamIndex.ToString(), GeneralCommandType.SetSubtitleStreamIndex.ToString() }, SupportsMediaControl = true, // 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); } }
private async Task RegisterServerEndpoints() { if (!_config.GetDlnaConfiguration().BlastAliveMessages) { return; } var cacheLength = _config.GetDlnaConfiguration().BlastAliveMessageIntervalSeconds; _Publisher.SupportPnpRootDevice = false; var addresses = (await _appHost.GetLocalIpAddresses().ConfigureAwait(false)).ToList(); var udn = CreateUuid(_appHost.SystemId); foreach (var address in addresses) { //if (IPAddress.IsLoopback(address)) //{ // // Should we allow this? // continue; //} var fullService = "urn:schemas-upnp-org:device:MediaServer:1"; _logger.Info("Registering publisher for {0} on {1}", fullService, address.ToString()); var descriptorUri = "/dlna/" + udn + "/description.xml"; var uri = new Uri(_appHost.GetLocalApiUrl(address) + descriptorUri); 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. 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. }; SetProperies(device, fullService); _Publisher.AddDevice(device); var embeddedDevices = new List <string> { "urn:schemas-upnp-org:service:ContentDirectory:1", "urn:schemas-upnp-org:service:ConnectionManager:1", //"urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:1" }; foreach (var subDevice in embeddedDevices) { var embeddedDevice = new SsdpEmbeddedDevice { FriendlyName = device.FriendlyName, Manufacturer = device.Manufacturer, ModelName = device.ModelName, Uuid = udn // This must be a globally unique value that survives reboots etc. Get from storage or embedded hardware etc. }; SetProperies(embeddedDevice, subDevice); device.AddDevice(embeddedDevice); } } }
public override async Task Open(CancellationToken openCancellationToken) { LiveStreamCancellationTokenSource.Token.ThrowIfCancellationRequested(); var mediaSource = OriginalMediaSource; var uri = new Uri(mediaSource.Path); var localPort = _networkManager.GetRandomUnusedUdpPort(); Directory.CreateDirectory(Path.GetDirectoryName(TempFilePath)); Logger.LogInformation("Opening HDHR UDP Live stream from {host}", uri.Host); var remoteAddress = IPAddress.Parse(uri.Host); var embyRemoteAddress = _networkManager.ParseIpAddress(uri.Host); IPAddress localAddress = null; using (var tcpSocket = CreateSocket(remoteAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp)) { try { tcpSocket.Connect(new IPEndPoint(remoteAddress, HdHomerunManager.HdHomeRunPort)); localAddress = ((IPEndPoint)tcpSocket.LocalEndPoint).Address; tcpSocket.Close(); } catch (Exception ex) { Logger.LogError(ex, "Unable to determine local ip address for Legacy HDHomerun stream."); return; } } var udpClient = _socketFactory.CreateUdpSocket(localPort); var hdHomerunManager = new HdHomerunManager(_socketFactory, Logger); try { // send url to start streaming await hdHomerunManager.StartStreaming(embyRemoteAddress, localAddress, localPort, _channelCommands, _numTuners, openCancellationToken).ConfigureAwait(false); } catch (Exception ex) { using (udpClient) using (hdHomerunManager) { if (!(ex is OperationCanceledException)) { Logger.LogError(ex, "Error opening live stream:"); } throw; } } var taskCompletionSource = new TaskCompletionSource <bool>(); await StartStreaming(udpClient, hdHomerunManager, remoteAddress, taskCompletionSource, LiveStreamCancellationTokenSource.Token); //OpenedMediaSource.Protocol = MediaProtocol.File; //OpenedMediaSource.Path = tempFile; //OpenedMediaSource.ReadAtNativeFramerate = true; MediaSource.Path = _appHost.GetLocalApiUrl("127.0.0.1") + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts"; MediaSource.Protocol = MediaProtocol.Http; //OpenedMediaSource.SupportsDirectPlay = false; //OpenedMediaSource.SupportsDirectStream = true; //OpenedMediaSource.SupportsTranscoding = true; //await Task.Delay(5000).ConfigureAwait(false); await taskCompletionSource.Task.ConfigureAwait(false); }
public override async Task Open(CancellationToken openCancellationToken) { LiveStreamCancellationTokenSource.Token.ThrowIfCancellationRequested(); var mediaSource = OriginalMediaSource; var url = mediaSource.Path; FileSystem.CreateDirectory(FileSystem.GetDirectoryName(TempFilePath)); var typeName = GetType().Name; Logger.Info("Opening " + typeName + " Live stream from {0}", url); var response = await _httpClient.SendAsync(new HttpRequestOptions { Url = url, CancellationToken = CancellationToken.None, BufferContent = false, // Increase a little bit TimeoutMs = 30000, EnableHttpCompression = false, LogResponse = true, LogResponseHeaders = true }, "GET").ConfigureAwait(false); var extension = "ts"; var requiresRemux = false; var contentType = response.ContentType ?? string.Empty; if (contentType.IndexOf("matroska", StringComparison.OrdinalIgnoreCase) != -1) { requiresRemux = true; } else if (contentType.IndexOf("mp4", StringComparison.OrdinalIgnoreCase) != -1 || contentType.IndexOf("dash", StringComparison.OrdinalIgnoreCase) != -1 || contentType.IndexOf("mpegURL", StringComparison.OrdinalIgnoreCase) != -1 || contentType.IndexOf("text/", StringComparison.OrdinalIgnoreCase) != -1) { requiresRemux = true; } // Close the stream without any sharing features if (requiresRemux) { using (response) { return; } } SetTempFilePath(extension); var taskCompletionSource = new TaskCompletionSource <bool>(); var now = DateTime.UtcNow; StartStreaming(response, taskCompletionSource, LiveStreamCancellationTokenSource.Token); //OpenedMediaSource.Protocol = MediaProtocol.File; //OpenedMediaSource.Path = tempFile; //OpenedMediaSource.ReadAtNativeFramerate = true; OpenedMediaSource.Path = _appHost.GetLocalApiUrl("127.0.0.1") + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts"; OpenedMediaSource.Protocol = MediaProtocol.Http; //OpenedMediaSource.Path = TempFilePath; //OpenedMediaSource.Protocol = MediaProtocol.File; //OpenedMediaSource.Path = _tempFilePath; //OpenedMediaSource.Protocol = MediaProtocol.File; //OpenedMediaSource.SupportsDirectPlay = false; //OpenedMediaSource.SupportsDirectStream = true; //OpenedMediaSource.SupportsTranscoding = true; await taskCompletionSource.Task.ConfigureAwait(false); if (OpenedMediaSource.SupportsProbing) { var elapsed = (DateTime.UtcNow - now).TotalMilliseconds; var delay = Convert.ToInt32(3000 - elapsed); if (delay > 0) { Logger.Info("Delaying shared stream by {0}ms to allow the buffer to build.", delay); await Task.Delay(delay).ConfigureAwait(false); } } }
/// <summary> /// Opens the dashboard page. /// </summary> /// <param name="page">The page.</param> /// <param name="appHost">The app host.</param> public static void OpenDashboardPage(string page, IServerApplicationHost appHost) { var url = appHost.GetLocalApiUrl("localhost") + "/web/" + page; OpenUrl(appHost, url); }
private async Task AddDevice(UpnpDeviceInfo info, string location, CancellationToken cancellationToken) { var uri = info.Location; _logger.LogDebug("Attempting to create PlayToController from location {0}", location); _logger.LogDebug("Logging session activity from location {0}", location); if (info.Headers.TryGetValue("USN", out string uuid)) { uuid = GetUuid(uuid); } else { uuid = location.GetMD5().ToString("N"); } var sessionInfo = _sessionManager.LogSessionActivity("DLNA", _appHost.ApplicationVersion, uuid, null, uri.OriginalString, null); var controller = sessionInfo.SessionControllers.OfType <PlayToController>().FirstOrDefault(); if (controller == null) { var device = await Device.CreateuPnpDeviceAsync(uri, _httpClient, _config, _logger, _timerFactory, cancellationToken).ConfigureAwait(false); string deviceName = device.Properties.Name; _sessionManager.UpdateDeviceName(sessionInfo.Id, deviceName); string serverAddress; if (info.LocalIpAddress == null || info.LocalIpAddress.Equals(IpAddressInfo.Any) || info.LocalIpAddress.Equals(IpAddressInfo.IPv6Any)) { serverAddress = await _appHost.GetLocalApiUrl(cancellationToken).ConfigureAwait(false); } else { serverAddress = _appHost.GetLocalApiUrl(info.LocalIpAddress); } controller = new PlayToController(sessionInfo, _sessionManager, _libraryManager, _logger, _dlnaManager, _userManager, _imageProcessor, serverAddress, null, _deviceDiscovery, _userDataManager, _localization, _mediaSourceManager, _config, _mediaEncoder); sessionInfo.AddController(controller); 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(), GeneralCommandType.Unmute.ToString(), GeneralCommandType.ToggleMute.ToString(), GeneralCommandType.SetVolume.ToString(), GeneralCommandType.SetAudioStreamIndex.ToString(), GeneralCommandType.SetSubtitleStreamIndex.ToString(), GeneralCommandType.PlayMediaSource.ToString() }, SupportsMediaControl = true }); _logger.LogInformation("DLNA Session created for {0} - {1}", device.Properties.Name, device.Properties.ModelName); } }
private async void _deviceDiscovery_DeviceDiscovered(object sender, GenericEventArgs <UpnpDeviceInfo> e) { if (_disposed) { return; } var info = e.Argument; string usn; if (!info.Headers.TryGetValue("USN", out usn)) { usn = string.Empty; } string nt; if (!info.Headers.TryGetValue("NT", out nt)) { nt = string.Empty; } // Filter device type if (usn.IndexOf("WANIPConnection:", StringComparison.OrdinalIgnoreCase) == -1 && nt.IndexOf("WANIPConnection:", StringComparison.OrdinalIgnoreCase) == -1 && usn.IndexOf("WANPPPConnection:", StringComparison.OrdinalIgnoreCase) == -1 && nt.IndexOf("WANPPPConnection:", StringComparison.OrdinalIgnoreCase) == -1) { return; } var identifier = string.IsNullOrWhiteSpace(usn) ? nt : usn; if (info.Location == null) { return; } lock (_usnsHandled) { if (_usnsHandled.Contains(identifier)) { return; } _usnsHandled.Add(identifier); } _logger.Debug("Found NAT device: " + identifier); IPAddress address; if (IPAddress.TryParse(info.Location.Host, out address)) { // The Handle method doesn't need the port var endpoint = new IPEndPoint(address, info.Location.Port); IPAddress localAddress = null; try { var localAddressString = await _appHost.GetLocalApiUrl().ConfigureAwait(false); Uri uri; if (Uri.TryCreate(localAddressString, UriKind.Absolute, out uri)) { localAddressString = uri.Host; if (!IPAddress.TryParse(localAddressString, out localAddress)) { return; } } } catch (Exception ex) { return; } if (_disposed) { return; } _logger.Debug("Calling Nat.Handle on " + identifier); NatUtility.Handle(localAddress, info, endpoint, NatProtocol.Upnp); } }
private string GetServerAddress(IPAddress localIp) { return(_appHost.GetLocalApiUrl(localIp.ToString())); }
private async Task <IEnumerable <MediaSourceInfo> > GetMediaSourcesInternal(IHasMediaSources item, CancellationToken cancellationToken) { IEnumerable <MediaSourceInfo> sources; var forceRequireOpening = false; try { if (item is ILiveTvRecording) { sources = await _liveTvManager.GetRecordingMediaSources(item.Id.ToString("N"), cancellationToken) .ConfigureAwait(false); } else { sources = await _liveTvManager.GetChannelMediaSources(item.Id.ToString("N"), cancellationToken) .ConfigureAwait(false); } } catch (NotImplementedException) { var hasMediaSources = (IHasMediaSources)item; sources = _mediaSourceManager.GetStaticMediaSources(hasMediaSources, false) .ToList(); forceRequireOpening = true; } var list = sources.ToList(); var serverUrl = await _appHost.GetLocalApiUrl().ConfigureAwait(false); foreach (var source in list) { source.Type = MediaSourceType.Default; source.BufferMs = source.BufferMs ?? 1500; if (source.RequiresOpening || forceRequireOpening) { source.RequiresOpening = true; } if (source.RequiresOpening) { var openKeys = new List <string>(); openKeys.Add(item.GetType().Name); openKeys.Add(item.Id.ToString("N")); openKeys.Add(source.Id ?? string.Empty); source.OpenToken = string.Join(StreamIdDelimeterString, openKeys.ToArray()); } // Dummy this up so that direct play checks can still run if (string.IsNullOrEmpty(source.Path) && source.Protocol == MediaProtocol.Http) { source.Path = serverUrl; } } _logger.Debug("MediaSources: {0}", _jsonSerializer.SerializeToString(list)); return(list); }
private async Task <IEnumerable <MediaSourceInfo> > GetMediaSourcesInternal(BaseItem item, ActiveRecordingInfo activeRecordingInfo, CancellationToken cancellationToken) { IEnumerable <MediaSourceInfo> sources; var forceRequireOpening = false; try { if (activeRecordingInfo != null) { sources = await EmbyTV.EmbyTV.Current.GetRecordingStreamMediaSources(activeRecordingInfo, cancellationToken) .ConfigureAwait(false); } else { sources = await _liveTvManager.GetChannelMediaSources(item, cancellationToken) .ConfigureAwait(false); } } catch (NotImplementedException) { sources = _mediaSourceManager.GetStaticMediaSources(item, false); forceRequireOpening = true; } var list = sources.ToList(); var serverUrl = await _appHost.GetLocalApiUrl(cancellationToken).ConfigureAwait(false); foreach (var source in list) { source.Type = MediaSourceType.Default; source.BufferMs ??= 1500; if (source.RequiresOpening || forceRequireOpening) { source.RequiresOpening = true; } if (source.RequiresOpening) { var openKeys = new List <string> { item.GetType().Name, item.Id.ToString("N", CultureInfo.InvariantCulture), source.Id ?? string.Empty }; source.OpenToken = string.Join(StreamIdDelimiter, openKeys); } // Dummy this up so that direct play checks can still run if (string.IsNullOrEmpty(source.Path) && source.Protocol == MediaProtocol.Http) { source.Path = serverUrl; } } _logger.LogDebug("MediaSources: {@MediaSources}", list); return(list); }
/// <summary> /// Opens the swagger. /// </summary> /// <param name="appHost">The app host.</param> /// <param name="logger">The logger.</param> public static void OpenSwagger(IServerApplicationHost appHost, ILogger logger) { var url = appHost.GetLocalApiUrl("localhost") + "/swagger-ui/index.html"; OpenUrl(url, logger); }
private async Task RegisterServerEndpoints() { var addresses = await _appHost.GetLocalIpAddresses().ConfigureAwait(false); var udn = CreateUuid(_appHost.SystemId); var descriptorUri = "/dlna/" + udn + "/description.xml"; foreach (var address in addresses) { if (address.AddressFamily == AddressFamily.InterNetworkV6) { // Not supporting IPv6 right now continue; } // Limit to LAN addresses only if (!_networkManager.IsAddressInSubnets(address, true, true)) { continue; } var fullService = "urn:schemas-upnp-org:device:MediaServer:1"; _logger.LogInformation("Registering publisher for {0} on {1}", fullService, address); var uri = new Uri(_appHost.GetLocalApiUrl(address) + descriptorUri); var device = new SsdpRootDevice { CacheLifetime = TimeSpan.FromSeconds(1800), // How long SSDP clients can cache this info. Location = uri, // Must point to the URL that serves your devices UPnP description document. Address = address, SubnetMask = _networkManager.GetLocalIpSubnetMask(address), FriendlyName = "Jellyfin", Manufacturer = "Jellyfin", ModelName = "Jellyfin Server", Uuid = udn // This must be a globally unique value that survives reboots etc. Get from storage or embedded hardware etc. }; SetProperies(device, fullService); _publisher.AddDevice(device); var embeddedDevices = new[] { "urn:schemas-upnp-org:service:ContentDirectory:1", "urn:schemas-upnp-org:service:ConnectionManager:1", // "urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:1" }; foreach (var subDevice in embeddedDevices) { var embeddedDevice = new SsdpEmbeddedDevice { FriendlyName = device.FriendlyName, Manufacturer = device.Manufacturer, ModelName = device.ModelName, Uuid = udn // This must be a globally unique value that survives reboots etc. Get from storage or embedded hardware etc. }; SetProperies(embeddedDevice, subDevice); device.AddDevice(embeddedDevice); } } }
private async void _deviceDiscovery_DeviceDiscovered(object sender, GenericEventArgs <UpnpDeviceInfo> e) { if (_disposed) { return; } var info = e.Argument; if (!info.Headers.TryGetValue("USN", out string usn)) { usn = string.Empty; } if (!info.Headers.TryGetValue("NT", out string nt)) { nt = string.Empty; } // Filter device type if (usn.IndexOf("WANIPConnection:", StringComparison.OrdinalIgnoreCase) == -1 && nt.IndexOf("WANIPConnection:", StringComparison.OrdinalIgnoreCase) == -1 && usn.IndexOf("WANPPPConnection:", StringComparison.OrdinalIgnoreCase) == -1 && nt.IndexOf("WANPPPConnection:", StringComparison.OrdinalIgnoreCase) == -1) { return; } var identifier = string.IsNullOrWhiteSpace(usn) ? nt : usn; if (info.Location == null) { return; } lock (_usnsHandled) { if (_usnsHandled.Contains(identifier)) { return; } _usnsHandled.Add(identifier); } _logger.LogDebug("Found NAT device: " + identifier); if (IPAddress.TryParse(info.Location.Host, out var address)) { // The Handle method doesn't need the port var endpoint = new IPEndPoint(address, info.Location.Port); IPAddress localAddress = null; try { var localAddressString = await _appHost.GetLocalApiUrl(CancellationToken.None).ConfigureAwait(false); if (Uri.TryCreate(localAddressString, UriKind.Absolute, out var uri)) { localAddressString = uri.Host; if (!IPAddress.TryParse(localAddressString, out localAddress)) { return; } } } catch (Exception ex) { _logger.LogError(ex, "Error"); return; } if (_disposed) { return; } // This should never happen, but the Handle method will throw ArgumentNullException if it does if (localAddress == null) { return; } var natManager = _natManager; if (natManager != null) { await natManager.Handle(localAddress, info, endpoint, NatProtocol.Upnp).ConfigureAwait(false); } } }
private async Task RegisterServerEndpoints() { 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)) //{ // // Should we allow this? // continue; //} var addressString = address.ToString(); var udn = (addressString).GetMD5().ToString("N"); var services = new List <string> { "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" }; 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('.', '-'); 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); } } }