private async Task RespondToV2Message(EndPoint endpoint, CancellationToken cancellationToken) { string?localUrl = _config[AddressOverrideConfigKey]; if (string.IsNullOrEmpty(localUrl)) { localUrl = _appHost.GetSmartApiUrl(((IPEndPoint)endpoint).Address); } if (string.IsNullOrEmpty(localUrl)) { _logger.LogWarning("Unable to respond to udp request because the local ip address could not be determined."); return; } var response = new ServerDiscoveryInfo(localUrl, _appHost.SystemId, _appHost.FriendlyName); try { await _udpSocket.SendToAsync(JsonSerializer.SerializeToUtf8Bytes(response), SocketFlags.None, endpoint, cancellationToken).ConfigureAwait(false); } catch (SocketException ex) { _logger.LogError(ex, "Error sending response message"); } }
private void RegisterServerEndpoints() { var udn = CreateUuid(_appHost.SystemId); var descriptorUri = "/dlna/" + udn + "/description.xml"; var bindAddresses = NetworkManager.CreateCollection( _networkManager.GetInternalBindAddresses() .Where(i => i.AddressFamily == AddressFamily.InterNetwork || (i.AddressFamily == AddressFamily.InterNetworkV6 && i.Address.ScopeId != 0))); if (bindAddresses.Count == 0) { // No interfaces returned, so use loopback. bindAddresses = _networkManager.GetLoopbacks(); } foreach (IPNetAddress address in bindAddresses) { if (address.AddressFamily == AddressFamily.InterNetworkV6) { // Not supporting IPv6 right now continue; } // Limit to LAN addresses only if (!_networkManager.IsInLocalNetwork(address)) { continue; } var fullService = "urn:schemas-upnp-org:device:MediaServer:1"; _logger.LogInformation("Registering publisher for {0} on {1}", fullService, address); var uri = new UriBuilder(_appHost.GetSmartApiUrl(address.Address) + descriptorUri); if (!string.IsNullOrEmpty(_appHost.PublishedServerUrl)) { // DLNA will only work over http, so we must reset to http:// : {port}. uri.Scheme = "http"; uri.Port = _netConfig.HttpServerPortNumber; } var device = new SsdpRootDevice { CacheLifetime = TimeSpan.FromSeconds(1800), // How long SSDP clients can cache this info. Location = uri.Uri, // Must point to the URL that serves your devices UPnP description document. Address = address.Address, PrefixLength = address.PrefixLength, 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 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(); 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 = _appHost.GetSmartApiUrl(string.Empty); } } _logger.LogDebug("MediaSources: {@MediaSources}", list); return(list); }
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", CultureInfo.InvariantCulture); } var sessionInfo = _sessionManager.LogSessionActivity("DLNA", _appHost.ApplicationVersionString, uuid, null, uri.OriginalString, null); var controller = sessionInfo.SessionControllers.OfType <PlayToController>().FirstOrDefault(); if (controller == null) { var device = await Device.CreateuPnpDeviceAsync(uri, _httpClientFactory, _logger, cancellationToken).ConfigureAwait(false); string deviceName = device.Properties.Name; _sessionManager.UpdateDeviceName(sessionInfo.Id, deviceName); string serverAddress = _appHost.GetSmartApiUrl(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[] { GeneralCommandType.VolumeDown, GeneralCommandType.VolumeUp, GeneralCommandType.Mute, GeneralCommandType.Unmute, GeneralCommandType.ToggleMute, GeneralCommandType.SetVolume, GeneralCommandType.SetAudioStreamIndex, GeneralCommandType.SetSubtitleStreamIndex, GeneralCommandType.PlayMediaSource }, SupportsMediaControl = true }); _logger.LogInformation("DLNA Session created for {0} - {1}", device.Properties.Name, device.Properties.ModelName); } }