improve support for compressed xmltv

This commit is contained in:
Luke Pulverenti
2017-09-25 01:06:15 -04:00
parent 768f20b1bb
commit 978eedbcb7
17 changed files with 324 additions and 123 deletions

View File

@@ -36,7 +36,12 @@ namespace MediaBrowser.Model.Dlna
return ContainerProfile.ContainsContainer(Container, container);
}
public bool ContainsCodec(string codec, string container)
public bool ContainsAnyCodec(string codec, string container)
{
return ContainsAnyCodec(ContainerProfile.SplitValue(codec), container);
}
public bool ContainsAnyCodec(string[] codec, string container)
{
if (!ContainsContainer(container))
{
@@ -44,8 +49,20 @@ namespace MediaBrowser.Model.Dlna
}
var codecs = GetCodecs();
if (codecs.Length == 0)
{
return true;
}
return codecs.Length == 0 || ListHelper.ContainsIgnoreCase(codecs, ContainerProfile.SplitValue(codec)[0]);
foreach (var val in codec)
{
if (ListHelper.ContainsIgnoreCase(codecs, val))
{
return true;
}
}
return false;
}
}
}

View File

@@ -283,7 +283,7 @@ namespace MediaBrowser.Model.Dlna
var conditions = new List<ProfileCondition>();
foreach (CodecProfile i in options.Profile.CodecProfiles)
{
if (i.Type == CodecType.Audio && i.ContainsCodec(audioCodec, item.Container))
if (i.Type == CodecType.Audio && i.ContainsAnyCodec(audioCodec, item.Container))
{
bool applyConditions = true;
foreach (ProfileCondition applyCondition in i.ApplyConditions)
@@ -375,7 +375,7 @@ namespace MediaBrowser.Model.Dlna
var audioCodecProfiles = new List<CodecProfile>();
foreach (CodecProfile i in options.Profile.CodecProfiles)
{
if (i.Type == CodecType.Audio && i.ContainsCodec(transcodingProfile.AudioCodec, transcodingProfile.Container))
if (i.Type == CodecType.Audio && i.ContainsAnyCodec(transcodingProfile.AudioCodec, transcodingProfile.Container))
{
audioCodecProfiles.Add(i);
}
@@ -772,7 +772,7 @@ namespace MediaBrowser.Model.Dlna
var isFirstAppliedCodecProfile = true;
foreach (CodecProfile i in options.Profile.CodecProfiles)
{
if (i.Type == CodecType.Video && i.ContainsCodec(transcodingProfile.VideoCodec, transcodingProfile.Container))
if (i.Type == CodecType.Video && i.ContainsAnyCodec(transcodingProfile.VideoCodec, transcodingProfile.Container))
{
bool applyConditions = true;
foreach (ProfileCondition applyCondition in i.ApplyConditions)
@@ -797,7 +797,7 @@ namespace MediaBrowser.Model.Dlna
var transcodingVideoCodecs = ContainerProfile.SplitValue(transcodingProfile.VideoCodec);
foreach (var transcodingVideoCodec in transcodingVideoCodecs)
{
if (i.ContainsCodec(transcodingVideoCodec, transcodingProfile.Container))
if (i.ContainsAnyCodec(transcodingVideoCodec, transcodingProfile.Container))
{
ApplyTranscodingConditions(playlistItem, i.Conditions, transcodingVideoCodec, !isFirstAppliedCodecProfile);
isFirstAppliedCodecProfile = false;
@@ -810,7 +810,7 @@ namespace MediaBrowser.Model.Dlna
var audioTranscodingConditions = new List<ProfileCondition>();
foreach (CodecProfile i in options.Profile.CodecProfiles)
{
if (i.Type == CodecType.VideoAudio && i.ContainsCodec(playlistItem.TargetAudioCodec, transcodingProfile.Container))
if (i.Type == CodecType.VideoAudio && i.ContainsAnyCodec(playlistItem.TargetAudioCodec, transcodingProfile.Container))
{
bool applyConditions = true;
foreach (ProfileCondition applyCondition in i.ApplyConditions)
@@ -899,8 +899,10 @@ namespace MediaBrowser.Model.Dlna
return 192000;
}
private int GetAudioBitrate(string subProtocol, long? maxTotalBitrate, int? targetAudioChannels, string targetAudioCodec, MediaStream audioStream)
private int GetAudioBitrate(string subProtocol, long? maxTotalBitrate, int? targetAudioChannels, string[] targetAudioCodecs, MediaStream audioStream)
{
var targetAudioCodec = targetAudioCodecs.Length == 0 ? null : targetAudioCodecs[0];
int defaultBitrate = audioStream == null ? 192000 : audioStream.BitRate ?? GetDefaultAudioBitrateIfUnknown(audioStream);
// Reduce the bitrate if we're downmixing
@@ -1064,7 +1066,7 @@ namespace MediaBrowser.Model.Dlna
conditions = new List<ProfileCondition>();
foreach (CodecProfile i in profile.CodecProfiles)
{
if (i.Type == CodecType.Video && i.ContainsCodec(videoCodec, container))
if (i.Type == CodecType.Video && i.ContainsAnyCodec(videoCodec, container))
{
bool applyConditions = true;
foreach (ProfileCondition applyCondition in i.ApplyConditions)
@@ -1120,7 +1122,7 @@ namespace MediaBrowser.Model.Dlna
foreach (CodecProfile i in profile.CodecProfiles)
{
if (i.Type == CodecType.VideoAudio && i.ContainsCodec(audioCodec, container))
if (i.Type == CodecType.VideoAudio && i.ContainsAnyCodec(audioCodec, container))
{
bool applyConditions = true;
foreach (ProfileCondition applyCondition in i.ApplyConditions)
@@ -1260,13 +1262,13 @@ namespace MediaBrowser.Model.Dlna
}
// Look for an external or hls profile that matches the stream type (text/graphical) and doesn't require conversion
return GetExternalSubtitleProfile(subtitleStream, subtitleProfiles, playMethod, transcoderSupport, false) ??
GetExternalSubtitleProfile(subtitleStream, subtitleProfiles, playMethod, transcoderSupport, true) ??
return GetExternalSubtitleProfile(subtitleStream, subtitleProfiles, playMethod, transcoderSupport, false) ??
GetExternalSubtitleProfile(subtitleStream, subtitleProfiles, playMethod, transcoderSupport, true) ??
new SubtitleProfile
{
Method = SubtitleDeliveryMethod.Encode,
Format = subtitleStream.Codec
};
{
Method = SubtitleDeliveryMethod.Encode,
Format = subtitleStream.Codec
};
}
private static bool IsSubtitleEmbedSupported(MediaStream subtitleStream, SubtitleProfile subtitleProfile, string transcodingSubProtocol, string transcodingContainer)
@@ -1555,7 +1557,7 @@ namespace MediaBrowser.Model.Dlna
}
case ProfileConditionValue.RefFrames:
{
if (qualifiedOnly)
if (string.IsNullOrWhiteSpace(qualifier))
{
continue;
}
@@ -1565,15 +1567,15 @@ namespace MediaBrowser.Model.Dlna
{
if (condition.Condition == ProfileConditionType.Equals)
{
item.MaxRefFrames = num;
item.SetOption(qualifier, "maxrefframes", StringHelper.ToStringCultureInvariant(num));
}
else if (condition.Condition == ProfileConditionType.LessThanEqual)
{
item.MaxRefFrames = Math.Min(num, item.MaxRefFrames ?? num);
item.SetOption(qualifier, "maxrefframes", StringHelper.ToStringCultureInvariant(Math.Min(num, item.GetTargetRefFrames(qualifier) ?? num)));
}
else if (condition.Condition == ProfileConditionType.GreaterThanEqual)
{
item.MaxRefFrames = Math.Max(num, item.MaxRefFrames ?? num);
item.SetOption(qualifier, "maxrefframes", StringHelper.ToStringCultureInvariant(Math.Max(num, item.GetTargetRefFrames(qualifier) ?? num)));
}
}
break;
@@ -1605,12 +1607,16 @@ namespace MediaBrowser.Model.Dlna
}
case ProfileConditionValue.VideoProfile:
{
if (qualifiedOnly)
if (string.IsNullOrWhiteSpace(qualifier))
{
continue;
}
item.VideoProfile = (value ?? string.Empty).Split('|')[0];
if (!string.IsNullOrWhiteSpace(value))
{
// change from split by | to comma
item.SetOption(qualifier, "profile", string.Join(",", value.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries)));
}
break;
}
case ProfileConditionValue.Height:
@@ -1690,7 +1696,7 @@ namespace MediaBrowser.Model.Dlna
}
case ProfileConditionValue.VideoLevel:
{
if (qualifiedOnly)
if (string.IsNullOrWhiteSpace(qualifier))
{
continue;
}
@@ -1700,15 +1706,15 @@ namespace MediaBrowser.Model.Dlna
{
if (condition.Condition == ProfileConditionType.Equals)
{
item.VideoLevel = num;
item.SetOption(qualifier, "level", StringHelper.ToStringCultureInvariant(num));
}
else if (condition.Condition == ProfileConditionType.LessThanEqual)
{
item.VideoLevel = Math.Min(num, item.VideoLevel ?? num);
item.SetOption(qualifier, "level", StringHelper.ToStringCultureInvariant(Math.Min(num, item.GetTargetVideoLevel(qualifier) ?? num)));
}
else if (condition.Condition == ProfileConditionType.GreaterThanEqual)
{
item.VideoLevel = Math.Max(num, item.VideoLevel ?? num);
item.SetOption(qualifier, "level", StringHelper.ToStringCultureInvariant(Math.Max(num, item.GetTargetVideoLevel(qualifier) ?? num)));
}
}
break;

View File

@@ -64,8 +64,6 @@ namespace MediaBrowser.Model.Dlna
public long StartPositionTicks { get; set; }
public string VideoProfile { get; set; }
public int? SegmentLength { get; set; }
public int? MinSegments { get; set; }
public bool BreakOnNonKeyFrames { get; set; }
@@ -88,13 +86,10 @@ namespace MediaBrowser.Model.Dlna
public int? VideoBitrate { get; set; }
public int? VideoLevel { get; set; }
public int? MaxWidth { get; set; }
public int? MaxHeight { get; set; }
public int? MaxVideoBitDepth { get; set; }
public int? MaxRefFrames { get; set; }
public float? MaxFramerate { get; set; }
@@ -274,11 +269,34 @@ namespace MediaBrowser.Model.Dlna
list.Add(new NameValuePair("StartTimeTicks", StringHelper.ToStringCultureInvariant(startPositionTicks)));
}
list.Add(new NameValuePair("Level", item.VideoLevel.HasValue ? StringHelper.ToStringCultureInvariant(item.VideoLevel.Value) : string.Empty));
if (isDlna)
{
// hack alert
// dlna needs to be update to support the qualified params
var level = item.GetTargetVideoLevel("h264");
list.Add(new NameValuePair("Level", level.HasValue ? StringHelper.ToStringCultureInvariant(level.Value) : string.Empty));
}
if (isDlna)
{
// hack alert
// dlna needs to be update to support the qualified params
var refframes = item.GetTargetRefFrames("h264");
list.Add(new NameValuePair("MaxRefFrames", refframes.HasValue ? StringHelper.ToStringCultureInvariant(refframes.Value) : string.Empty));
}
list.Add(new NameValuePair("MaxRefFrames", item.MaxRefFrames.HasValue ? StringHelper.ToStringCultureInvariant(item.MaxRefFrames.Value) : string.Empty));
list.Add(new NameValuePair("MaxVideoBitDepth", item.MaxVideoBitDepth.HasValue ? StringHelper.ToStringCultureInvariant(item.MaxVideoBitDepth.Value) : string.Empty));
list.Add(new NameValuePair("Profile", item.VideoProfile ?? string.Empty));
if (isDlna)
{
// hack alert
// dlna needs to be update to support the qualified params
var profile = item.GetOption("h264", "profile");
list.Add(new NameValuePair("Profile", profile ?? string.Empty));
}
// no longer used
list.Add(new NameValuePair("Cabac", string.Empty));
@@ -559,8 +577,19 @@ namespace MediaBrowser.Model.Dlna
{
get
{
MediaStream stream = TargetVideoStream;
return stream == null || !IsDirectStream ? null : stream.RefFrames;
if (IsDirectStream)
{
return TargetVideoStream == null ? (int?)null : TargetVideoStream.RefFrames;
}
var targetVideoCodecs = TargetVideoCodec;
var videoCodec = targetVideoCodecs.Length == 0 ? null : targetVideoCodecs[0];
if (!string.IsNullOrWhiteSpace(videoCodec))
{
return GetTargetRefFrames(videoCodec);
}
return TargetVideoStream == null ? (int?)null : TargetVideoStream.RefFrames;
}
}
@@ -585,13 +614,56 @@ namespace MediaBrowser.Model.Dlna
{
get
{
MediaStream stream = TargetVideoStream;
return VideoLevel.HasValue && !IsDirectStream
? VideoLevel
: stream == null ? null : stream.Level;
if (IsDirectStream)
{
return TargetVideoStream == null ? (double?)null : TargetVideoStream.Level;
}
var targetVideoCodecs = TargetVideoCodec;
var videoCodec = targetVideoCodecs.Length == 0 ? null : targetVideoCodecs[0];
if (!string.IsNullOrWhiteSpace(videoCodec))
{
return GetTargetVideoLevel(videoCodec);
}
return TargetVideoStream == null ? (double?)null : TargetVideoStream.Level;
}
}
public double? GetTargetVideoLevel(string codec)
{
var value = GetOption(codec, "level");
if (string.IsNullOrWhiteSpace(value))
{
return null;
}
double result;
if (double.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out result))
{
return result;
}
return null;
}
public int? GetTargetRefFrames(string codec)
{
var value = GetOption(codec, "maxrefframes");
if (string.IsNullOrWhiteSpace(value))
{
return null;
}
int result;
if (int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out result))
{
return result;
}
return null;
}
/// <summary>
/// Predicts the audio sample rate that will be in the output stream
/// </summary>
@@ -613,10 +685,19 @@ namespace MediaBrowser.Model.Dlna
{
get
{
MediaStream stream = TargetVideoStream;
return !string.IsNullOrEmpty(VideoProfile) && !IsDirectStream
? VideoProfile
: stream == null ? null : stream.Profile;
if (IsDirectStream)
{
return TargetVideoStream == null ? null : TargetVideoStream.Profile;
}
var targetVideoCodecs = TargetVideoCodec;
var videoCodec = targetVideoCodecs.Length == 0 ? null : targetVideoCodecs[0];
if (!string.IsNullOrWhiteSpace(videoCodec))
{
return GetOption(videoCodec, "profile");
}
return TargetVideoStream == null ? null : TargetVideoStream.Profile;
}
}
@@ -676,7 +757,7 @@ namespace MediaBrowser.Model.Dlna
/// <summary>
/// Predicts the audio codec that will be in the output stream
/// </summary>
public string TargetAudioCodec
public string[] TargetAudioCodec
{
get
{
@@ -686,22 +767,22 @@ namespace MediaBrowser.Model.Dlna
if (IsDirectStream)
{
return inputCodec;
return string.IsNullOrWhiteSpace(inputCodec) ? new string[] { } : new[] { inputCodec };
}
foreach (string codec in AudioCodecs)
{
if (StringHelper.EqualsIgnoreCase(codec, inputCodec))
{
return codec;
return string.IsNullOrWhiteSpace(codec) ? new string[] { } : new[] { codec };
}
}
return AudioCodecs.Length == 0 ? null : AudioCodecs[0];
return AudioCodecs;
}
}
public string TargetVideoCodec
public string[] TargetVideoCodec
{
get
{
@@ -711,18 +792,18 @@ namespace MediaBrowser.Model.Dlna
if (IsDirectStream)
{
return inputCodec;
return string.IsNullOrWhiteSpace(inputCodec) ? new string[] { } : new[] { inputCodec };
}
foreach (string codec in VideoCodecs)
{
if (StringHelper.EqualsIgnoreCase(codec, inputCodec))
{
return codec;
return string.IsNullOrWhiteSpace(codec) ? new string[] { } : new[] { codec };
}
}
return VideoCodecs.Length == 0 ? null : VideoCodecs[0];
return VideoCodecs;
}
}
@@ -813,7 +894,8 @@ namespace MediaBrowser.Model.Dlna
return TargetVideoStream == null ? (bool?)null : TargetVideoStream.IsInterlaced;
}
var videoCodec = TargetVideoCodec;
var targetVideoCodecs = TargetVideoCodec;
var videoCodec = targetVideoCodecs.Length == 0 ? null : targetVideoCodecs[0];
if (!string.IsNullOrWhiteSpace(videoCodec))
{
if (string.Equals(GetOption(videoCodec, "deinterlace"), "true", StringComparison.OrdinalIgnoreCase))

View File

@@ -23,6 +23,8 @@ namespace MediaBrowser.Model.IO
/// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param>
void ExtractAll(Stream source, string targetPath, bool overwriteExistingFiles);
void ExtractAllFromGz(Stream source, string targetPath, bool overwriteExistingFiles);
/// <summary>
/// Extracts all from zip.
/// </summary>