commit
88d62050a6
|
@ -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);
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
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>
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
using System.Reflection;
|
||||
|
||||
[assembly: AssemblyVersion("3.2.32.5")]
|
||||
[assembly: AssemblyVersion("3.2.32.6")]
|
||||
|
|
Loading…
Reference in New Issue
Block a user