diff options
| author | Luke Pulverenti <luke.pulverenti@gmail.com> | 2014-04-18 13:16:25 -0400 |
|---|---|---|
| committer | Luke Pulverenti <luke.pulverenti@gmail.com> | 2014-04-18 13:16:25 -0400 |
| commit | 5170042eb5efee7be005dcc5aca863b66c23a6f2 (patch) | |
| tree | bd54e8945bee9cc987e3e38720fe97eb435788d1 /MediaBrowser.Model | |
| parent | b7b6f64f0089d7ce4ff8c3c5682fd8ede7311b1b (diff) | |
support more dlna resource properties
Diffstat (limited to 'MediaBrowser.Model')
| -rw-r--r-- | MediaBrowser.Model/Configuration/ServerConfiguration.cs | 3 | ||||
| -rw-r--r-- | MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs | 126 | ||||
| -rw-r--r-- | MediaBrowser.Model/Dlna/StreamBuilder.cs | 6 | ||||
| -rw-r--r-- | MediaBrowser.Model/Dlna/StreamInfo.cs | 146 |
4 files changed, 220 insertions, 61 deletions
diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 932d5d63d..ca5f569ed 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -222,6 +222,8 @@ namespace MediaBrowser.Model.Configuration public DlnaOptions DlnaOptions { get; set; } + public double DownMixAudioBoost { get; set; } + /// <summary> /// Initializes a new instance of the <see cref="ServerConfiguration" /> class. /// </summary> @@ -242,6 +244,7 @@ namespace MediaBrowser.Model.Configuration EnablePeoplePrefixSubFolders = true; EnableUPnP = true; + DownMixAudioBoost = 2; MinResumePct = 5; MaxResumePct = 90; diff --git a/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs b/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs index 76480930f..8b5966c9a 100644 --- a/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs +++ b/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs @@ -35,17 +35,23 @@ namespace MediaBrowser.Model.Dlna private MediaFormatProfile ResolveVideoMPEG2TSFormat(string videoCodec, string audioCodec, int? width, int? height, int? bitrate, TransportStreamTimestamp timestampType) { - // String suffix = ""; - // if (isNoTimestamp(timestampType)) - // suffix = "_ISO"; - // else if (timestampType == TransportStreamTimestamp.VALID) { - // suffix = "_T"; - // } + var suffix = ""; - // String resolution = "S"; - // if ((width.intValue() > 720) || (height.intValue() > 576)) { - // resolution = "H"; - // } + switch (timestampType) + { + case TransportStreamTimestamp.NONE: + suffix = "_ISO"; + break; + case TransportStreamTimestamp.VALID: + suffix = "_T"; + break; + } + + String resolution = "S"; + if ((width.HasValue && width.Value > 720) || (height.HasValue && height.Value > 576)) + { + resolution = "H"; + } // if (videoCodec == VideoCodec.MPEG2) // { @@ -55,54 +61,60 @@ namespace MediaBrowser.Model.Dlna // profiles.add(MediaFormatProfile.MPEG_TS_JP_T); // } // return profiles; - // }if (videoCodec == VideoCodec.H264) - // { - // if (audioCodec == AudioCodec.LPCM) - // return Collections.singletonList(MediaFormatProfile.AVC_TS_HD_50_LPCM_T); - // if (audioCodec == AudioCodec.DTS) { - // if (isNoTimestamp(timestampType)) { - // return Collections.singletonList(MediaFormatProfile.AVC_TS_HD_DTS_ISO); - // } - // return Collections.singletonList(MediaFormatProfile.AVC_TS_HD_DTS_T); - // } - // if (audioCodec == AudioCodec.MP2) { - // if (isNoTimestamp(timestampType)) { - // return Collections.singletonList(MediaFormatProfile.valueOf(String.format("AVC_TS_HP_%sD_MPEG1_L2_ISO", cast(Object[])[ resolution ]))); - // } - // return Collections.singletonList(MediaFormatProfile.valueOf(String.format("AVC_TS_HP_%sD_MPEG1_L2_T", cast(Object[])[ resolution ]))); - // } - - // if (audioCodec == AudioCodec.AAC) - // return Collections.singletonList(MediaFormatProfile.valueOf(String.format("AVC_TS_MP_%sD_AAC_MULT5%s", cast(Object[])[ resolution, suffix ]))); - // if (audioCodec == AudioCodec.MP3) - // return Collections.singletonList(MediaFormatProfile.valueOf(String.format("AVC_TS_MP_%sD_MPEG1_L3%s", cast(Object[])[ resolution, suffix ]))); - // if ((audioCodec is null) || (audioCodec == AudioCodec.AC3)) { - // return Collections.singletonList(MediaFormatProfile.valueOf(String.format("AVC_TS_MP_%sD_AC3%s", cast(Object[])[ resolution, suffix ]))); - // } - // } - // else if (videoCodec == VideoCodec.VC1) { - // if ((audioCodec is null) || (audioCodec == AudioCodec.AC3)) - // { - // if ((width.intValue() > 720) || (height.intValue() > 576)) { - // return Collections.singletonList(MediaFormatProfile.VC1_TS_AP_L2_AC3_ISO); - // } - // return Collections.singletonList(MediaFormatProfile.VC1_TS_AP_L1_AC3_ISO); - // } - // if (audioCodec == AudioCodec.DTS) { - // suffix = suffix.equals("_ISO") ? suffix : "_T"; - // return Collections.singletonList(MediaFormatProfile.valueOf(String.format("VC1_TS_HD_DTS%s", cast(Object[])[ suffix ]))); - // } - // } else if ((videoCodec == VideoCodec.MPEG4) || (videoCodec == VideoCodec.MSMPEG4)) { - // if (audioCodec == AudioCodec.AAC) - // return Collections.singletonList(MediaFormatProfile.valueOf(String.format("MPEG4_P2_TS_ASP_AAC%s", cast(Object[])[ suffix ]))); - // if (audioCodec == AudioCodec.MP3) - // return Collections.singletonList(MediaFormatProfile.valueOf(String.format("MPEG4_P2_TS_ASP_MPEG1_L3%s", cast(Object[])[ suffix ]))); - // if (audioCodec == AudioCodec.MP2) - // return Collections.singletonList(MediaFormatProfile.valueOf(String.format("MPEG4_P2_TS_ASP_MPEG2_L2%s", cast(Object[])[ suffix ]))); - // if ((audioCodec is null) || (audioCodec == AudioCodec.AC3)) { - // return Collections.singletonList(MediaFormatProfile.valueOf(String.format("MPEG4_P2_TS_ASP_AC3%s", cast(Object[])[ suffix ]))); - // } // } + if (string.Equals(videoCodec, "h264", StringComparison.OrdinalIgnoreCase)) + { + if (string.Equals(audioCodec, "lpcm", StringComparison.OrdinalIgnoreCase)) + return MediaFormatProfile.AVC_TS_HD_50_LPCM_T; + + if (string.Equals(audioCodec, "dts", StringComparison.OrdinalIgnoreCase)) + { + if (timestampType == TransportStreamTimestamp.NONE) + { + return MediaFormatProfile.AVC_TS_HD_DTS_ISO; + } + return MediaFormatProfile.AVC_TS_HD_DTS_T; + } + //if (audioCodec == AudioCodec.MP2) { + // if (isNoTimestamp(timestampType)) { + // return Collections.singletonList(MediaFormatProfile.valueOf(String.format("AVC_TS_HP_%sD_MPEG1_L2_ISO", cast(Object[])[ resolution ]))); + // } + // return Collections.singletonList(MediaFormatProfile.valueOf(String.format("AVC_TS_HP_%sD_MPEG1_L2_T", cast(Object[])[ resolution ]))); + //} + + //if (audioCodec == AudioCodec.AAC) + // return Collections.singletonList(MediaFormatProfile.valueOf(String.format("AVC_TS_MP_%sD_AAC_MULT5%s", cast(Object[])[ resolution, suffix ]))); + //if (audioCodec == AudioCodec.MP3) + // return Collections.singletonList(MediaFormatProfile.valueOf(String.format("AVC_TS_MP_%sD_MPEG1_L3%s", cast(Object[])[ resolution, suffix ]))); + //if ((audioCodec is null) || (audioCodec == AudioCodec.AC3)) { + // return Collections.singletonList(MediaFormatProfile.valueOf(String.format("AVC_TS_MP_%sD_AC3%s", cast(Object[])[ resolution, suffix ]))); + //} + } + else if (string.Equals(videoCodec, "vc1", StringComparison.OrdinalIgnoreCase)) + { + if (string.IsNullOrEmpty(audioCodec) || string.Equals(audioCodec, "ac3", StringComparison.OrdinalIgnoreCase)) + { + if ((width.HasValue && width.Value > 720) || (height.HasValue && height.Value > 576)) + { + return MediaFormatProfile.VC1_TS_AP_L2_AC3_ISO; + } + return MediaFormatProfile.VC1_TS_AP_L1_AC3_ISO; + } + // if (audioCodec == AudioCodec.DTS) { + // suffix = suffix.equals("_ISO") ? suffix : "_T"; + // return Collections.singletonList(MediaFormatProfile.valueOf(String.format("VC1_TS_HD_DTS%s", cast(Object[])[ suffix ]))); + // } + //} else if ((videoCodec == VideoCodec.MPEG4) || (videoCodec == VideoCodec.MSMPEG4)) { + // if (audioCodec == AudioCodec.AAC) + // return Collections.singletonList(MediaFormatProfile.valueOf(String.format("MPEG4_P2_TS_ASP_AAC%s", cast(Object[])[ suffix ]))); + // if (audioCodec == AudioCodec.MP3) + // return Collections.singletonList(MediaFormatProfile.valueOf(String.format("MPEG4_P2_TS_ASP_MPEG1_L3%s", cast(Object[])[ suffix ]))); + // if (audioCodec == AudioCodec.MP2) + // return Collections.singletonList(MediaFormatProfile.valueOf(String.format("MPEG4_P2_TS_ASP_MPEG2_L2%s", cast(Object[])[ suffix ]))); + // if ((audioCodec is null) || (audioCodec == AudioCodec.AC3)) { + // return Collections.singletonList(MediaFormatProfile.valueOf(String.format("MPEG4_P2_TS_ASP_AC3%s", cast(Object[])[ suffix ]))); + // } + } throw new ArgumentException("Mpeg video file does not match any supported DLNA profile"); } diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index d975b1c4b..0c007d694 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -81,7 +81,7 @@ namespace MediaBrowser.Model.Dlna { ItemId = options.ItemId, MediaType = DlnaProfileType.Audio, - MediaSourceId = item.Id, + MediaSource = item, RunTimeTicks = item.RunTimeTicks }; @@ -116,6 +116,7 @@ namespace MediaBrowser.Model.Dlna { playlistItem.IsDirectStream = false; playlistItem.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo; + playlistItem.EstimateContentLength = transcodingProfile.EstimateContentLength; playlistItem.Container = transcodingProfile.Container; playlistItem.AudioCodec = transcodingProfile.AudioCodec; @@ -152,7 +153,7 @@ namespace MediaBrowser.Model.Dlna { ItemId = options.ItemId, MediaType = DlnaProfileType.Video, - MediaSourceId = item.Id, + MediaSource = item, RunTimeTicks = item.RunTimeTicks }; @@ -196,6 +197,7 @@ namespace MediaBrowser.Model.Dlna { playlistItem.IsDirectStream = false; playlistItem.Container = transcodingProfile.Container; + playlistItem.EstimateContentLength = transcodingProfile.EstimateContentLength; playlistItem.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo; playlistItem.AudioCodec = transcodingProfile.AudioCodec.Split(',').FirstOrDefault(); playlistItem.VideoCodec = transcodingProfile.VideoCodec; diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs index 6ba7fe399..b46d95af8 100644 --- a/MediaBrowser.Model/Dlna/StreamInfo.cs +++ b/MediaBrowser.Model/Dlna/StreamInfo.cs @@ -1,7 +1,9 @@ using MediaBrowser.Model.Dto; +using MediaBrowser.Model.Entities; using System; using System.Collections.Generic; using System.Globalization; +using System.Linq; namespace MediaBrowser.Model.Dlna { @@ -12,8 +14,6 @@ namespace MediaBrowser.Model.Dlna { public string ItemId { get; set; } - public string MediaSourceId { get; set; } - public bool IsDirectStream { get; set; } public DlnaProfileType MediaType { get; set; } @@ -50,6 +50,18 @@ namespace MediaBrowser.Model.Dlna public TranscodeSeekInfo TranscodeSeekInfo { get; set; } + public bool EstimateContentLength { get; set; } + + public MediaSourceInfo MediaSource { get; set; } + + public string MediaSourceId + { + get + { + return MediaSource == null ? null : MediaSource.Id; + } + } + public string ToUrl(string baseUrl) { return ToDlnaUrl(baseUrl); @@ -102,6 +114,136 @@ namespace MediaBrowser.Model.Dlna return string.Format("Params={0}", string.Join(";", list.ToArray())); } + /// <summary> + /// Returns the audio stream that will be used + /// </summary> + public MediaStream TargetAudioStream + { + get + { + if (MediaSource != null) + { + var audioStreams = MediaSource.MediaStreams.Where(i => i.Type == MediaStreamType.Audio); + + if (AudioStreamIndex.HasValue) + { + return audioStreams.FirstOrDefault(i => i.Index == AudioStreamIndex.Value); + } + + return audioStreams.FirstOrDefault(); + } + + return null; + } + } + + /// <summary> + /// Returns the video stream that will be used + /// </summary> + public MediaStream TargetVideoStream + { + get + { + if (MediaSource != null) + { + return MediaSource.MediaStreams + .FirstOrDefault(i => i.Type == MediaStreamType.Video && (i.Codec ?? string.Empty).IndexOf("jpeg", StringComparison.OrdinalIgnoreCase) == -1); + } + + return null; + } + } + + /// <summary> + /// Predicts the audio sample rate that will be in the output stream + /// </summary> + public int? TargetAudioSampleRate + { + get + { + var stream = TargetAudioStream; + return stream == null ? null : stream.SampleRate; + } + } + + /// <summary> + /// Predicts the audio bitrate that will be in the output stream + /// </summary> + public int? TargetAudioBitrate + { + get + { + var stream = TargetAudioStream; + return AudioBitrate.HasValue && !IsDirectStream + ? AudioBitrate + : stream == null ? null : stream.BitRate; + } + } + + /// <summary> + /// Predicts the audio channels that will be in the output stream + /// </summary> + public int? TargetAudioChannels + { + get + { + var stream = TargetAudioStream; + + return MaxAudioChannels.HasValue && !IsDirectStream + ? (stream.Channels.HasValue ? Math.Min(MaxAudioChannels.Value, stream.Channels.Value) : MaxAudioChannels.Value) + : stream == null ? null : stream.Channels; + } + } + + /// <summary> + /// Predicts the audio codec that will be in the output stream + /// </summary> + public string TargetAudioCodec + { + get + { + var stream = TargetAudioStream; + + return IsDirectStream + ? (stream == null ? null : stream.Codec) + : AudioCodec; + } + } + + /// <summary> + /// Predicts the audio channels that will be in the output stream + /// </summary> + public long? TargetSize + { + get + { + if (IsDirectStream) + { + return MediaSource.Bitrate; + } + + if (RunTimeTicks.HasValue) + { + var totalBitrate = 0; + + if (AudioBitrate.HasValue) + { + totalBitrate += AudioBitrate.Value; + } + if (VideoBitrate.HasValue) + { + totalBitrate += VideoBitrate.Value; + } + + return Convert.ToInt64(totalBitrate * TimeSpan.FromTicks(RunTimeTicks.Value).TotalSeconds); + } + var stream = TargetAudioStream; + + return MaxAudioChannels.HasValue && !IsDirectStream + ? (stream.Channels.HasValue ? Math.Min(MaxAudioChannels.Value, stream.Channels.Value) : MaxAudioChannels.Value) + : stream == null ? null : stream.Channels; + } + } } /// <summary> |
