public XmlElement GetItemElement(DlnaOptions options, XmlDocument doc, BaseItem item, BaseItem context, StubType? contextStubType, string deviceId, Filter filter, StreamInfo streamInfo = null) { var clientId = GetClientId(item, null); var element = doc.CreateElement(string.Empty, "item", NS_DIDL); element.SetAttribute("restricted", "1"); element.SetAttribute("id", clientId); if (context != null) { element.SetAttribute("parentID", GetClientId(context, contextStubType)); } else { var parent = item.DisplayParentId; if (parent.HasValue) { element.SetAttribute("parentID", GetClientId(parent.Value, null)); } } //AddBookmarkInfo(item, user, element); AddGeneralProperties(item, null, context, element, filter); // refID? // storeAttribute(itemNode, object, ClassProperties.REF_ID, false); var hasMediaSources = item as IHasMediaSources; if (hasMediaSources != null) { if (string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase)) { AddAudioResource(options, element, hasMediaSources, deviceId, filter, streamInfo); } else if (string.Equals(item.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase)) { AddVideoResource(options, element, hasMediaSources, deviceId, filter, streamInfo); } } AddCover(item, context, null, element); return element; }
public string GetItemDidl(DlnaOptions options, BaseItem item, BaseItem context, string deviceId, Filter filter, StreamInfo streamInfo) { var result = new XmlDocument(); var didl = result.CreateElement(string.Empty, "DIDL-Lite", NS_DIDL); didl.SetAttribute("xmlns:dc", NS_DC); didl.SetAttribute("xmlns:dlna", NS_DLNA); didl.SetAttribute("xmlns:upnp", NS_UPNP); //didl.SetAttribute("xmlns:sec", NS_SEC); foreach (var att in _profile.XmlRootAttributes) { didl.SetAttribute(att.Name, att.Value); } result.AppendChild(didl); result.DocumentElement.AppendChild(GetItemElement(options, result, item, context, null, deviceId, filter, streamInfo)); return result.DocumentElement.OuterXml; }
private StubType? GetDisplayStubType(BaseItem item, BaseItem context, DlnaOptions options) { if (context == null || context.IsFolder) { var movie = item as Movie; if (movie != null && options.EnableEnhancedMovies) { if (movie.GetTrailerIds().Count > 0 || movie.SpecialFeatureIds.Count > 0) { return StubType.Folder; } if (EnablePeopleDisplay(item)) { return StubType.Folder; } } } return null; }
private void AddAudioResource(DlnaOptions options, XmlElement container, IHasMediaSources audio, string deviceId, Filter filter, StreamInfo streamInfo = null) { var res = container.OwnerDocument.CreateElement(string.Empty, "res", NS_DIDL); if (streamInfo == null) { var sources = _mediaSourceManager.GetStaticMediaSources(audio, true, _user).ToList(); streamInfo = new StreamBuilder(_mediaEncoder, GetStreamBuilderLogger(options)).BuildAudioItem(new AudioOptions { ItemId = GetClientId(audio), MediaSources = sources, Profile = _profile, DeviceId = deviceId }); } var url = streamInfo.ToDlnaUrl(_serverAddress, _accessToken); res.InnerText = url; var mediaSource = streamInfo.MediaSource; if (mediaSource.RunTimeTicks.HasValue) { res.SetAttribute("duration", TimeSpan.FromTicks(mediaSource.RunTimeTicks.Value).ToString("c", _usCulture)); } if (filter.Contains("res@size")) { if (streamInfo.IsDirectStream || streamInfo.EstimateContentLength) { var size = streamInfo.TargetSize; if (size.HasValue) { res.SetAttribute("size", size.Value.ToString(_usCulture)); } } } var targetAudioBitrate = streamInfo.TargetAudioBitrate; var targetSampleRate = streamInfo.TargetAudioSampleRate; var targetChannels = streamInfo.TargetAudioChannels; if (targetChannels.HasValue) { res.SetAttribute("nrAudioChannels", targetChannels.Value.ToString(_usCulture)); } if (targetSampleRate.HasValue) { res.SetAttribute("sampleFrequency", targetSampleRate.Value.ToString(_usCulture)); } if (targetAudioBitrate.HasValue) { res.SetAttribute("bitrate", targetAudioBitrate.Value.ToString(_usCulture)); } var mediaProfile = _profile.GetAudioMediaProfile(streamInfo.Container, streamInfo.AudioCodec, targetChannels, targetAudioBitrate); var filename = url.Substring(0, url.IndexOf('?')); var mimeType = mediaProfile == null || string.IsNullOrEmpty(mediaProfile.MimeType) ? MimeTypes.GetMimeType(filename) : mediaProfile.MimeType; var contentFeatures = new ContentFeatureBuilder(_profile).BuildAudioHeader(streamInfo.Container, streamInfo.TargetAudioCodec, targetAudioBitrate, targetSampleRate, targetChannels, streamInfo.IsDirectStream, streamInfo.RunTimeTicks, streamInfo.TranscodeSeekInfo); res.SetAttribute("protocolInfo", String.Format( "http-get:*:{0}:{1}", mimeType, contentFeatures )); container.AppendChild(res); }
private void AddVideoResource(DlnaOptions options, XmlElement container, IHasMediaSources video, string deviceId, Filter filter, StreamInfo streamInfo = null) { if (streamInfo == null) { var sources = _mediaSourceManager.GetStaticMediaSources(video, true, _user).ToList(); streamInfo = new StreamBuilder(_mediaEncoder, GetStreamBuilderLogger(options)).BuildVideoItem(new VideoOptions { ItemId = GetClientId(video), MediaSources = sources, Profile = _profile, DeviceId = deviceId, MaxBitrate = _profile.MaxStreamingBitrate }); } var targetWidth = streamInfo.TargetWidth; var targetHeight = streamInfo.TargetHeight; var contentFeatureList = new ContentFeatureBuilder(_profile).BuildVideoHeader(streamInfo.Container, streamInfo.VideoCodec, streamInfo.AudioCodec, targetWidth, targetHeight, streamInfo.TargetVideoBitDepth, streamInfo.TargetVideoBitrate, streamInfo.TargetTimestamp, streamInfo.IsDirectStream, streamInfo.RunTimeTicks, streamInfo.TargetVideoProfile, streamInfo.TargetVideoLevel, streamInfo.TargetFramerate, streamInfo.TargetPacketLength, streamInfo.TranscodeSeekInfo, streamInfo.IsTargetAnamorphic, streamInfo.TargetRefFrames, streamInfo.TargetVideoStreamCount, streamInfo.TargetAudioStreamCount, streamInfo.TargetVideoCodecTag); foreach (var contentFeature in contentFeatureList) { AddVideoResource(container, video, deviceId, filter, contentFeature, streamInfo); } foreach (var subtitle in streamInfo.GetSubtitleProfiles(false, _serverAddress, _accessToken)) { if (subtitle.DeliveryMethod == SubtitleDeliveryMethod.External) { var subtitleAdded = AddSubtitleElement(container, subtitle); if (subtitleAdded && _profile.EnableSingleSubtitleLimit) { break; } } } }
private ILogger GetStreamBuilderLogger(DlnaOptions options) { if (options.EnableDebugLog) { return _logger; } return new NullLogger(); }
/// <summary> /// Initializes a new instance of the <see cref="ServerConfiguration" /> class. /// </summary> public ServerConfiguration() : base() { MediaEncodingQuality = EncodingQuality.Auto; ImageSavingConvention = ImageSavingConvention.Compatible; HttpServerPortNumber = 8096; LegacyWebSocketPortNumber = 8945; EnableHttpLevelLogging = true; EnableDashboardResponseCaching = true; EnableAutomaticRestart = true; EnablePeoplePrefixSubFolders = true; EnableUPnP = true; DownMixAudioBoost = 2; MinResumePct = 5; MaxResumePct = 90; MinResumeDurationSeconds = Convert.ToInt32(TimeSpan.FromMinutes(5).TotalSeconds); RealtimeMonitorDelay = 30; EnableInternetProviders = true; //initial installs will need these PathSubstitutions = new PathSubstitution[] { }; MetadataRefreshDays = 30; PreferredMetadataLanguage = "en"; MetadataCountryCode = "US"; SortReplaceCharacters = new[] { ".", "+", "%" }; SortRemoveCharacters = new[] { ",", "&", "-", "{", "}", "'" }; SortRemoveWords = new[] { "the", "a", "an" }; ManualLoginClients = new string[] { }; SeasonZeroDisplayName = "Specials"; LiveTvOptions = new LiveTvOptions(); TvFileOrganizationOptions = new TvFileOrganizationOptions(); EnableRealtimeMonitor = true; List <MetadataOptions> options = new List <MetadataOptions> { new MetadataOptions(1, 1280) { ItemType = "Book" }, new MetadataOptions(1, 1280) { ItemType = "MusicAlbum" }, new MetadataOptions(1, 1280) { ItemType = "MusicArtist" }, new MetadataOptions(0, 1280) { ItemType = "Season" } }; MetadataOptions = options.ToArray(); DlnaOptions = new DlnaOptions(); UICulture = "en-us"; NotificationOptions = new NotificationOptions(); SubtitleOptions = new SubtitleOptions(); ChannelOptions = new ChannelOptions(); ChapterOptions = new ChapterOptions(); }
/// <summary> /// Initializes a new instance of the <see cref="ServerConfiguration" /> class. /// </summary> public ServerConfiguration() : base() { MediaEncodingQuality = EncodingQuality.Auto; ImageSavingConvention = ImageSavingConvention.Compatible; HttpServerPortNumber = 8096; LegacyWebSocketPortNumber = 8945; EnableHttpLevelLogging = true; EnableDashboardResponseCaching = true; EnableMovieChapterImageExtraction = true; EnableEpisodeChapterImageExtraction = false; EnableOtherVideoChapterImageExtraction = false; EnableAutomaticRestart = true; EnablePeoplePrefixSubFolders = true; EnableUPnP = true; MinResumePct = 5; MaxResumePct = 90; MinResumeDurationSeconds = Convert.ToInt32(TimeSpan.FromMinutes(5).TotalSeconds); RealtimeMonitorDelay = 30; RecentItemDays = 10; EnableInternetProviders = true; //initial installs will need these ManualLoginClients = new ManualLoginCategory[] { }; PathSubstitutions = new PathSubstitution[] { }; MetadataRefreshDays = 30; PreferredMetadataLanguage = "en"; MetadataCountryCode = "US"; SortReplaceCharacters = new[] { ".", "+", "%" }; SortRemoveCharacters = new[] { ",", "&", "-", "{", "}", "'" }; SortRemoveWords = new[] { "the", "a", "an" }; SeasonZeroDisplayName = "Specials"; LiveTvOptions = new LiveTvOptions(); TvFileOrganizationOptions = new TvFileOrganizationOptions(); EnableRealtimeMonitor = true; var options = new List<MetadataOptions> { new MetadataOptions(1, 1280) {ItemType = "Book"}, new MetadataOptions(1, 1280) {ItemType = "MusicAlbum"}, new MetadataOptions(1, 1280) {ItemType = "MusicArtist"}, new MetadataOptions(0, 1280) {ItemType = "Season"} }; MetadataOptions = options.ToArray(); DlnaOptions = new DlnaOptions(); UICulture = "en-us"; }