public string GetItemDidl(BaseItem item, User user, BaseItem context, string deviceId, Filter filter, StreamInfo streamInfo) { var settings = new XmlWriterSettings { Encoding = Encoding.UTF8, CloseOutput = false, OmitXmlDeclaration = true, ConformanceLevel = ConformanceLevel.Fragment }; using (StringWriter builder = new StringWriterWithEncoding(Encoding.UTF8)) { using (var writer = XmlWriter.Create(builder, settings)) { //writer.WriteStartDocument(); writer.WriteStartElement(string.Empty, "DIDL-Lite", NS_DIDL); writer.WriteAttributeString("xmlns", "dc", null, NS_DC); writer.WriteAttributeString("xmlns", "dlna", null, NS_DLNA); writer.WriteAttributeString("xmlns", "upnp", null, NS_UPNP); //didl.SetAttribute("xmlns:sec", NS_SEC); WriteXmlRootAttributes(_profile, writer); WriteItemElement(writer, item, user, context, null, deviceId, filter, streamInfo); writer.WriteFullEndElement(); //writer.WriteEndDocument(); } return(builder.ToString()); } }
private void AddVideoResource(XmlWriter writer, BaseItem video, string deviceId, Filter filter, StreamInfo streamInfo = null) { if (streamInfo == null) { var sources = _mediaSourceManager.GetStaticMediaSources(video, true, _user); streamInfo = new StreamBuilder(_mediaEncoder, _logger).BuildVideoItem(new VideoOptions { ItemId = video.Id, MediaSources = sources.ToArray(), Profile = _profile, DeviceId = deviceId, MaxBitrate = _profile.MaxStreamingBitrate }); } var targetWidth = streamInfo.TargetWidth; var targetHeight = streamInfo.TargetHeight; var contentFeatureList = new ContentFeatureBuilder(_profile).BuildVideoHeader(streamInfo.Container, streamInfo.TargetVideoCodec.FirstOrDefault(), streamInfo.TargetAudioCodec.FirstOrDefault(), targetWidth, targetHeight, streamInfo.TargetVideoBitDepth, streamInfo.TargetVideoBitrate, streamInfo.TargetTimestamp, streamInfo.IsDirectStream, streamInfo.RunTimeTicks ?? 0, streamInfo.TargetVideoProfile, streamInfo.TargetVideoLevel, streamInfo.TargetFramerate ?? 0, streamInfo.TargetPacketLength, streamInfo.TranscodeSeekInfo, streamInfo.IsTargetAnamorphic, streamInfo.IsTargetInterlaced, streamInfo.TargetRefFrames, streamInfo.TargetVideoStreamCount, streamInfo.TargetAudioStreamCount, streamInfo.TargetVideoCodecTag, streamInfo.IsTargetAVC); foreach (var contentFeature in contentFeatureList) { AddVideoResource(writer, filter, contentFeature, streamInfo); } var subtitleProfiles = streamInfo.GetSubtitleProfiles(_mediaEncoder, false, _serverAddress, _accessToken); foreach (var subtitle in subtitleProfiles) { if (subtitle.DeliveryMethod != SubtitleDeliveryMethod.External) { continue; } var subtitleAdded = AddSubtitleElement(writer, subtitle); if (subtitleAdded && _profile.EnableSingleSubtitleLimit) { break; } } }
private void AddVideoResource(XmlWriter writer, Filter filter, string contentFeatures, StreamInfo streamInfo) { writer.WriteStartElement(string.Empty, "res", NS_DIDL); var url = NormalizeDlnaMediaUrl(streamInfo.ToUrl(_serverAddress, _accessToken)); var mediaSource = streamInfo.MediaSource; if (mediaSource.RunTimeTicks.HasValue) { writer.WriteAttributeString("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) { writer.WriteAttributeString("size", size.Value.ToString(_usCulture)); } } } var totalBitrate = streamInfo.TargetTotalBitrate; var targetSampleRate = streamInfo.TargetAudioSampleRate; var targetChannels = streamInfo.TargetAudioChannels; var targetWidth = streamInfo.TargetWidth; var targetHeight = streamInfo.TargetHeight; if (targetChannels.HasValue) { writer.WriteAttributeString("nrAudioChannels", targetChannels.Value.ToString(_usCulture)); } if (filter.Contains("res@resolution")) { if (targetWidth.HasValue && targetHeight.HasValue) { writer.WriteAttributeString( "resolution", string.Format( CultureInfo.InvariantCulture, "{0}x{1}", targetWidth.Value, targetHeight.Value)); } } if (targetSampleRate.HasValue) { writer.WriteAttributeString("sampleFrequency", targetSampleRate.Value.ToString(_usCulture)); } if (totalBitrate.HasValue) { writer.WriteAttributeString("bitrate", totalBitrate.Value.ToString(_usCulture)); } var mediaProfile = _profile.GetVideoMediaProfile(streamInfo.Container, streamInfo.TargetAudioCodec.FirstOrDefault(), streamInfo.TargetVideoCodec.FirstOrDefault(), streamInfo.TargetAudioBitrate, targetWidth, targetHeight, streamInfo.TargetVideoBitDepth, streamInfo.TargetVideoProfile, streamInfo.TargetVideoLevel, streamInfo.TargetFramerate ?? 0, streamInfo.TargetPacketLength, streamInfo.TargetTimestamp, streamInfo.IsTargetAnamorphic, streamInfo.IsTargetInterlaced, streamInfo.TargetRefFrames, streamInfo.TargetVideoStreamCount, streamInfo.TargetAudioStreamCount, streamInfo.TargetVideoCodecTag, streamInfo.IsTargetAVC); var filename = url.Substring(0, url.IndexOf('?', StringComparison.Ordinal)); var mimeType = mediaProfile == null || string.IsNullOrEmpty(mediaProfile.MimeType) ? MimeTypes.GetMimeType(filename) : mediaProfile.MimeType; writer.WriteAttributeString( "protocolInfo", string.Format( CultureInfo.InvariantCulture, "http-get:*:{0}:{1}", mimeType, contentFeatures)); writer.WriteString(url); writer.WriteFullEndElement(); }
private void AddGeneralProperties(BaseItem item, StubType?itemStubType, BaseItem context, XmlWriter writer, Filter filter) { AddCommonFields(item, itemStubType, context, writer, filter); var audio = item as Audio; if (audio != null) { foreach (var artist in audio.Artists) { AddValue(writer, "upnp", "artist", artist, NS_UPNP); } if (!string.IsNullOrEmpty(audio.Album)) { AddValue(writer, "upnp", "album", audio.Album, NS_UPNP); } foreach (var artist in audio.AlbumArtists) { AddAlbumArtist(writer, artist); } } var album = item as MusicAlbum; if (album != null) { foreach (var artist in album.AlbumArtists) { AddAlbumArtist(writer, artist); AddValue(writer, "upnp", "artist", artist, NS_UPNP); } foreach (var artist in album.Artists) { AddValue(writer, "upnp", "artist", artist, NS_UPNP); } } var musicVideo = item as MusicVideo; if (musicVideo != null) { foreach (var artist in musicVideo.Artists) { AddValue(writer, "upnp", "artist", artist, NS_UPNP); AddAlbumArtist(writer, artist); } if (!string.IsNullOrEmpty(musicVideo.Album)) { AddValue(writer, "upnp", "album", musicVideo.Album, NS_UPNP); } } if (item.IndexNumber.HasValue) { AddValue(writer, "upnp", "originalTrackNumber", item.IndexNumber.Value.ToString(_usCulture), NS_UPNP); if (item is Episode) { AddValue(writer, "upnp", "episodeNumber", item.IndexNumber.Value.ToString(_usCulture), NS_UPNP); } } }
/// <summary> /// Adds fields used by both items and folders /// </summary> private void AddCommonFields(BaseItem item, StubType?itemStubType, BaseItem context, XmlWriter writer, Filter filter) { // Don't filter on dc:title because not all devices will include it in the filter // MediaMonkey for example won't display content without a title //if (filter.Contains("dc:title")) { AddValue(writer, "dc", "title", GetDisplayName(item, itemStubType, context), NS_DC); } WriteObjectClass(writer, item, itemStubType); if (filter.Contains("dc:date")) { if (item.PremiereDate.HasValue) { AddValue(writer, "dc", "date", item.PremiereDate.Value.ToString("o"), NS_DC); } } if (filter.Contains("upnp:genre")) { foreach (var genre in item.Genres) { AddValue(writer, "upnp", "genre", genre, NS_UPNP); } } foreach (var studio in item.Studios) { AddValue(writer, "upnp", "publisher", studio, NS_UPNP); } if (filter.Contains("dc:description")) { var desc = item.Overview; if (!string.IsNullOrWhiteSpace(desc)) { AddValue(writer, "dc", "description", desc, NS_DC); } } if (filter.Contains("upnp:longDescription")) { if (!string.IsNullOrWhiteSpace(item.Overview)) { AddValue(writer, "upnp", "longDescription", item.Overview, NS_UPNP); } } if (!string.IsNullOrEmpty(item.OfficialRating)) { if (filter.Contains("dc:rating")) { AddValue(writer, "dc", "rating", item.OfficialRating, NS_DC); } if (filter.Contains("upnp:rating")) { AddValue(writer, "upnp", "rating", item.OfficialRating, NS_UPNP); } } AddPeople(item, writer); }
public void WriteFolderElement(XmlWriter writer, BaseItem folder, StubType?stubType, BaseItem context, int childCount, Filter filter, string requestedId = null) { writer.WriteStartElement(string.Empty, "container", NS_DIDL); writer.WriteAttributeString("restricted", "0"); writer.WriteAttributeString("searchable", "1"); writer.WriteAttributeString("childCount", childCount.ToString(_usCulture)); var clientId = GetClientId(folder, stubType); if (string.Equals(requestedId, "0")) { writer.WriteAttributeString("id", "0"); writer.WriteAttributeString("parentID", "-1"); } else { writer.WriteAttributeString("id", clientId); if (context != null) { writer.WriteAttributeString("parentID", GetClientId(context, null)); } else { var parent = folder.DisplayParentId; if (!parent.HasValue) { writer.WriteAttributeString("parentID", "0"); } else { writer.WriteAttributeString("parentID", GetClientId(parent.Value, null)); } } } AddGeneralProperties(folder, stubType, context, writer, filter); AddCover(folder, context, stubType, writer); writer.WriteFullEndElement(); }
private void AddAudioResource(DlnaOptions options, XmlWriter writer, IHasMediaSources audio, string deviceId, Filter filter, StreamInfo streamInfo = null) { writer.WriteStartElement(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); var mediaSource = streamInfo.MediaSource; if (mediaSource.RunTimeTicks.HasValue) { writer.WriteAttributeString("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) { writer.WriteAttributeString("size", size.Value.ToString(_usCulture)); } } } var targetAudioBitrate = streamInfo.TargetAudioBitrate; var targetSampleRate = streamInfo.TargetAudioSampleRate; var targetChannels = streamInfo.TargetAudioChannels; var targetAudioBitDepth = streamInfo.TargetAudioBitDepth; if (targetChannels.HasValue) { writer.WriteAttributeString("nrAudioChannels", targetChannels.Value.ToString(_usCulture)); } if (targetSampleRate.HasValue) { writer.WriteAttributeString("sampleFrequency", targetSampleRate.Value.ToString(_usCulture)); } if (targetAudioBitrate.HasValue) { writer.WriteAttributeString("bitrate", targetAudioBitrate.Value.ToString(_usCulture)); } var mediaProfile = _profile.GetAudioMediaProfile(streamInfo.Container, streamInfo.TargetAudioCodec, targetChannels, targetAudioBitrate, targetSampleRate, targetAudioBitDepth); var filename = url.Substring(0, url.IndexOf('?')); var mimeType = mediaProfile == null || string.IsNullOrEmpty(mediaProfile.MimeType) ? GetMimeType(filename) : mediaProfile.MimeType; var contentFeatures = new ContentFeatureBuilder(_profile).BuildAudioHeader(streamInfo.Container, streamInfo.TargetAudioCodec, targetAudioBitrate, targetSampleRate, targetChannels, targetAudioBitDepth, streamInfo.IsDirectStream, streamInfo.RunTimeTicks, streamInfo.TranscodeSeekInfo); writer.WriteAttributeString("protocolInfo", String.Format( "http-get:*:{0}:{1}", mimeType, contentFeatures )); writer.WriteString(url); writer.WriteFullEndElement(); }
private void AddGeneralProperties(BaseItem item, StubType? itemStubType, BaseItem context, XmlWriter writer, Filter filter) { AddCommonFields(item, itemStubType, context, writer, filter); var hasArtists = item as IHasArtist; var hasAlbumArtists = item as IHasAlbumArtist; if (hasArtists != null) { foreach (var artist in hasArtists.Artists) { AddValue(writer, "upnp", "artist", artist, NS_UPNP); AddValue(writer, "dc", "creator", artist, NS_DC); // If it doesn't support album artists (musicvideo), then tag as both if (hasAlbumArtists == null) { AddAlbumArtist(writer, artist); } } } if (hasAlbumArtists != null) { foreach (var albumArtist in hasAlbumArtists.AlbumArtists) { AddAlbumArtist(writer, albumArtist); } } if (!string.IsNullOrWhiteSpace(item.Album)) { AddValue(writer, "upnp", "album", item.Album, NS_UPNP); } if (item.IndexNumber.HasValue) { AddValue(writer, "upnp", "originalTrackNumber", item.IndexNumber.Value.ToString(_usCulture), NS_UPNP); if (item is Episode) { AddValue(writer, "upnp", "episodeNumber", item.IndexNumber.Value.ToString(_usCulture), NS_UPNP); } } }