mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-04-25 11:34:43 +01:00
improve support for compressed xmltv
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user