Exemple #1
0
        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");
            }
        }
Exemple #2
0
        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);
                }
            }
        }
Exemple #3
0
        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);
        }
Exemple #4
0
        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);
            }
        }