diff --git a/Emby.Dlna/Didl/DidlBuilder.cs b/Emby.Dlna/Didl/DidlBuilder.cs
index 1cb9a24fb..5e200428a 100644
--- a/Emby.Dlna/Didl/DidlBuilder.cs
+++ b/Emby.Dlna/Didl/DidlBuilder.cs
@@ -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,
diff --git a/Emby.Dlna/PlayTo/PlayToController.cs b/Emby.Dlna/PlayTo/PlayToController.cs
index 95b164212..ba1d3a6de 100644
--- a/Emby.Dlna/PlayTo/PlayToController.cs
+++ b/Emby.Dlna/PlayTo/PlayToController.cs
@@ -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,
diff --git a/Emby.Server.Implementations/Archiving/ZipClient.cs b/Emby.Server.Implementations/Archiving/ZipClient.cs
index 3218d56c6..d7d37bb61 100644
--- a/Emby.Server.Implementations/Archiving/ZipClient.cs
+++ b/Emby.Server.Implementations/Archiving/ZipClient.cs
@@ -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);
+ }
+ }
+
///
/// Extracts all from7z.
///
diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj
index ccff29eef..41a62a417 100644
--- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj
+++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj
@@ -667,8 +667,8 @@
..\packages\ServiceStack.Text.4.5.8\lib\net45\ServiceStack.Text.dll
True
-
- ..\packages\SharpCompress.0.14.0\lib\net45\SharpCompress.dll
+
+ ..\packages\SharpCompress.0.18.2\lib\net45\SharpCompress.dll
..\packages\SimpleInjector.4.0.8\lib\net45\SimpleInjector.dll
diff --git a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs
index fb8308cda..55500df6e 100644
--- a/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs
+++ b/Emby.Server.Implementations/LiveTv/Listings/XmlTvListingsProvider.cs
@@ -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);
+ 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);
+ 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);
+ _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 _fileSystem.GetFiles(tempFolder, true)
+ .Where(i => string.Equals(i.Extension, ".xml", StringComparison.OrdinalIgnoreCase))
+ .Select(i => i.FullName)
+ .FirstOrDefault();
+ }
+ }
return file;
}
diff --git a/Emby.Server.Implementations/packages.config b/Emby.Server.Implementations/packages.config
index c27b8ac26..d27722fef 100644
--- a/Emby.Server.Implementations/packages.config
+++ b/Emby.Server.Implementations/packages.config
@@ -2,7 +2,7 @@
-
+
diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
index 642a42c8e..7be3c3754 100644
--- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
+++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
@@ -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)
{
diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs
index fb8aa9767..450bbf7c1 100644
--- a/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs
+++ b/MediaBrowser.Controller/MediaEncoding/EncodingJobInfo.cs
@@ -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(StringComparer.OrdinalIgnoreCase);
- PlayableStreamFileNames = new string[]{};
+ PlayableStreamFileNames = new string[] { };
SupportedAudioCodecs = new List();
SupportedVideoCodecs = new List();
SupportedSubtitleCodecs = new List();
@@ -338,12 +393,19 @@ namespace MediaBrowser.Controller.MediaEncoding
{
get
{
- var stream = VideoStream;
- var request = BaseRequest;
+ if (BaseRequest.Static)
+ {
+ return VideoStream == null ? null : VideoStream.Level;
+ }
- return !string.IsNullOrEmpty(request.Level) && !request.Static
- ? double.Parse(request.Level, CultureInfo.InvariantCulture)
- : stream == null ? null : stream.Level;
+ var level = GetRequestedLevel(ActualOutputVideoCodec);
+ double result;
+ if (!string.IsNullOrWhiteSpace(level) && double.TryParse(level, NumberStyles.Any, CultureInfo.InvariantCulture, out result))
+ {
+ return result;
+ }
+
+ 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;
}
}
diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs b/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs
index cb675ba68..bac2a6e65 100644
--- a/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs
+++ b/MediaBrowser.Controller/MediaEncoding/EncodingJobOptions.cs
@@ -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 StreamOptions { get; private set; }
+ public Dictionary StreamOptions { get; set; }
public void SetOption(string name, string value)
{
diff --git a/MediaBrowser.Model/Dlna/CodecProfile.cs b/MediaBrowser.Model/Dlna/CodecProfile.cs
index d75547adb..6d143962d 100644
--- a/MediaBrowser.Model/Dlna/CodecProfile.cs
+++ b/MediaBrowser.Model/Dlna/CodecProfile.cs
@@ -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;
}
}
}
diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs
index 3b68db802..dfc9317fd 100644
--- a/MediaBrowser.Model/Dlna/StreamBuilder.cs
+++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs
@@ -283,7 +283,7 @@ namespace MediaBrowser.Model.Dlna
var conditions = new List();
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();
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();
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();
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;
diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs
index 3e7ff9c3d..fe5aaa739 100644
--- a/MediaBrowser.Model/Dlna/StreamInfo.cs
+++ b/MediaBrowser.Model/Dlna/StreamInfo.cs
@@ -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;
+ }
+
///
/// Predicts the audio sample rate that will be in the output stream
///
@@ -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
///
/// Predicts the audio codec that will be in the output stream
///
- 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))
diff --git a/MediaBrowser.Model/IO/IZipClient.cs b/MediaBrowser.Model/IO/IZipClient.cs
index ac57d58a6..2dc4880c2 100644
--- a/MediaBrowser.Model/IO/IZipClient.cs
+++ b/MediaBrowser.Model/IO/IZipClient.cs
@@ -23,6 +23,8 @@ namespace MediaBrowser.Model.IO
/// if set to true [overwrite existing files].
void ExtractAll(Stream source, string targetPath, bool overwriteExistingFiles);
+ void ExtractAllFromGz(Stream source, string targetPath, bool overwriteExistingFiles);
+
///
/// Extracts all from zip.
///
diff --git a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj
index d2ce0b40d..365977530 100644
--- a/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj
+++ b/MediaBrowser.Server.Mono/MediaBrowser.Server.Mono.csproj
@@ -55,9 +55,8 @@
..\packages\ServiceStack.Text.4.5.8\lib\net45\ServiceStack.Text.dll
True
-
- ..\packages\SharpCompress.0.14.0\lib\net45\SharpCompress.dll
- True
+
+ ..\packages\SharpCompress.0.18.2\lib\net45\SharpCompress.dll
..\packages\SimpleInjector.4.0.8\lib\net45\SimpleInjector.dll
diff --git a/MediaBrowser.Server.Mono/packages.config b/MediaBrowser.Server.Mono/packages.config
index cff873f1f..dfa3dc75d 100644
--- a/MediaBrowser.Server.Mono/packages.config
+++ b/MediaBrowser.Server.Mono/packages.config
@@ -2,7 +2,7 @@
-
+
diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj
index 23db82cf1..9e4f52489 100644
--- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj
+++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj
@@ -77,9 +77,8 @@
..\packages\ServiceStack.Text.4.5.8\lib\net45\ServiceStack.Text.dll
True
-
- ..\packages\SharpCompress.0.14.0\lib\net45\SharpCompress.dll
- True
+
+ ..\packages\SharpCompress.0.18.2\lib\net45\SharpCompress.dll
..\packages\SimpleInjector.4.0.8\lib\net45\SimpleInjector.dll
diff --git a/MediaBrowser.ServerApplication/packages.config b/MediaBrowser.ServerApplication/packages.config
index 85d2613bb..c7b98700e 100644
--- a/MediaBrowser.ServerApplication/packages.config
+++ b/MediaBrowser.ServerApplication/packages.config
@@ -1,7 +1,7 @@
-
+
diff --git a/SharedVersion.cs b/SharedVersion.cs
index 1093bcd4c..180c32184 100644
--- a/SharedVersion.cs
+++ b/SharedVersion.cs
@@ -1,3 +1,3 @@
using System.Reflection;
-[assembly: AssemblyVersion("3.2.32.5")]
+[assembly: AssemblyVersion("3.2.32.6")]