improve support for compressed xmltv

pull/1154/head
Luke Pulverenti 7 years ago
parent 768f20b1bb
commit 978eedbcb7

@ -209,8 +209,8 @@ namespace Emby.Dlna.Didl
var targetHeight = streamInfo.TargetHeight;
var contentFeatureList = new ContentFeatureBuilder(_profile).BuildVideoHeader(streamInfo.Container,
streamInfo.TargetVideoCodec,
streamInfo.TargetAudioCodec,
streamInfo.TargetVideoCodec.FirstOrDefault(),
streamInfo.TargetAudioCodec.FirstOrDefault(),
targetWidth,
targetHeight,
streamInfo.TargetVideoBitDepth,
@ -353,8 +353,8 @@ namespace Emby.Dlna.Didl
}
var mediaProfile = _profile.GetVideoMediaProfile(streamInfo.Container,
streamInfo.TargetAudioCodec,
streamInfo.TargetVideoCodec,
streamInfo.TargetAudioCodec.FirstOrDefault(),
streamInfo.TargetVideoCodec.FirstOrDefault(),
streamInfo.TargetAudioBitrate,
targetWidth,
targetHeight,
@ -554,7 +554,7 @@ namespace Emby.Dlna.Didl
}
var mediaProfile = _profile.GetAudioMediaProfile(streamInfo.Container,
streamInfo.TargetAudioCodec,
streamInfo.TargetAudioCodec.FirstOrDefault(),
targetChannels,
targetAudioBitrate,
targetSampleRate,
@ -567,7 +567,7 @@ namespace Emby.Dlna.Didl
: mediaProfile.MimeType;
var contentFeatures = new ContentFeatureBuilder(_profile).BuildAudioHeader(streamInfo.Container,
streamInfo.TargetAudioCodec,
streamInfo.TargetAudioCodec.FirstOrDefault(),
targetAudioBitrate,
targetSampleRate,
targetChannels,

@ -13,6 +13,7 @@ using MediaBrowser.Model.System;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common.Configuration;
@ -515,7 +516,7 @@ namespace Emby.Dlna.PlayTo
{
return new ContentFeatureBuilder(profile)
.BuildAudioHeader(streamInfo.Container,
streamInfo.TargetAudioCodec,
streamInfo.TargetAudioCodec.FirstOrDefault(),
streamInfo.TargetAudioBitrate,
streamInfo.TargetAudioSampleRate,
streamInfo.TargetAudioChannels,
@ -529,8 +530,8 @@ namespace Emby.Dlna.PlayTo
{
var list = new ContentFeatureBuilder(profile)
.BuildVideoHeader(streamInfo.Container,
streamInfo.TargetVideoCodec,
streamInfo.TargetAudioCodec,
streamInfo.TargetVideoCodec.FirstOrDefault(),
streamInfo.TargetAudioCodec.FirstOrDefault(),
streamInfo.TargetWidth,
streamInfo.TargetHeight,
streamInfo.TargetVideoBitDepth,

@ -4,6 +4,7 @@ using SharpCompress.Archives.Rar;
using SharpCompress.Archives.SevenZip;
using SharpCompress.Archives.Tar;
using SharpCompress.Readers;
using SharpCompress.Readers.GZip;
using SharpCompress.Readers.Zip;
namespace Emby.Server.Implementations.Archiving
@ -72,6 +73,22 @@ namespace Emby.Server.Implementations.Archiving
}
}
public void ExtractAllFromGz(Stream source, string targetPath, bool overwriteExistingFiles)
{
using (var reader = GZipReader.Open(source))
{
var options = new ExtractionOptions();
options.ExtractFullPath = true;
if (overwriteExistingFiles)
{
options.Overwrite = true;
}
reader.WriteAllToDirectory(targetPath, options);
}
}
/// <summary>
/// Extracts all from7z.
/// </summary>

@ -667,8 +667,8 @@
<HintPath>..\packages\ServiceStack.Text.4.5.8\lib\net45\ServiceStack.Text.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="SharpCompress, Version=0.14.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\SharpCompress.0.14.0\lib\net45\SharpCompress.dll</HintPath>
<Reference Include="SharpCompress, Version=0.18.2.0, Culture=neutral, PublicKeyToken=afb0a02973931d96, processorArchitecture=MSIL">
<HintPath>..\packages\SharpCompress.0.18.2\lib\net45\SharpCompress.dll</HintPath>
</Reference>
<Reference Include="SimpleInjector, Version=4.0.8.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
<HintPath>..\packages\SimpleInjector.4.0.8\lib\net45\SimpleInjector.dll</HintPath>

@ -65,14 +65,15 @@ namespace Emby.Server.Implementations.LiveTv.Listings
if (!path.StartsWith("http", StringComparison.OrdinalIgnoreCase))
{
return path;
return UnzipIfNeeded(path, path);
}
var cacheFilename = DateTime.UtcNow.DayOfYear.ToString(CultureInfo.InvariantCulture) + "-" + DateTime.UtcNow.Hour.ToString(CultureInfo.InvariantCulture) + ".xml";
var cacheFile = Path.Combine(_config.ApplicationPaths.CachePath, "xmltv", cacheFilename);
if (_fileSystem.FileExists(cacheFile))
{
return UnzipIfNeeded(path, cacheFile);
//return UnzipIfNeeded(path, cacheFile);
return cacheFile;
}
_logger.Info("Downloading xmltv listings from {0}", path);
@ -112,28 +113,29 @@ namespace Emby.Server.Implementations.LiveTv.Listings
}
_logger.Debug("Returning xmltv path {0}", cacheFile);
return UnzipIfNeeded(path, cacheFile);
return cacheFile;
//return UnzipIfNeeded(path, cacheFile);
}
private string UnzipIfNeeded(string originalUrl, string file)
{
//var ext = Path.GetExtension(originalUrl);
//if (string.Equals(ext, ".gz", StringComparison.OrdinalIgnoreCase))
//{
// using (var stream = _fileSystem.OpenRead(file))
// {
// var tempFolder = Path.Combine(_config.ApplicationPaths.TempDirectory, Guid.NewGuid().ToString());
// _fileSystem.CreateDirectory(tempFolder);
// _zipClient.ExtractAllFromZip(stream, tempFolder, true);
// return _fileSystem.GetFiles(tempFolder, true)
// .Where(i => string.Equals(i.Extension, ".xml", StringComparison.OrdinalIgnoreCase))
// .Select(i => i.FullName)
// .FirstOrDefault();
// }
//}
var ext = Path.GetExtension(originalUrl.Split('?')[0]);
if (string.Equals(ext, ".gz", StringComparison.OrdinalIgnoreCase))
{
using (var stream = _fileSystem.OpenRead(file))
{
var tempFolder = Path.Combine(_config.ApplicationPaths.TempDirectory, Guid.NewGuid().ToString());
_fileSystem.CreateDirectory(tempFolder);
_zipClient.ExtractAllFromGz(stream, tempFolder, true);
return _fileSystem.GetFiles(tempFolder, true)
.Where(i => string.Equals(i.Extension, ".xml", StringComparison.OrdinalIgnoreCase))
.Select(i => i.FullName)
.FirstOrDefault();
}
}
return file;
}

@ -2,7 +2,7 @@
<packages>
<package id="Emby.XmlTv" version="1.0.10" targetFramework="net46" />
<package id="ServiceStack.Text" version="4.5.8" targetFramework="net46" />
<package id="SharpCompress" version="0.14.0" targetFramework="net46" />
<package id="SharpCompress" version="0.18.2" targetFramework="net46" />
<package id="SimpleInjector" version="4.0.8" targetFramework="net46" />
<package id="SQLitePCL.pretty" version="1.1.0" targetFramework="portable45-net45+win8" />
<package id="SQLitePCLRaw.core" version="1.1.8" targetFramework="net46" />

@ -691,22 +691,26 @@ namespace MediaBrowser.Controller.MediaEncoding
param += string.Format(" -r {0}", framerate.Value.ToString(_usCulture));
}
var request = state.BaseRequest;
var targetVideoCodec = state.ActualOutputVideoCodec;
if (!string.IsNullOrEmpty(request.Profile))
var request = state.BaseRequest;
var profile = state.GetRequestedProfiles(targetVideoCodec).FirstOrDefault();
if (!string.IsNullOrEmpty(profile))
{
if (!string.Equals(videoEncoder, "h264_omx", StringComparison.OrdinalIgnoreCase) &&
!string.Equals(videoEncoder, "h264_vaapi", StringComparison.OrdinalIgnoreCase) &&
!string.Equals(videoEncoder, "h264_v4l2m2m", StringComparison.OrdinalIgnoreCase))
{
// not supported by h264_omx
param += " -profile:v " + request.Profile;
param += " -profile:v " + profile;
}
}
if (!string.IsNullOrEmpty(request.Level))
var level = state.GetRequestedLevel(targetVideoCodec);
if (!string.IsNullOrEmpty(level))
{
var level = NormalizeTranscodingLevel(state.OutputVideoCodec, request.Level);
level = NormalizeTranscodingLevel(state.OutputVideoCodec, level);
// h264_qsv and h264_nvenc expect levels to be expressed as a decimal. libx264 supports decimal and non-decimal format
// also needed for libx264 due to https://trac.ffmpeg.org/ticket/3307
@ -756,7 +760,6 @@ namespace MediaBrowser.Controller.MediaEncoding
{
param += " -level " + level;
}
}
if (string.Equals(videoEncoder, "libx264", StringComparison.OrdinalIgnoreCase))
@ -834,18 +837,21 @@ namespace MediaBrowser.Controller.MediaEncoding
return false;
}
var requestedProfiles = state.GetRequestedProfiles(videoStream.Codec);
// If client is requesting a specific video profile, it must match the source
if (!string.IsNullOrEmpty(request.Profile))
if (requestedProfiles.Length > 0)
{
if (string.IsNullOrEmpty(videoStream.Profile))
{
//return false;
}
if (!string.IsNullOrEmpty(videoStream.Profile) && !string.Equals(request.Profile, videoStream.Profile, StringComparison.OrdinalIgnoreCase))
var requestedProfile = requestedProfiles[0];
if (!string.IsNullOrEmpty(videoStream.Profile) && !string.Equals(requestedProfile, videoStream.Profile, StringComparison.OrdinalIgnoreCase))
{
var currentScore = GetVideoProfileScore(videoStream.Profile);
var requestedScore = GetVideoProfileScore(request.Profile);
var requestedScore = GetVideoProfileScore(requestedProfile);
if (currentScore == -1 || currentScore > requestedScore)
{
@ -910,11 +916,12 @@ namespace MediaBrowser.Controller.MediaEncoding
}
// If a specific level was requested, the source must match or be less than
if (!string.IsNullOrEmpty(request.Level))
var level = state.GetRequestedLevel(videoStream.Codec);
if (!string.IsNullOrEmpty(level))
{
double requestLevel;
if (double.TryParse(request.Level, NumberStyles.Any, _usCulture, out requestLevel))
if (double.TryParse(level, NumberStyles.Any, _usCulture, out requestLevel))
{
if (!videoStream.Level.HasValue)
{

@ -180,6 +180,61 @@ namespace MediaBrowser.Controller.MediaEncoding
return false;
}
public string[] GetRequestedProfiles(string codec)
{
if (!string.IsNullOrWhiteSpace(BaseRequest.Profile))
{
return BaseRequest.Profile.Split(new[] { '|', ',' }, StringSplitOptions.RemoveEmptyEntries);
}
if (!string.IsNullOrWhiteSpace(codec))
{
var profile = BaseRequest.GetOption(codec, "profile");
if (!string.IsNullOrWhiteSpace(profile))
{
return profile.Split(new[] { '|', ',' }, StringSplitOptions.RemoveEmptyEntries);
}
}
return new string[] { };
}
public string GetRequestedLevel(string codec)
{
if (!string.IsNullOrWhiteSpace(BaseRequest.Level))
{
return BaseRequest.Level;
}
if (!string.IsNullOrWhiteSpace(codec))
{
return BaseRequest.GetOption(codec, "level");
}
return null;
}
public int? GetRequestedMaxRefFrames(string codec)
{
if (!string.IsNullOrWhiteSpace(BaseRequest.Level))
{
return BaseRequest.MaxRefFrames;
}
if (!string.IsNullOrWhiteSpace(codec))
{
var value = BaseRequest.GetOption(codec, "maxrefframes");
int result;
if (!string.IsNullOrWhiteSpace(value) && int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out result))
{
return result;
}
}
return null;
}
public bool IsVideoRequest { get; set; }
public TranscodingJobType TranscodingType { get; set; }
@ -188,7 +243,7 @@ namespace MediaBrowser.Controller.MediaEncoding
_logger = logger;
TranscodingType = jobType;
RemoteHttpHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
PlayableStreamFileNames = new string[]{};
PlayableStreamFileNames = new string[] { };
SupportedAudioCodecs = new List<string>();
SupportedVideoCodecs = new List<string>();
SupportedSubtitleCodecs = new List<string>();
@ -338,12 +393,19 @@ namespace MediaBrowser.Controller.MediaEncoding
{
get
{
var stream = VideoStream;
var request = BaseRequest;
if (BaseRequest.Static)
{
return VideoStream == null ? null : VideoStream.Level;
}
var level = GetRequestedLevel(ActualOutputVideoCodec);
double result;
if (!string.IsNullOrWhiteSpace(level) && double.TryParse(level, NumberStyles.Any, CultureInfo.InvariantCulture, out result))
{
return result;
}
return !string.IsNullOrEmpty(request.Level) && !request.Static
? double.Parse(request.Level, CultureInfo.InvariantCulture)
: stream == null ? null : stream.Level;
return null;
}
}
@ -367,8 +429,12 @@ namespace MediaBrowser.Controller.MediaEncoding
{
get
{
var stream = VideoStream;
return stream == null || !BaseRequest.Static ? null : stream.RefFrames;
if (BaseRequest.Static)
{
return VideoStream == null ? null : VideoStream.RefFrames;
}
return null;
}
}
@ -423,10 +489,18 @@ namespace MediaBrowser.Controller.MediaEncoding
{
get
{
var stream = VideoStream;
return !string.IsNullOrEmpty(BaseRequest.Profile) && !BaseRequest.Static
? BaseRequest.Profile
: stream == null ? null : stream.Profile;
if (BaseRequest.Static)
{
return VideoStream == null ? null : VideoStream.Profile;
}
var requestedProfile = GetRequestedProfiles(ActualOutputVideoCodec).FirstOrDefault();
if (!string.IsNullOrWhiteSpace(requestedProfile))
{
return requestedProfile;
}
return null;
}
}

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Services;
@ -39,18 +40,16 @@ namespace MediaBrowser.Controller.MediaEncoding
MaxWidth = info.MaxWidth;
MaxHeight = info.MaxHeight;
MaxFramerate = info.MaxFramerate;
Profile = info.VideoProfile;
ItemId = info.ItemId;
MediaSourceId = info.MediaSourceId;
AudioCodec = info.TargetAudioCodec;
AudioCodec = info.TargetAudioCodec.FirstOrDefault();
MaxAudioChannels = info.MaxAudioChannels;
AudioBitRate = info.AudioBitrate;
AudioSampleRate = info.TargetAudioSampleRate;
DeviceProfile = deviceProfile;
VideoCodec = info.TargetVideoCodec;
VideoCodec = info.TargetVideoCodec.FirstOrDefault();
VideoBitRate = info.VideoBitrate;
AudioStreamIndex = info.AudioStreamIndex;
MaxRefFrames = info.MaxRefFrames;
MaxVideoBitDepth = info.MaxVideoBitDepth;
SubtitleMethod = info.SubtitleDeliveryMethod;
Context = info.Context;
@ -60,11 +59,7 @@ namespace MediaBrowser.Controller.MediaEncoding
{
SubtitleStreamIndex = info.SubtitleStreamIndex;
}
if (info.VideoLevel.HasValue)
{
Level = info.VideoLevel.Value.ToString(_usCulture);
}
StreamOptions = info.StreamOptions;
}
}
@ -231,7 +226,7 @@ namespace MediaBrowser.Controller.MediaEncoding
SetOption(qualifier + "-" + name, value);
}
public Dictionary<string, string> StreamOptions { get; private set; }
public Dictionary<string, string> StreamOptions { get; set; }
public void SetOption(string name, string value)
{

@ -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;
}
foreach (var val in codec)
{
if (ListHelper.ContainsIgnoreCase(codecs, val))
{
return true;
}
}
return codecs.Length == 0 || ListHelper.ContainsIgnoreCase(codecs, ContainerProfile.SplitValue(codec)[0]);
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,11 +614,54 @@ 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>
@ -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>

@ -55,9 +55,8 @@
<HintPath>..\packages\ServiceStack.Text.4.5.8\lib\net45\ServiceStack.Text.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="SharpCompress, Version=0.14.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\SharpCompress.0.14.0\lib\net45\SharpCompress.dll</HintPath>
<Private>True</Private>
<Reference Include="SharpCompress, Version=0.18.2.0, Culture=neutral, PublicKeyToken=afb0a02973931d96, processorArchitecture=MSIL">
<HintPath>..\packages\SharpCompress.0.18.2\lib\net45\SharpCompress.dll</HintPath>
</Reference>
<Reference Include="SimpleInjector, Version=4.0.8.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
<HintPath>..\packages\SimpleInjector.4.0.8\lib\net45\SimpleInjector.dll</HintPath>

@ -2,7 +2,7 @@
<packages>
<package id="Mono.Posix" version="4.0.0.0" targetFramework="net45" />
<package id="ServiceStack.Text" version="4.5.8" targetFramework="net46" />
<package id="SharpCompress" version="0.14.0" targetFramework="net46" />
<package id="SharpCompress" version="0.18.2" targetFramework="net46" />
<package id="SimpleInjector" version="4.0.8" targetFramework="net46" />
<package id="SkiaSharp" version="1.58.1" targetFramework="net46" />
<package id="SQLitePCLRaw.core" version="1.1.8" targetFramework="net46" />

@ -77,9 +77,8 @@
<HintPath>..\packages\ServiceStack.Text.4.5.8\lib\net45\ServiceStack.Text.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="SharpCompress, Version=0.14.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\SharpCompress.0.14.0\lib\net45\SharpCompress.dll</HintPath>
<Private>True</Private>
<Reference Include="SharpCompress, Version=0.18.2.0, Culture=neutral, PublicKeyToken=afb0a02973931d96, processorArchitecture=MSIL">
<HintPath>..\packages\SharpCompress.0.18.2\lib\net45\SharpCompress.dll</HintPath>
</Reference>
<Reference Include="SimpleInjector, Version=4.0.8.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
<HintPath>..\packages\SimpleInjector.4.0.8\lib\net45\SimpleInjector.dll</HintPath>

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="ServiceStack.Text" version="4.5.8" targetFramework="net462" />
<package id="SharpCompress" version="0.14.0" targetFramework="net462" />
<package id="SharpCompress" version="0.18.2" targetFramework="net462" />
<package id="SimpleInjector" version="4.0.8" targetFramework="net462" />
<package id="SkiaSharp" version="1.58.1" targetFramework="net462" />
<package id="SQLitePCLRaw.core" version="1.1.8" targetFramework="net462" />

Loading…
Cancel
Save