From d270b10db67eeaa16a35920d5d86b1975dfffd16 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 27 Jul 2017 01:18:39 -0400 Subject: move auto-organize to plugin --- MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 33 +--------------------- 1 file changed, 1 insertion(+), 32 deletions(-) (limited to 'MediaBrowser.MediaEncoding') diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index f1bf29d92..f416ea417 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -597,21 +597,7 @@ namespace MediaBrowser.MediaEncoding.Encoder } } - var mediaInfo = new ProbeResultNormalizer(_logger, FileSystem, _memoryStreamProvider).GetMediaInfo(result, videoType, isAudio, primaryPath, protocol); - - var videoStream = mediaInfo.MediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Video); - - if (videoStream != null && !videoStream.IsInterlaced) - { - var isInterlaced = DetectInterlaced(mediaInfo, videoStream); - - if (isInterlaced) - { - videoStream.IsInterlaced = true; - } - } - - return mediaInfo; + return new ProbeResultNormalizer(_logger, FileSystem, _memoryStreamProvider).GetMediaInfo(result, videoType, isAudio, primaryPath, protocol); } catch { @@ -622,23 +608,6 @@ namespace MediaBrowser.MediaEncoding.Encoder } } - private bool DetectInterlaced(MediaSourceInfo video, MediaStream videoStream) - { - // If it's mpeg based, assume true - if ((videoStream.Codec ?? string.Empty).IndexOf("mpeg", StringComparison.OrdinalIgnoreCase) != -1) - { - var formats = (video.Container ?? string.Empty).Split(',').ToList(); - return formats.Contains("vob", StringComparer.OrdinalIgnoreCase) || - formats.Contains("m2ts", StringComparer.OrdinalIgnoreCase) || - formats.Contains("ts", StringComparer.OrdinalIgnoreCase) || - formats.Contains("mpegts", StringComparer.OrdinalIgnoreCase) || - formats.Contains("wtv", StringComparer.OrdinalIgnoreCase); - - } - - return false; - } - /// /// The us culture /// -- cgit v1.2.3 From b89af7af43379e4213a70200410c7b5151e2ebd7 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 1 Aug 2017 15:43:39 -0400 Subject: fixes #2121 - background roku thumbnail generation (or maybe... any scheduled task?) should be "niced" --- .../MediaEncoder/EncodingManager.cs | 2 +- MediaBrowser.Api/Playback/BaseStreamingService.cs | 2 +- .../MediaEncoding/EncodingHelper.cs | 22 ++++---- .../MediaEncoding/IMediaEncoder.cs | 21 ++------ MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs | 2 +- MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 60 ++++++++++++++++++---- .../MediaInfo/VideoImageProvider.cs | 6 ++- 7 files changed, 73 insertions(+), 42 deletions(-) (limited to 'MediaBrowser.MediaEncoding') diff --git a/Emby.Server.Implementations/MediaEncoder/EncodingManager.cs b/Emby.Server.Implementations/MediaEncoder/EncodingManager.cs index 1d74e8788..e4eb41e3a 100644 --- a/Emby.Server.Implementations/MediaEncoder/EncodingManager.cs +++ b/Emby.Server.Implementations/MediaEncoder/EncodingManager.cs @@ -142,7 +142,7 @@ namespace Emby.Server.Implementations.MediaEncoder var container = video.Container; - var tempFile = await _encoder.ExtractVideoImage(inputPath, container, protocol, video.Video3DFormat, time, cancellationToken).ConfigureAwait(false); + var tempFile = await _encoder.ExtractVideoImage(inputPath, container, protocol, video.GetDefaultVideoStream(), video.Video3DFormat, time, cancellationToken).ConfigureAwait(false); _fileSystem.CopyFile(tempFile, path, true); try diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index c300fcce3..4fde66d1a 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -95,7 +95,7 @@ namespace MediaBrowser.Api.Playback LibraryManager = libraryManager; IsoManager = isoManager; MediaEncoder = mediaEncoder; - EncodingHelper = new EncodingHelper(MediaEncoder, serverConfig, FileSystem, SubtitleEncoder); + EncodingHelper = new EncodingHelper(MediaEncoder, FileSystem, SubtitleEncoder); } /// diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 6d2ec2eab..4b3e340c9 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -4,7 +4,6 @@ using System.Globalization; using System.IO; using System.Linq; using System.Threading; -using MediaBrowser.Controller.Configuration; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Dto; @@ -19,14 +18,12 @@ namespace MediaBrowser.Controller.MediaEncoding private readonly CultureInfo _usCulture = new CultureInfo("en-US"); private readonly IMediaEncoder _mediaEncoder; - private readonly IServerConfigurationManager _config; private readonly IFileSystem _fileSystem; private readonly ISubtitleEncoder _subtitleEncoder; - public EncodingHelper(IMediaEncoder mediaEncoder, IServerConfigurationManager config, IFileSystem fileSystem, ISubtitleEncoder subtitleEncoder) + public EncodingHelper(IMediaEncoder mediaEncoder, IFileSystem fileSystem, ISubtitleEncoder subtitleEncoder) { _mediaEncoder = mediaEncoder; - _config = config; _fileSystem = fileSystem; _subtitleEncoder = subtitleEncoder; } @@ -1771,29 +1768,34 @@ namespace MediaBrowser.Controller.MediaEncoding return null; } + return GetVideoDecoder(state.MediaSource.VideoType ?? VideoType.VideoFile, state.VideoStream, encodingOptions); + } + + public string GetVideoDecoder(VideoType videoType, MediaStream videoStream, EncodingOptions encodingOptions) + { // Only use alternative encoders for video files. // When using concat with folder rips, if the mfx session fails to initialize, ffmpeg will be stuck retrying and will not exit gracefully // Since transcoding of folder rips is expiremental anyway, it's not worth adding additional variables such as this. - if (state.VideoType != VideoType.VideoFile) + if (videoType != VideoType.VideoFile) { return null; } - if (state.VideoStream != null && - !string.IsNullOrWhiteSpace(state.VideoStream.Codec) && + if (videoStream != null && + !string.IsNullOrWhiteSpace(videoStream.Codec) && !string.IsNullOrWhiteSpace(encodingOptions.HardwareAccelerationType) && encodingOptions.EnableHardwareDecoding) { if (string.Equals(encodingOptions.HardwareAccelerationType, "qsv", StringComparison.OrdinalIgnoreCase)) { - switch (state.MediaSource.VideoStream.Codec.ToLower()) + switch (videoStream.Codec.ToLower()) { case "avc": case "h264": if (_mediaEncoder.SupportsDecoder("h264_qsv")) { // qsv decoder does not support 10-bit input - if ((state.VideoStream.BitDepth ?? 8) > 8) + if ((videoStream.BitDepth ?? 8) > 8) { return null; } @@ -1824,7 +1826,7 @@ namespace MediaBrowser.Controller.MediaEncoding else if (string.Equals(encodingOptions.HardwareAccelerationType, "nvenc", StringComparison.OrdinalIgnoreCase)) { - switch (state.MediaSource.VideoStream.Codec.ToLower()) + switch (videoStream.Codec.ToLower()) { case "avc": case "h264": diff --git a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs index 10d7b9a7e..05bb35771 100644 --- a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs +++ b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs @@ -39,29 +39,16 @@ namespace MediaBrowser.Controller.MediaEncoding /// /// Extracts the video image. /// - /// The input files. - /// The protocol. - /// The threed format. - /// The offset. - /// The cancellation token. - /// Task{Stream}. - Task ExtractVideoImage(string[] inputFiles, string container, MediaProtocol protocol, Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken); + Task ExtractVideoImage(string[] inputFiles, string container, MediaProtocol protocol, MediaStream videoStream, Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken); - Task ExtractVideoImage(string[] inputFiles, string container, MediaProtocol protocol, int? imageStreamIndex, CancellationToken cancellationToken); + Task ExtractVideoImage(string[] inputFiles, string container, MediaProtocol protocol, MediaStream imageStream, int? imageStreamIndex, CancellationToken cancellationToken); /// /// Extracts the video images on interval. /// - /// The input files. - /// The protocol. - /// The threed format. - /// The interval. - /// The target directory. - /// The filename prefix. - /// The maximum width. - /// The cancellation token. - /// Task. Task ExtractVideoImagesOnInterval(string[] inputFiles, + string container, + MediaStream videoStream, MediaProtocol protocol, Video3DFormat? threedFormat, TimeSpan interval, diff --git a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs index 3672e4e84..a291a9852 100644 --- a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs @@ -59,7 +59,7 @@ namespace MediaBrowser.MediaEncoding.Encoder MediaSourceManager = mediaSourceManager; ProcessFactory = processFactory; - EncodingHelper = new EncodingHelper(MediaEncoder, ConfigurationManager, FileSystem, SubtitleEncoder); + EncodingHelper = new EncodingHelper(MediaEncoder, FileSystem, SubtitleEncoder); } public async Task Start(EncodingJobOptions options, diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index f416ea417..a2ebe0832 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -615,20 +615,20 @@ namespace MediaBrowser.MediaEncoding.Encoder public Task ExtractAudioImage(string path, int? imageStreamIndex, CancellationToken cancellationToken) { - return ExtractImage(new[] { path }, null, imageStreamIndex, MediaProtocol.File, true, null, null, cancellationToken); + return ExtractImage(new[] { path }, null, null, imageStreamIndex, MediaProtocol.File, true, null, null, cancellationToken); } - public Task ExtractVideoImage(string[] inputFiles, string container, MediaProtocol protocol, Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken) + public Task ExtractVideoImage(string[] inputFiles, string container, MediaProtocol protocol, MediaStream videoStream, Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken) { - return ExtractImage(inputFiles, container, null, protocol, false, threedFormat, offset, cancellationToken); + return ExtractImage(inputFiles, container, videoStream, null, protocol, false, threedFormat, offset, cancellationToken); } - public Task ExtractVideoImage(string[] inputFiles, string container, MediaProtocol protocol, int? imageStreamIndex, CancellationToken cancellationToken) + public Task ExtractVideoImage(string[] inputFiles, string container, MediaProtocol protocol, MediaStream imageStream, int? imageStreamIndex, CancellationToken cancellationToken) { - return ExtractImage(inputFiles, container, imageStreamIndex, protocol, false, null, null, cancellationToken); + return ExtractImage(inputFiles, container, imageStream, imageStreamIndex, protocol, false, null, null, cancellationToken); } - private async Task ExtractImage(string[] inputFiles, string container, int? imageStreamIndex, MediaProtocol protocol, bool isAudio, + private async Task ExtractImage(string[] inputFiles, string container, MediaStream videoStream, int? imageStreamIndex, MediaProtocol protocol, bool isAudio, Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken) { var inputArgument = GetInputArgument(inputFiles, protocol); @@ -645,7 +645,7 @@ namespace MediaBrowser.MediaEncoding.Encoder { try { - return await ExtractImageInternal(inputArgument, container, imageStreamIndex, protocol, threedFormat, offset, true, cancellationToken).ConfigureAwait(false); + return await ExtractImageInternal(inputArgument, container, videoStream, imageStreamIndex, threedFormat, offset, true, cancellationToken).ConfigureAwait(false); } catch (ArgumentException) { @@ -657,10 +657,10 @@ namespace MediaBrowser.MediaEncoding.Encoder } } - return await ExtractImageInternal(inputArgument, container, imageStreamIndex, protocol, threedFormat, offset, false, cancellationToken).ConfigureAwait(false); + return await ExtractImageInternal(inputArgument, container, videoStream, imageStreamIndex, threedFormat, offset, false, cancellationToken).ConfigureAwait(false); } - private async Task ExtractImageInternal(string inputPath, string container, int? imageStreamIndex, MediaProtocol protocol, Video3DFormat? threedFormat, TimeSpan? offset, bool useIFrame, CancellationToken cancellationToken) + private async Task ExtractImageInternal(string inputPath, string container, MediaStream videoStream, int? imageStreamIndex, Video3DFormat? threedFormat, TimeSpan? offset, bool useIFrame, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(inputPath)) { @@ -698,7 +698,7 @@ namespace MediaBrowser.MediaEncoding.Encoder break; } } - + var mapArg = imageStreamIndex.HasValue ? (" -map 0:v:" + imageStreamIndex.Value.ToString(CultureInfo.InvariantCulture)) : string.Empty; var enableThumbnail = !new List { "wtv" }.Contains(container ?? string.Empty, StringComparer.OrdinalIgnoreCase); @@ -726,6 +726,25 @@ namespace MediaBrowser.MediaEncoding.Encoder args = string.Format("-ss {0} ", GetTimeParameter(offset.Value)) + args; } + var encodinghelper = new EncodingHelper(this, FileSystem, SubtitleEncoder()); + if (videoStream != null) + { + var decoder = encodinghelper.GetVideoDecoder(VideoType.VideoFile, videoStream, GetEncodingOptions()); + if (!string.IsNullOrWhiteSpace(decoder)) + { + args = decoder + " " + args; + } + } + + if (!string.IsNullOrWhiteSpace(container)) + { + var inputFormat = encodinghelper.GetInputFormat(container); + if (!string.IsNullOrWhiteSpace(inputFormat)) + { + args = "-f " + inputFormat + " " + args; + } + } + var process = _processFactory.Create(new ProcessOptions { CreateNoWindow = true, @@ -786,6 +805,8 @@ namespace MediaBrowser.MediaEncoding.Encoder } public async Task ExtractVideoImagesOnInterval(string[] inputFiles, + string container, + MediaStream videoStream, MediaProtocol protocol, Video3DFormat? threedFormat, TimeSpan interval, @@ -825,6 +846,25 @@ namespace MediaBrowser.MediaEncoding.Encoder args = analyzeDurationArgument + " " + args; } + var encodinghelper = new EncodingHelper(this, FileSystem, SubtitleEncoder()); + if (videoStream != null) + { + var decoder = encodinghelper.GetVideoDecoder(VideoType.VideoFile, videoStream, GetEncodingOptions()); + if (!string.IsNullOrWhiteSpace(decoder)) + { + args = decoder + " " + args; + } + } + + if (!string.IsNullOrWhiteSpace(container)) + { + var inputFormat = encodinghelper.GetInputFormat(container); + if (!string.IsNullOrWhiteSpace(inputFormat)) + { + args = "-f " + inputFormat + " " + args; + } + } + var process = _processFactory.Create(new ProcessOptions { CreateNoWindow = true, diff --git a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs index ca701b70f..bb1c4e647 100644 --- a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs @@ -133,7 +133,7 @@ namespace MediaBrowser.Providers.MediaInfo } } - extractedImagePath = await _mediaEncoder.ExtractVideoImage(inputPath, item.Container, protocol, videoIndex, cancellationToken).ConfigureAwait(false); + extractedImagePath = await _mediaEncoder.ExtractVideoImage(inputPath, item.Container, protocol, imageStream, videoIndex, cancellationToken).ConfigureAwait(false); } else { @@ -144,7 +144,9 @@ namespace MediaBrowser.Providers.MediaInfo ? TimeSpan.FromTicks(Convert.ToInt64(item.RunTimeTicks.Value * .1)) : TimeSpan.FromSeconds(10); - extractedImagePath = await _mediaEncoder.ExtractVideoImage(inputPath, item.Container, protocol, item.Video3DFormat, imageOffset, cancellationToken).ConfigureAwait(false); + var videoStream = mediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Video); + + extractedImagePath = await _mediaEncoder.ExtractVideoImage(inputPath, item.Container, protocol, videoStream, item.Video3DFormat, imageOffset, cancellationToken).ConfigureAwait(false); } return new DynamicImageResponse -- cgit v1.2.3 From d8e2887071125eb109e3a9210f0df94506dcf7c7 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 4 Aug 2017 16:29:34 -0400 Subject: update container value --- MediaBrowser.Api/Playback/BaseStreamingService.cs | 2 +- MediaBrowser.Api/Playback/MediaInfoService.cs | 20 ++++++++++- .../Progressive/BaseProgressiveStreamingService.cs | 2 +- MediaBrowser.Api/Playback/StreamState.cs | 4 +-- .../MediaEncoding/EncodingHelper.cs | 11 ++++-- .../Probing/ProbeResultNormalizer.cs | 19 +++++++++- MediaBrowser.Model/Dlna/ContainerProfile.cs | 3 +- MediaBrowser.Model/Dlna/DeviceProfile.cs | 31 ++++++---------- MediaBrowser.Model/Dlna/ResponseProfile.cs | 7 +--- MediaBrowser.Model/Dlna/StreamBuilder.cs | 42 +++++++++++++++++++--- MediaBrowser.Model/Net/MimeTypes.cs | 18 ++++++---- .../MediaInfo/FFProbeAudioInfo.cs | 4 +-- .../MediaInfo/FFProbeVideoInfo.cs | 1 + 13 files changed, 116 insertions(+), 48 deletions(-) (limited to 'MediaBrowser.MediaEncoding') diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 4fde66d1a..d157f1b65 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -779,7 +779,7 @@ namespace MediaBrowser.Api.Playback if (string.IsNullOrEmpty(container)) { container = request.Static ? - state.InputContainer : + StreamBuilder.NormalizeMediaSourceFormatIntoSingleContainer(state.InputContainer, null, DlnaProfileType.Audio) : GetOutputFileExtension(state); } diff --git a/MediaBrowser.Api/Playback/MediaInfoService.cs b/MediaBrowser.Api/Playback/MediaInfoService.cs index 536236f5f..9d2359102 100644 --- a/MediaBrowser.Api/Playback/MediaInfoService.cs +++ b/MediaBrowser.Api/Playback/MediaInfoService.cs @@ -117,7 +117,7 @@ namespace MediaBrowser.Api.Playback var authInfo = _authContext.GetAuthorizationInfo(Request); var result = await _mediaSourceManager.OpenLiveStream(request, CancellationToken.None).ConfigureAwait(false); - + var profile = request.DeviceProfile; if (profile == null) { @@ -144,6 +144,11 @@ namespace MediaBrowser.Api.Playback } } + if (result.MediaSource != null) + { + NormalizeMediaSourceContainer(result.MediaSource, profile, DlnaProfileType.Video); + } + return result; } @@ -207,9 +212,22 @@ namespace MediaBrowser.Api.Playback } } + if (info.MediaSources != null) + { + foreach (var mediaSource in info.MediaSources) + { + NormalizeMediaSourceContainer(mediaSource, profile, DlnaProfileType.Video); + } + } + return info; } + private void NormalizeMediaSourceContainer(MediaSourceInfo mediaSource, DeviceProfile profile, DlnaProfileType type) + { + mediaSource.Container = StreamBuilder.NormalizeMediaSourceFormatIntoSingleContainer(mediaSource.Container, profile, type); + } + public async Task Post(GetPostedPlaybackInfo request) { var result = await GetPlaybackInfo(request).ConfigureAwait(false); diff --git a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs index db5c78a2f..95b8c3329 100644 --- a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs +++ b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs @@ -167,7 +167,7 @@ namespace MediaBrowser.Api.Playback.Progressive // Static stream if (request.Static) { - var contentType = state.GetMimeType(state.MediaPath); + var contentType = state.GetMimeType("." + state.OutputContainer, false) ?? state.GetMimeType(state.MediaPath); using (state) { diff --git a/MediaBrowser.Api/Playback/StreamState.cs b/MediaBrowser.Api/Playback/StreamState.cs index eecc12432..6c098deea 100644 --- a/MediaBrowser.Api/Playback/StreamState.cs +++ b/MediaBrowser.Api/Playback/StreamState.cs @@ -131,14 +131,14 @@ namespace MediaBrowser.Api.Playback public long? EncodingDurationTicks { get; set; } - public string GetMimeType(string outputPath) + public string GetMimeType(string outputPath, bool enableStreamDefault = true) { if (!string.IsNullOrEmpty(MimeType)) { return MimeType; } - return MimeTypes.GetMimeType(outputPath); + return MimeTypes.GetMimeType(outputPath, enableStreamDefault); } public bool EnableDlnaHeaders { get; set; } diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 4b3e340c9..afbb99d39 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -10,6 +10,7 @@ using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.IO; using MediaBrowser.Model.MediaInfo; +using MediaBrowser.Model.Extensions; namespace MediaBrowser.Controller.MediaEncoding { @@ -148,10 +149,13 @@ namespace MediaBrowser.Controller.MediaEncoding public string GetInputFormat(string container) { - if (string.Equals(container, "mkv", StringComparison.OrdinalIgnoreCase)) + if (string.IsNullOrWhiteSpace(container)) { - return "matroska"; + return null; } + + container = container.Replace("mkv", "matroska", StringComparison.OrdinalIgnoreCase); + if (string.Equals(container, "ts", StringComparison.OrdinalIgnoreCase)) { return "mpegts"; @@ -1694,7 +1698,8 @@ namespace MediaBrowser.Controller.MediaEncoding state.InputAudioSync = "1"; } - if (string.Equals(mediaSource.Container, "wma", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(mediaSource.Container, "wma", StringComparison.OrdinalIgnoreCase) || + string.Equals(mediaSource.Container, "asf", StringComparison.OrdinalIgnoreCase)) { // Seeing some stuttering when transcoding wma to audio-only HLS state.InputAudioSync = "1"; diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index 1e91a8198..023100f44 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -53,7 +53,7 @@ namespace MediaBrowser.MediaEncoding.Probing if (data.format != null) { - info.Container = data.format.format_name; + info.Container = NormalizeFormat(data.format.format_name); if (!string.IsNullOrEmpty(data.format.bit_rate)) { @@ -195,6 +195,23 @@ namespace MediaBrowser.MediaEncoding.Probing return info; } + private string NormalizeFormat(string format) + { + if (string.IsNullOrWhiteSpace(format)) + { + return null; + } + + if (string.Equals(format, "mpegvideo", StringComparison.OrdinalIgnoreCase)) + { + return "mpeg"; + } + + format = format.Replace("matroska", "mkv", StringComparison.OrdinalIgnoreCase); + + return format; + } + private int? GetEstimatedAudioBitrate(string codec, int? channels) { if (!channels.HasValue) diff --git a/MediaBrowser.Model/Dlna/ContainerProfile.cs b/MediaBrowser.Model/Dlna/ContainerProfile.cs index c05c19412..2004cfc1f 100644 --- a/MediaBrowser.Model/Dlna/ContainerProfile.cs +++ b/MediaBrowser.Model/Dlna/ContainerProfile.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Xml.Serialization; using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Extensions; diff --git a/MediaBrowser.Model/Dlna/DeviceProfile.cs b/MediaBrowser.Model/Dlna/DeviceProfile.cs index cd7ff08d6..5f9bd772c 100644 --- a/MediaBrowser.Model/Dlna/DeviceProfile.cs +++ b/MediaBrowser.Model/Dlna/DeviceProfile.cs @@ -187,17 +187,14 @@ namespace MediaBrowser.Model.Dlna public ResponseProfile GetAudioMediaProfile(string container, string audioCodec, int? audioChannels, int? audioBitrate, int? audioSampleRate, int? audioBitDepth) { - container = StringHelper.TrimStart(container ?? string.Empty, '.'); - foreach (var i in ResponseProfiles) { - if (i.Type != MediaBrowser.Model.Dlna.DlnaProfileType.Audio) + if (i.Type != DlnaProfileType.Audio) { continue; } - List containers = i.GetContainers(); - if (containers.Count > 0 && !ListHelper.ContainsIgnoreCase(containers, container)) + if (!ContainerProfile.ContainsContainer(i.GetContainers(), container)) { continue; } @@ -208,7 +205,7 @@ namespace MediaBrowser.Model.Dlna continue; } - var conditionProcessor = new MediaBrowser.Model.Dlna.ConditionProcessor(); + var conditionProcessor = new ConditionProcessor(); var anyOff = false; foreach (ProfileCondition c in i.Conditions) @@ -230,9 +227,9 @@ namespace MediaBrowser.Model.Dlna return null; } - private MediaBrowser.Model.Dlna.ProfileCondition GetModelProfileCondition(ProfileCondition c) + private ProfileCondition GetModelProfileCondition(ProfileCondition c) { - return new MediaBrowser.Model.Dlna.ProfileCondition + return new ProfileCondition { Condition = c.Condition, IsRequired = c.IsRequired, @@ -243,22 +240,19 @@ namespace MediaBrowser.Model.Dlna public ResponseProfile GetImageMediaProfile(string container, int? width, int? height) { - container = StringHelper.TrimStart(container ?? string.Empty, '.'); - foreach (var i in ResponseProfiles) { - if (i.Type != MediaBrowser.Model.Dlna.DlnaProfileType.Photo) + if (i.Type != DlnaProfileType.Photo) { continue; } - List containers = i.GetContainers(); - if (containers.Count > 0 && !ListHelper.ContainsIgnoreCase(containers, container)) + if (!ContainerProfile.ContainsContainer(i.GetContainers(), container)) { continue; } - var conditionProcessor = new MediaBrowser.Model.Dlna.ConditionProcessor(); + var conditionProcessor = new ConditionProcessor(); var anyOff = false; foreach (ProfileCondition c in i.Conditions) @@ -300,17 +294,14 @@ namespace MediaBrowser.Model.Dlna string videoCodecTag, bool? isAvc) { - container = StringHelper.TrimStart(container ?? string.Empty, '.'); - foreach (var i in ResponseProfiles) { - if (i.Type != MediaBrowser.Model.Dlna.DlnaProfileType.Video) + if (i.Type != DlnaProfileType.Video) { continue; } - List containers = i.GetContainers(); - if (containers.Count > 0 && !ListHelper.ContainsIgnoreCase(containers, container ?? string.Empty)) + if (!ContainerProfile.ContainsContainer(i.GetContainers(), container)) { continue; } @@ -327,7 +318,7 @@ namespace MediaBrowser.Model.Dlna continue; } - var conditionProcessor = new MediaBrowser.Model.Dlna.ConditionProcessor(); + var conditionProcessor = new ConditionProcessor(); var anyOff = false; foreach (ProfileCondition c in i.Conditions) diff --git a/MediaBrowser.Model/Dlna/ResponseProfile.cs b/MediaBrowser.Model/Dlna/ResponseProfile.cs index 1d4791b5c..f1a001bba 100644 --- a/MediaBrowser.Model/Dlna/ResponseProfile.cs +++ b/MediaBrowser.Model/Dlna/ResponseProfile.cs @@ -33,12 +33,7 @@ namespace MediaBrowser.Model.Dlna public List GetContainers() { - List list = new List(); - foreach (string i in (Container ?? string.Empty).Split(',')) - { - if (!string.IsNullOrEmpty(i)) list.Add(i); - } - return list; + return ContainerProfile.SplitValue(Container); } public List GetAudioCodecs() diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index 1be0b40a5..189ed27e4 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -197,6 +197,40 @@ namespace MediaBrowser.Model.Dlna } } + public static string NormalizeMediaSourceFormatIntoSingleContainer(string inputContainer, DeviceProfile profile, DlnaProfileType type) + { + if (string.IsNullOrWhiteSpace(inputContainer)) + { + return null; + } + + var formats = ContainerProfile.SplitValue(inputContainer); + + if (formats.Count == 1) + { + return formats[0]; + } + + if (profile != null) + { + foreach (var format in formats) + { + foreach (var directPlayProfile in profile.DirectPlayProfiles) + { + if (directPlayProfile.Type == type) + { + if (directPlayProfile.SupportsContainer(format)) + { + return format; + } + } + } + } + } + + return formats[0]; + } + private StreamInfo BuildAudioItem(MediaSourceInfo item, AudioOptions options) { List transcodeReasons = new List(); @@ -214,14 +248,14 @@ namespace MediaBrowser.Model.Dlna if (options.ForceDirectPlay) { playlistItem.PlayMethod = PlayMethod.DirectPlay; - playlistItem.Container = item.Container; + playlistItem.Container = NormalizeMediaSourceFormatIntoSingleContainer(item.Container, options.Profile, DlnaProfileType.Audio); return playlistItem; } if (options.ForceDirectStream) { playlistItem.PlayMethod = PlayMethod.DirectStream; - playlistItem.Container = item.Container; + playlistItem.Container = NormalizeMediaSourceFormatIntoSingleContainer(item.Container, options.Profile, DlnaProfileType.Audio); return playlistItem; } @@ -295,7 +329,7 @@ namespace MediaBrowser.Model.Dlna playlistItem.PlayMethod = PlayMethod.DirectStream; } - playlistItem.Container = item.Container; + playlistItem.Container = NormalizeMediaSourceFormatIntoSingleContainer(item.Container, options.Profile, DlnaProfileType.Audio); return playlistItem; } @@ -648,7 +682,7 @@ namespace MediaBrowser.Model.Dlna if (directPlay != null) { playlistItem.PlayMethod = directPlay.Value; - playlistItem.Container = item.Container; + playlistItem.Container = NormalizeMediaSourceFormatIntoSingleContainer(item.Container, options.Profile, DlnaProfileType.Video); if (subtitleStream != null) { diff --git a/MediaBrowser.Model/Net/MimeTypes.cs b/MediaBrowser.Model/Net/MimeTypes.cs index 2f132cb37..7a2e1f215 100644 --- a/MediaBrowser.Model/Net/MimeTypes.cs +++ b/MediaBrowser.Model/Net/MimeTypes.cs @@ -106,14 +106,15 @@ namespace MediaBrowser.Model.Net return dict; } + public static string GetMimeType(string path) + { + return GetMimeType(path, true); + } + /// /// Gets the type of the MIME. /// - /// The path. - /// System.String. - /// path - /// Argument not supported: + path - public static string GetMimeType(string path) + public static string GetMimeType(string path, bool enableStreamDefault) { if (string.IsNullOrEmpty(path)) { @@ -329,7 +330,12 @@ namespace MediaBrowser.Model.Net return "application/ttml+xml"; } - return "application/octet-stream"; + if (enableStreamDefault) + { + return "application/octet-stream"; + } + + return null; } public static string ToExtension(string mimeType) diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs index 04e549526..12d1d3468 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs @@ -95,14 +95,14 @@ namespace MediaBrowser.Providers.MediaInfo { var mediaStreams = mediaInfo.MediaStreams; - //audio.FormatName = mediaInfo.Container; + audio.Container = mediaInfo.Container; audio.TotalBitrate = mediaInfo.Bitrate; audio.RunTimeTicks = mediaInfo.RunTimeTicks; audio.Size = mediaInfo.Size; var extension = (Path.GetExtension(audio.Path) ?? string.Empty).TrimStart('.'); - audio.Container = extension; + //audio.Container = extension; await FetchDataFromTags(audio, mediaInfo).ConfigureAwait(false); diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs index eaf3505d1..06267f33a 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs @@ -187,6 +187,7 @@ namespace MediaBrowser.Providers.MediaInfo { video.Container = null; } + video.Container = mediaInfo.Container; var chapters = mediaInfo.Chapters ?? new List(); if (blurayInfo != null) -- cgit v1.2.3 From 40442f887ba717ae47620b152315f21b252fe049 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 9 Aug 2017 15:56:38 -0400 Subject: consolidate emby.server.core into emby.server.implementations --- .../Emby.Common.Implementations.csproj | 8 +- Emby.Common.Implementations/Logging/NlogManager.cs | 14 +- .../Networking/NetworkManager.cs | 2 +- .../ScheduledTasks/ScheduledTaskWorker.cs | 6 +- Emby.Common.Implementations/packages.config | 4 +- Emby.Dlna/ContentDirectory/ControlHandler.cs | 36 +- Emby.Dlna/DlnaManager.cs | 10 +- Emby.Dlna/PlayTo/Device.cs | 3 +- Emby.Dlna/Profiles/DefaultProfile.cs | 5 +- Emby.Dlna/Server/DescriptionXmlBuilder.cs | 2 +- Emby.Dlna/Service/BaseControlHandler.cs | 28 +- Emby.Drawing/ImageProcessor.cs | 6 +- Emby.Photos/PhotoProvider.cs | 2 +- Emby.Server.Core/ApplicationHost.cs | 1772 ------------------ Emby.Server.Core/ApplicationPathHelper.cs | 51 - Emby.Server.Core/Cryptography/ASN1.cs | 340 ---- Emby.Server.Core/Cryptography/ASN1Convert.cs | 207 --- Emby.Server.Core/Cryptography/BitConverterLE.cs | 239 --- .../Cryptography/CertificateGenerator.cs | 69 - Emby.Server.Core/Cryptography/CryptoConvert.cs | 745 -------- Emby.Server.Core/Cryptography/PKCS1.cs | 491 ----- Emby.Server.Core/Cryptography/PKCS12.cs | 1934 -------------------- Emby.Server.Core/Cryptography/PKCS7.cs | 1012 ---------- Emby.Server.Core/Cryptography/PKCS8.cs | 495 ----- Emby.Server.Core/Cryptography/PfxGenerator.cs | 75 - Emby.Server.Core/Cryptography/X501Name.cs | 393 ---- Emby.Server.Core/Cryptography/X509Builder.cs | 153 -- Emby.Server.Core/Cryptography/X509Certificate.cs | 563 ------ .../Cryptography/X509CertificateBuilder.cs | 245 --- .../Cryptography/X509CertificateCollection.cs | 201 -- Emby.Server.Core/Cryptography/X509Extension.cs | 208 --- Emby.Server.Core/Cryptography/X509Extensions.cs | 195 -- Emby.Server.Core/Cryptography/X520Attributes.cs | 346 ---- Emby.Server.Core/Emby.Server.Core.csproj | 176 -- .../EntryPoints/ExternalPortForwarding.cs | 334 ---- Emby.Server.Core/HttpServerFactory.cs | 112 -- Emby.Server.Core/IO/LibraryMonitor.cs | 653 ------- Emby.Server.Core/IO/MemoryStreamProvider.cs | 56 - Emby.Server.Core/Localization/TextLocalizer.cs | 64 - Emby.Server.Core/Logging/ConsoleLogger.cs | 16 - Emby.Server.Core/Properties/AssemblyInfo.cs | 34 - Emby.Server.Core/SystemEvents.cs | 50 - Emby.Server.Core/app.config | 11 - Emby.Server.Core/packages.config | 6 - .../Activity/ActivityLogEntryPoint.cs | 3 +- .../Activity/ActivityRepository.cs | 9 +- Emby.Server.Implementations/ApplicationHost.cs | 1749 ++++++++++++++++++ .../ApplicationPathHelper.cs | 51 + .../Channels/ChannelManager.cs | 39 +- .../Configuration/ServerConfigurationManager.cs | 5 +- Emby.Server.Implementations/Cryptography/ASN1.cs | 340 ++++ .../Cryptography/ASN1Convert.cs | 207 +++ .../Cryptography/BitConverterLE.cs | 239 +++ .../Cryptography/CertificateGenerator.cs | 69 + .../Cryptography/CryptoConvert.cs | 745 ++++++++ Emby.Server.Implementations/Cryptography/PKCS1.cs | 491 +++++ Emby.Server.Implementations/Cryptography/PKCS12.cs | 1934 ++++++++++++++++++++ Emby.Server.Implementations/Cryptography/PKCS7.cs | 1012 ++++++++++ Emby.Server.Implementations/Cryptography/PKCS8.cs | 495 +++++ .../Cryptography/PfxGenerator.cs | 75 + .../Cryptography/X501Name.cs | 393 ++++ .../Cryptography/X509Builder.cs | 153 ++ .../Cryptography/X509Certificate.cs | 563 ++++++ .../Cryptography/X509CertificateBuilder.cs | 245 +++ .../Cryptography/X509CertificateCollection.cs | 201 ++ .../Cryptography/X509Extension.cs | 208 +++ .../Cryptography/X509Extensions.cs | 195 ++ .../Cryptography/X520Attributes.cs | 346 ++++ .../Data/BaseSqliteRepository.cs | 25 +- .../Data/SqliteItemRepository.cs | 108 +- Emby.Server.Implementations/Dto/DtoService.cs | 14 +- .../Emby.Server.Implementations.csproj | 84 +- .../EntryPoints/ExternalPortForwarding.cs | 335 ++++ .../EntryPoints/UsageEntryPoint.cs | 3 +- .../HttpServer/HttpListenerHost.cs | 17 +- .../HttpServer/LoggerUtils.cs | 3 +- .../HttpServer/SocketSharp/HttpUtility.cs | 3 +- Emby.Server.Implementations/HttpServerFactory.cs | 110 ++ Emby.Server.Implementations/IO/LibraryMonitor.cs | 652 +++++++ .../IO/MemoryStreamProvider.cs | 56 + .../Images/BaseDynamicImageProvider.cs | 10 +- .../Library/LibraryManager.cs | 37 +- .../Library/LocalTrailerPostScanTask.cs | 5 +- .../Library/MusicManager.cs | 22 +- .../Library/Resolvers/BaseVideoResolver.cs | 7 +- .../Library/Resolvers/Movies/MovieResolver.cs | 12 +- .../Library/Resolvers/PhotoResolver.cs | 2 +- .../Library/Resolvers/TV/EpisodeResolver.cs | 9 +- .../Library/Resolvers/VideoResolver.cs | 12 +- .../Library/SearchEngine.cs | 5 +- .../Library/UserViewManager.cs | 5 +- .../Library/Validators/PeopleValidator.cs | 17 +- .../LiveTv/EmbyTV/EncodedRecorder.cs | 2 +- .../LiveTv/LiveTvDtoService.cs | 6 +- .../LiveTv/LiveTvManager.cs | 51 +- .../LiveTv/LiveTvMediaSourceProvider.cs | 3 +- .../Localization/LocalizationManager.cs | 6 +- .../Localization/TextLocalizer.cs | 63 + .../Logging/ConsoleLogger.cs | 13 + .../Notifications/SqliteNotificationsRepository.cs | 13 +- .../Notifications/WebSocketNotifier.cs | 3 +- .../Photos/PhotoAlbumImageProvider.cs | 2 +- .../Playlists/PlaylistImageProvider.cs | 7 +- .../ScheduledTasks/ChapterImagesTask.cs | 3 +- .../Security/AuthenticationRepository.cs | 9 +- .../Services/ServiceController.cs | 8 +- .../Services/ServiceExec.cs | 3 +- .../Services/ServicePath.cs | 11 +- .../Session/SessionManager.cs | 5 +- .../Social/SharingRepository.cs | 3 +- Emby.Server.Implementations/SystemEvents.cs | 50 + .../UserViews/CollectionFolderImageProvider.cs | 4 +- .../UserViews/DynamicImageProvider.cs | 8 +- Emby.Server.Implementations/packages.config | 5 +- MediaBrowser.Api/ApiEntryPoint.cs | 746 +------- MediaBrowser.Api/FilterService.cs | 2 +- MediaBrowser.Api/GamesService.cs | 7 +- MediaBrowser.Api/Images/ImageService.cs | 13 +- MediaBrowser.Api/ItemUpdateService.cs | 8 +- MediaBrowser.Api/Library/LibraryService.cs | 20 +- MediaBrowser.Api/LiveTv/LiveTvService.cs | 13 +- MediaBrowser.Api/LiveTv/ProgressiveFileCopier.cs | 164 ++ MediaBrowser.Api/LocalizationService.cs | 4 +- MediaBrowser.Api/MediaBrowser.Api.csproj | 18 +- MediaBrowser.Api/Movies/MoviesService.cs | 44 +- MediaBrowser.Api/Music/InstantMixService.cs | 10 +- MediaBrowser.Api/Playback/BaseStreamingService.cs | 1024 ----------- MediaBrowser.Api/Playback/Hls/BaseHlsService.cs | 331 ---- MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs | 970 ---------- MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs | 163 -- MediaBrowser.Api/Playback/Hls/VideoHlsService.cs | 137 -- MediaBrowser.Api/Playback/MediaInfoService.cs | 614 ------- .../Playback/Progressive/AudioService.cs | 67 - .../Progressive/BaseProgressiveStreamingService.cs | 429 ----- .../Progressive/ProgressiveStreamWriter.cs | 193 -- .../Playback/Progressive/VideoService.cs | 100 - .../Playback/StaticRemoteStreamWriter.cs | 47 - MediaBrowser.Api/Playback/StreamRequest.cs | 63 - MediaBrowser.Api/Playback/StreamState.cs | 259 --- MediaBrowser.Api/Playback/TranscodingThrottler.cs | 176 -- MediaBrowser.Api/Playback/UniversalAudioService.cs | 349 ---- MediaBrowser.Api/PlaylistService.cs | 7 +- MediaBrowser.Api/Reports/Data/ReportBuilder.cs | 2 +- MediaBrowser.Api/SearchService.cs | 6 +- MediaBrowser.Api/Session/SessionsService.cs | 2 +- MediaBrowser.Api/SimilarItemsHelper.cs | 5 +- MediaBrowser.Api/SuggestionsService.cs | 3 +- MediaBrowser.Api/System/SystemService.cs | 5 +- MediaBrowser.Api/TestService.cs | 77 - MediaBrowser.Api/TvShowsService.cs | 23 +- .../UserLibrary/BaseItemsByNameService.cs | 3 +- MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs | 4 +- MediaBrowser.Api/UserLibrary/ItemsService.cs | 7 +- MediaBrowser.Api/UserLibrary/PlaystateService.cs | 451 ----- MediaBrowser.Api/UserLibrary/UserLibraryService.cs | 6 +- .../Entities/AggregateFolder.cs | 4 +- .../Entities/Audio/MusicArtist.cs | 2 +- MediaBrowser.Controller/Entities/BaseItem.cs | 132 +- .../Entities/CollectionFolder.cs | 4 +- MediaBrowser.Controller/Entities/Folder.cs | 9 +- MediaBrowser.Controller/Entities/Game.cs | 4 +- MediaBrowser.Controller/Entities/IHasMetadata.cs | 6 +- MediaBrowser.Controller/Entities/TV/Series.cs | 30 +- MediaBrowser.Controller/Entities/TagExtensions.cs | 18 +- .../Entities/UserViewBuilder.cs | 4 +- MediaBrowser.Controller/Entities/Video.cs | 3 +- MediaBrowser.Controller/IO/FileData.cs | 17 +- MediaBrowser.Controller/Library/ILibraryManager.cs | 13 +- MediaBrowser.Controller/Library/IMusicManager.cs | 10 +- MediaBrowser.Controller/LiveTv/ILiveTvManager.cs | 2 +- .../Net/AuthenticatedAttribute.cs | 4 +- .../Persistence/IItemRepository.cs | 2 +- .../Providers/DirectoryService.cs | 55 +- .../Providers/IDirectoryService.cs | 8 +- .../Images/ImagesByNameImageProvider.cs | 58 - .../Images/LocalImageProvider.cs | 18 +- .../MediaBrowser.LocalMetadata.csproj | 1 - .../Parsers/BaseItemXmlParser.cs | 18 +- MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs | 10 +- .../BdInfo/BdInfoExaminer.cs | 201 -- .../Configuration/EncodingConfigurationFactory.cs | 58 - MediaBrowser.MediaEncoding/Encoder/AudioEncoder.cs | 62 - MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs | 375 ---- .../Encoder/EncoderValidator.cs | 219 --- MediaBrowser.MediaEncoding/Encoder/EncodingJob.cs | 197 -- .../Encoder/EncodingJobFactory.cs | 305 --- .../Encoder/EncodingUtils.cs | 70 - .../Encoder/FontConfigLoader.cs | 182 -- MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 1129 ------------ MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs | 66 - .../MediaBrowser.MediaEncoding.csproj | 100 - .../MediaBrowser.MediaEncoding.nuget.targets | 6 - .../Probing/FFProbeHelpers.cs | 117 -- .../Probing/InternalMediaInfoResult.cs | 341 ---- .../Probing/ProbeResultNormalizer.cs | 1389 -------------- .../Properties/AssemblyInfo.cs | 33 - MediaBrowser.MediaEncoding/Subtitles/AssParser.cs | 120 -- .../Subtitles/ConfigurationExtension.cs | 29 - .../Subtitles/ISubtitleParser.cs | 17 - .../Subtitles/ISubtitleWriter.cs | 20 - MediaBrowser.MediaEncoding/Subtitles/JsonWriter.cs | 28 - .../Subtitles/OpenSubtitleDownloader.cs | 349 ---- .../Subtitles/ParserValues.cs | 7 - MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs | 90 - MediaBrowser.MediaEncoding/Subtitles/SrtWriter.cs | 39 - MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs | 394 ---- .../Subtitles/SubtitleEncoder.cs | 738 -------- MediaBrowser.MediaEncoding/Subtitles/TtmlWriter.cs | 60 - MediaBrowser.MediaEncoding/Subtitles/VttWriter.cs | 44 - MediaBrowser.MediaEncoding/packages.config | 3 - MediaBrowser.Model/Dlna/CodecProfile.cs | 1 - MediaBrowser.Model/Dlna/ConditionProcessor.cs | 1 - MediaBrowser.Model/Dlna/DirectPlayProfile.cs | 1 - MediaBrowser.Model/Dlna/StreamInfo.cs | 4 +- MediaBrowser.Model/Dto/BaseItemDto.cs | 36 +- MediaBrowser.Model/Entities/MediaStream.cs | 4 +- MediaBrowser.Model/Extensions/LinqExtensions.cs | 26 + .../Globalization/ILocalizationManager.cs | 4 +- MediaBrowser.Model/Net/ISocket.cs | 1 - MediaBrowser.Model/Services/IHttpRequest.cs | 1 - MediaBrowser.Model/Services/IHttpResponse.cs | 1 - MediaBrowser.Model/Services/IHttpResult.cs | 1 - .../Services/QueryParamCollection.cs | 3 +- MediaBrowser.Model/Social/ISharingRepository.cs | 6 +- MediaBrowser.Model/Tasks/ScheduledTaskHelpers.cs | 12 +- MediaBrowser.Model/Tasks/TaskInfo.cs | 4 +- .../Books/AudioBookMetadataService.cs | 2 +- .../Books/AudioPodcastMetadataService.cs | 2 +- .../Books/BookMetadataService.cs | 2 +- .../BoxSets/BoxSetMetadataService.cs | 2 +- .../BoxSets/MovieDbBoxSetImageProvider.cs | 6 +- .../Channels/ChannelMetadataService.cs | 2 +- .../Folders/CollectionFolderMetadataService.cs | 4 +- .../Folders/FolderMetadataService.cs | 2 +- .../Folders/UserViewMetadataService.cs | 2 +- .../GameGenres/GameGenreMetadataService.cs | 2 +- .../Games/GameMetadataService.cs | 2 +- .../Games/GameSystemMetadataService.cs | 2 +- .../Genres/GenreMetadataService.cs | 2 +- .../LiveTv/AudioRecordingService.cs | 2 +- .../LiveTv/ChannelMetadataService.cs | 2 +- .../LiveTv/ProgramMetadataService.cs | 2 +- .../LiveTv/VideoRecordingService.cs | 2 +- MediaBrowser.Providers/Manager/ImageSaver.cs | 3 +- .../Manager/ItemImageProvider.cs | 12 +- MediaBrowser.Providers/Manager/MetadataService.cs | 12 +- MediaBrowser.Providers/Manager/ProviderManager.cs | 4 +- MediaBrowser.Providers/Manager/ProviderUtils.cs | 18 +- .../MediaInfo/AudioImageProvider.cs | 3 +- .../MediaInfo/FFProbeAudioInfo.cs | 8 +- .../MediaInfo/FFProbeVideoInfo.cs | 9 +- .../MediaInfo/SubtitleResolver.cs | 2 +- .../MediaInfo/SubtitleScheduledTask.cs | 3 +- .../Movies/GenericMovieDbInfo.cs | 9 +- .../Movies/MovieDbImageProvider.cs | 6 +- MediaBrowser.Providers/Movies/MovieDbProvider.cs | 3 +- .../Movies/MovieMetadataService.cs | 4 +- .../Music/AlbumMetadataService.cs | 8 +- .../Music/ArtistMetadataService.cs | 4 +- .../Music/AudioMetadataService.cs | 5 +- .../Music/MusicBrainzAlbumProvider.cs | 6 +- .../Music/MusicBrainzArtistProvider.cs | 6 +- .../Music/MusicVideoMetadataService.cs | 5 +- .../MusicGenres/MusicGenreMetadataService.cs | 2 +- .../People/MovieDbPersonImageProvider.cs | 3 +- .../People/MovieDbPersonProvider.cs | 2 +- .../People/PersonMetadataService.cs | 2 +- .../Photos/PhotoAlbumMetadataService.cs | 2 +- .../Photos/PhotoMetadataService.cs | 2 +- .../Playlists/PlaylistMetadataService.cs | 2 +- .../Studios/StudioMetadataService.cs | 2 +- .../Subtitles/SubtitleManager.cs | 3 +- .../TV/EpisodeMetadataService.cs | 2 +- MediaBrowser.Providers/TV/SeasonMetadataService.cs | 2 +- MediaBrowser.Providers/TV/SeriesMetadataService.cs | 2 +- .../TV/TheMovieDb/MovieDbEpisodeImageProvider.cs | 3 +- .../TV/TheMovieDb/MovieDbSeriesImageProvider.cs | 6 +- .../TV/TheMovieDb/MovieDbSeriesProvider.cs | 3 +- .../TV/TheTVDB/TvdbPrescanTask.cs | 7 +- .../TV/TheTVDB/TvdbSeasonImageProvider.cs | 3 +- .../TV/TheTVDB/TvdbSeriesImageProvider.cs | 3 +- .../TV/TheTVDB/TvdbSeriesProvider.cs | 13 +- .../Users/UserMetadataService.cs | 2 +- .../Videos/VideoMetadataService.cs | 2 +- .../Years/YearMetadataService.cs | 2 +- .../MediaBrowser.Server.Mono.csproj | 22 +- MediaBrowser.Server.Mono/Program.cs | 4 +- MediaBrowser.Server.Mono/packages.config | 8 +- MediaBrowser.ServerApplication/MainStartup.cs | 7 +- .../MediaBrowser.ServerApplication.csproj | 22 +- MediaBrowser.ServerApplication/packages.config | 8 +- MediaBrowser.Tests/MediaBrowser.Tests.csproj | 29 +- .../MediaEncoding/Subtitles/AssParserTests.cs | 1 + .../MediaEncoding/Subtitles/SrtParserTests.cs | 2 +- .../MediaEncoding/Subtitles/VttWriterTest.cs | 2 +- MediaBrowser.WebDashboard/Api/PackageCreator.cs | 3 +- MediaBrowser.XbmcMetadata/EntryPoint.cs | 2 +- MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs | 15 +- MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs | 4 +- MediaBrowser.sln | 79 +- Mono.Nat/NatUtility.cs | 6 +- Mono.Nat/Pmp/PmpNatDevice.cs | 3 +- Nuget/MediaBrowser.Common.nuspec | 2 +- Nuget/MediaBrowser.Server.Core.nuspec | 4 +- SocketHttpListener/Net/WebHeaderCollection.cs | 3 +- 305 files changed, 12088 insertions(+), 25246 deletions(-) delete mode 100644 Emby.Server.Core/ApplicationHost.cs delete mode 100644 Emby.Server.Core/ApplicationPathHelper.cs delete mode 100644 Emby.Server.Core/Cryptography/ASN1.cs delete mode 100644 Emby.Server.Core/Cryptography/ASN1Convert.cs delete mode 100644 Emby.Server.Core/Cryptography/BitConverterLE.cs delete mode 100644 Emby.Server.Core/Cryptography/CertificateGenerator.cs delete mode 100644 Emby.Server.Core/Cryptography/CryptoConvert.cs delete mode 100644 Emby.Server.Core/Cryptography/PKCS1.cs delete mode 100644 Emby.Server.Core/Cryptography/PKCS12.cs delete mode 100644 Emby.Server.Core/Cryptography/PKCS7.cs delete mode 100644 Emby.Server.Core/Cryptography/PKCS8.cs delete mode 100644 Emby.Server.Core/Cryptography/PfxGenerator.cs delete mode 100644 Emby.Server.Core/Cryptography/X501Name.cs delete mode 100644 Emby.Server.Core/Cryptography/X509Builder.cs delete mode 100644 Emby.Server.Core/Cryptography/X509Certificate.cs delete mode 100644 Emby.Server.Core/Cryptography/X509CertificateBuilder.cs delete mode 100644 Emby.Server.Core/Cryptography/X509CertificateCollection.cs delete mode 100644 Emby.Server.Core/Cryptography/X509Extension.cs delete mode 100644 Emby.Server.Core/Cryptography/X509Extensions.cs delete mode 100644 Emby.Server.Core/Cryptography/X520Attributes.cs delete mode 100644 Emby.Server.Core/Emby.Server.Core.csproj delete mode 100644 Emby.Server.Core/EntryPoints/ExternalPortForwarding.cs delete mode 100644 Emby.Server.Core/HttpServerFactory.cs delete mode 100644 Emby.Server.Core/IO/LibraryMonitor.cs delete mode 100644 Emby.Server.Core/IO/MemoryStreamProvider.cs delete mode 100644 Emby.Server.Core/Localization/TextLocalizer.cs delete mode 100644 Emby.Server.Core/Logging/ConsoleLogger.cs delete mode 100644 Emby.Server.Core/Properties/AssemblyInfo.cs delete mode 100644 Emby.Server.Core/SystemEvents.cs delete mode 100644 Emby.Server.Core/app.config delete mode 100644 Emby.Server.Core/packages.config create mode 100644 Emby.Server.Implementations/ApplicationHost.cs create mode 100644 Emby.Server.Implementations/ApplicationPathHelper.cs create mode 100644 Emby.Server.Implementations/Cryptography/ASN1.cs create mode 100644 Emby.Server.Implementations/Cryptography/ASN1Convert.cs create mode 100644 Emby.Server.Implementations/Cryptography/BitConverterLE.cs create mode 100644 Emby.Server.Implementations/Cryptography/CertificateGenerator.cs create mode 100644 Emby.Server.Implementations/Cryptography/CryptoConvert.cs create mode 100644 Emby.Server.Implementations/Cryptography/PKCS1.cs create mode 100644 Emby.Server.Implementations/Cryptography/PKCS12.cs create mode 100644 Emby.Server.Implementations/Cryptography/PKCS7.cs create mode 100644 Emby.Server.Implementations/Cryptography/PKCS8.cs create mode 100644 Emby.Server.Implementations/Cryptography/PfxGenerator.cs create mode 100644 Emby.Server.Implementations/Cryptography/X501Name.cs create mode 100644 Emby.Server.Implementations/Cryptography/X509Builder.cs create mode 100644 Emby.Server.Implementations/Cryptography/X509Certificate.cs create mode 100644 Emby.Server.Implementations/Cryptography/X509CertificateBuilder.cs create mode 100644 Emby.Server.Implementations/Cryptography/X509CertificateCollection.cs create mode 100644 Emby.Server.Implementations/Cryptography/X509Extension.cs create mode 100644 Emby.Server.Implementations/Cryptography/X509Extensions.cs create mode 100644 Emby.Server.Implementations/Cryptography/X520Attributes.cs create mode 100644 Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs create mode 100644 Emby.Server.Implementations/HttpServerFactory.cs create mode 100644 Emby.Server.Implementations/IO/LibraryMonitor.cs create mode 100644 Emby.Server.Implementations/IO/MemoryStreamProvider.cs create mode 100644 Emby.Server.Implementations/Localization/TextLocalizer.cs create mode 100644 Emby.Server.Implementations/Logging/ConsoleLogger.cs create mode 100644 Emby.Server.Implementations/SystemEvents.cs create mode 100644 MediaBrowser.Api/LiveTv/ProgressiveFileCopier.cs delete mode 100644 MediaBrowser.Api/Playback/BaseStreamingService.cs delete mode 100644 MediaBrowser.Api/Playback/Hls/BaseHlsService.cs delete mode 100644 MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs delete mode 100644 MediaBrowser.Api/Playback/Hls/HlsSegmentService.cs delete mode 100644 MediaBrowser.Api/Playback/Hls/VideoHlsService.cs delete mode 100644 MediaBrowser.Api/Playback/MediaInfoService.cs delete mode 100644 MediaBrowser.Api/Playback/Progressive/AudioService.cs delete mode 100644 MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs delete mode 100644 MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs delete mode 100644 MediaBrowser.Api/Playback/Progressive/VideoService.cs delete mode 100644 MediaBrowser.Api/Playback/StaticRemoteStreamWriter.cs delete mode 100644 MediaBrowser.Api/Playback/StreamRequest.cs delete mode 100644 MediaBrowser.Api/Playback/StreamState.cs delete mode 100644 MediaBrowser.Api/Playback/TranscodingThrottler.cs delete mode 100644 MediaBrowser.Api/Playback/UniversalAudioService.cs delete mode 100644 MediaBrowser.Api/TestService.cs delete mode 100644 MediaBrowser.Api/UserLibrary/PlaystateService.cs delete mode 100644 MediaBrowser.LocalMetadata/Images/ImagesByNameImageProvider.cs delete mode 100644 MediaBrowser.MediaEncoding/BdInfo/BdInfoExaminer.cs delete mode 100644 MediaBrowser.MediaEncoding/Configuration/EncodingConfigurationFactory.cs delete mode 100644 MediaBrowser.MediaEncoding/Encoder/AudioEncoder.cs delete mode 100644 MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs delete mode 100644 MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs delete mode 100644 MediaBrowser.MediaEncoding/Encoder/EncodingJob.cs delete mode 100644 MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs delete mode 100644 MediaBrowser.MediaEncoding/Encoder/EncodingUtils.cs delete mode 100644 MediaBrowser.MediaEncoding/Encoder/FontConfigLoader.cs delete mode 100644 MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs delete mode 100644 MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs delete mode 100644 MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj delete mode 100644 MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.nuget.targets delete mode 100644 MediaBrowser.MediaEncoding/Probing/FFProbeHelpers.cs delete mode 100644 MediaBrowser.MediaEncoding/Probing/InternalMediaInfoResult.cs delete mode 100644 MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs delete mode 100644 MediaBrowser.MediaEncoding/Properties/AssemblyInfo.cs delete mode 100644 MediaBrowser.MediaEncoding/Subtitles/AssParser.cs delete mode 100644 MediaBrowser.MediaEncoding/Subtitles/ConfigurationExtension.cs delete mode 100644 MediaBrowser.MediaEncoding/Subtitles/ISubtitleParser.cs delete mode 100644 MediaBrowser.MediaEncoding/Subtitles/ISubtitleWriter.cs delete mode 100644 MediaBrowser.MediaEncoding/Subtitles/JsonWriter.cs delete mode 100644 MediaBrowser.MediaEncoding/Subtitles/OpenSubtitleDownloader.cs delete mode 100644 MediaBrowser.MediaEncoding/Subtitles/ParserValues.cs delete mode 100644 MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs delete mode 100644 MediaBrowser.MediaEncoding/Subtitles/SrtWriter.cs delete mode 100644 MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs delete mode 100644 MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs delete mode 100644 MediaBrowser.MediaEncoding/Subtitles/TtmlWriter.cs delete mode 100644 MediaBrowser.MediaEncoding/Subtitles/VttWriter.cs delete mode 100644 MediaBrowser.MediaEncoding/packages.config (limited to 'MediaBrowser.MediaEncoding') diff --git a/Emby.Common.Implementations/Emby.Common.Implementations.csproj b/Emby.Common.Implementations/Emby.Common.Implementations.csproj index 00c90d16e..879e8e82f 100644 --- a/Emby.Common.Implementations/Emby.Common.Implementations.csproj +++ b/Emby.Common.Implementations/Emby.Common.Implementations.csproj @@ -32,12 +32,10 @@ - ..\packages\NLog.4.4.11\lib\net45\NLog.dll - True + ..\packages\NLog.4.4.12\lib\net45\NLog.dll - - ..\packages\ServiceStack.Text.4.5.8\lib\net45\ServiceStack.Text.dll - True + + ..\packages\ServiceStack.Text.4.5.12\lib\net45\ServiceStack.Text.dll ..\packages\SharpCompress.0.14.0\lib\net45\SharpCompress.dll diff --git a/Emby.Common.Implementations/Logging/NlogManager.cs b/Emby.Common.Implementations/Logging/NlogManager.cs index f7b723e8b..4446e2cdb 100644 --- a/Emby.Common.Implementations/Logging/NlogManager.cs +++ b/Emby.Common.Implementations/Logging/NlogManager.cs @@ -152,13 +152,23 @@ namespace Emby.Common.Implementations.Logging RemoveTarget("ApplicationLogFileWrapper"); - var wrapper = new AsyncTargetWrapper(); + // https://github.com/NLog/NLog/wiki/Performance + var wrapper = new AsyncTargetWrapper + { + OverflowAction = AsyncTargetWrapperOverflowAction.Block, + QueueLimit = 10000, + BatchSize = 500, + TimeToSleepBetweenBatches = 50 + }; + wrapper.Name = "ApplicationLogFileWrapper"; var logFile = new FileTarget { FileName = path, - Layout = "${longdate} ${level} ${logger}: ${message}" + Layout = "${longdate} ${level} ${logger}: ${message}", + KeepFileOpen = true, + ConcurrentWrites = false }; logFile.Name = "ApplicationLogFile"; diff --git a/Emby.Common.Implementations/Networking/NetworkManager.cs b/Emby.Common.Implementations/Networking/NetworkManager.cs index 2f218656c..354107bb7 100644 --- a/Emby.Common.Implementations/Networking/NetworkManager.cs +++ b/Emby.Common.Implementations/Networking/NetworkManager.cs @@ -506,7 +506,7 @@ namespace Emby.Common.Implementations.Networking public async Task GetHostAddressesAsync(string host) { var addresses = await Dns.GetHostAddressesAsync(host).ConfigureAwait(false); - return addresses.Select(ToIpAddressInfo).ToArray(); + return addresses.Select(ToIpAddressInfo).ToArray(addresses.Length); } /// diff --git a/Emby.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs b/Emby.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs index c373ffddb..dd840677a 100644 --- a/Emby.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs +++ b/Emby.Common.Implementations/ScheduledTasks/ScheduledTaskWorker.cs @@ -14,6 +14,7 @@ using MediaBrowser.Model.Logging; using MediaBrowser.Model.Serialization; using MediaBrowser.Model.System; using MediaBrowser.Model.Tasks; +using MediaBrowser.Model.Extensions; namespace Emby.Common.Implementations.ScheduledTasks { @@ -274,7 +275,8 @@ namespace Emby.Common.Implementations.ScheduledTasks { get { - return InternalTriggers.Select(i => i.Item1).ToArray(); + var triggers = InternalTriggers; + return triggers.Select(i => i.Item1).ToArray(triggers.Length); } set { @@ -288,7 +290,7 @@ namespace Emby.Common.Implementations.ScheduledTasks SaveTriggers(triggerList); - InternalTriggers = triggerList.Select(i => new Tuple(i, GetTrigger(i))).ToArray(); + InternalTriggers = triggerList.Select(i => new Tuple(i, GetTrigger(i))).ToArray(triggerList.Length); } } diff --git a/Emby.Common.Implementations/packages.config b/Emby.Common.Implementations/packages.config index a255465cc..a9fc75af6 100644 --- a/Emby.Common.Implementations/packages.config +++ b/Emby.Common.Implementations/packages.config @@ -1,7 +1,7 @@  - - + + \ No newline at end of file diff --git a/Emby.Dlna/ContentDirectory/ControlHandler.cs b/Emby.Dlna/ContentDirectory/ControlHandler.cs index 4d82b6b25..4be2dc945 100644 --- a/Emby.Dlna/ContentDirectory/ControlHandler.cs +++ b/Emby.Dlna/ContentDirectory/ControlHandler.cs @@ -30,6 +30,7 @@ using MediaBrowser.Controller.Playlists; using MediaBrowser.Controller.TV; using MediaBrowser.Model.Globalization; using MediaBrowser.Model.Xml; +using MediaBrowser.Model.Extensions; namespace Emby.Dlna.ContentDirectory { @@ -457,14 +458,14 @@ namespace Emby.Dlna.ContentDirectory { Limit = limit, StartIndex = startIndex, - SortBy = sortOrders.ToArray(), + SortBy = sortOrders.ToArray(sortOrders.Count), SortOrder = sort.SortOrder, User = user, Recursive = true, IsMissing = false, ExcludeItemTypes = new[] { typeof(Game).Name, typeof(Book).Name }, IsFolder = isFolder, - MediaTypes = mediaTypes.ToArray(), + MediaTypes = mediaTypes.ToArray(mediaTypes.Count), DtoOptions = GetDtoOptions() }); } @@ -508,12 +509,12 @@ namespace Emby.Dlna.ContentDirectory { ItemId = item.Id - }).ToArray(); + }); var result = new QueryResult { - Items = items.Select(i => new ServerItem(i)).ToArray(), - TotalRecordCount = items.Length + Items = items.Select(i => new ServerItem(i)).ToArray(items.Count), + TotalRecordCount = items.Count }; return ApplyPaging(result, startIndex, limit); @@ -662,7 +663,7 @@ namespace Emby.Dlna.ContentDirectory return new QueryResult { - Items = list.ToArray(), + Items = list.ToArray(list.Count), TotalRecordCount = list.Count }; } @@ -740,7 +741,7 @@ namespace Emby.Dlna.ContentDirectory return new QueryResult { - Items = list.ToArray(), + Items = list.ToArray(list.Count), TotalRecordCount = list.Count }; } @@ -828,7 +829,7 @@ namespace Emby.Dlna.ContentDirectory return new QueryResult { - Items = list.ToArray(), + Items = list.ToArray(list.Count), TotalRecordCount = list.Count }; } @@ -995,7 +996,7 @@ namespace Emby.Dlna.ContentDirectory var result = new QueryResult { TotalRecordCount = genresResult.TotalRecordCount, - Items = genresResult.Items.Select(i => i.Item1).ToArray() + Items = genresResult.Items.Select(i => i.Item1).ToArray(genresResult.Items.Length) }; return ToResult(result); @@ -1013,7 +1014,7 @@ namespace Emby.Dlna.ContentDirectory var result = new QueryResult { TotalRecordCount = genresResult.TotalRecordCount, - Items = genresResult.Items.Select(i => i.Item1).ToArray() + Items = genresResult.Items.Select(i => i.Item1).ToArray(genresResult.Items.Length) }; return ToResult(result); @@ -1031,7 +1032,7 @@ namespace Emby.Dlna.ContentDirectory var result = new QueryResult { TotalRecordCount = artists.TotalRecordCount, - Items = artists.Items.Select(i => i.Item1).ToArray() + Items = artists.Items.Select(i => i.Item1).ToArray(artists.Items.Length) }; return ToResult(result); @@ -1049,7 +1050,7 @@ namespace Emby.Dlna.ContentDirectory var result = new QueryResult { TotalRecordCount = artists.TotalRecordCount, - Items = artists.Items.Select(i => i.Item1).ToArray() + Items = artists.Items.Select(i => i.Item1).ToArray(artists.Items.Length) }; return ToResult(result); @@ -1068,7 +1069,7 @@ namespace Emby.Dlna.ContentDirectory var result = new QueryResult { TotalRecordCount = artists.TotalRecordCount, - Items = artists.Items.Select(i => i.Item1).ToArray() + Items = artists.Items.Select(i => i.Item1).ToArray(artists.Items.Length) }; return ToResult(result); @@ -1196,7 +1197,7 @@ namespace Emby.Dlna.ContentDirectory { var serverItems = result .Select(i => new ServerItem(i)) - .ToArray(); + .ToArray(result.Count); return new QueryResult { @@ -1210,7 +1211,7 @@ namespace Emby.Dlna.ContentDirectory var serverItems = result .Items .Select(i => new ServerItem(i)) - .ToArray(); + .ToArray(result.Items.Length); return new QueryResult { @@ -1227,7 +1228,7 @@ namespace Emby.Dlna.ContentDirectory sortOrders.Add(ItemSortBy.SortName); } - query.SortBy = sortOrders.ToArray(); + query.SortBy = sortOrders.ToArray(sortOrders.Count); query.SortOrder = sort.SortOrder; } @@ -1243,8 +1244,7 @@ namespace Emby.Dlna.ContentDirectory DtoOptions = GetDtoOptions() }); - var serverItems = itemsResult.Items.Select(i => new ServerItem(i)) - .ToArray(); + var serverItems = itemsResult.Items.Select(i => new ServerItem(i)).ToArray(itemsResult.Items.Length); return new QueryResult { diff --git a/Emby.Dlna/DlnaManager.cs b/Emby.Dlna/DlnaManager.cs index 82975ce22..847f63619 100644 --- a/Emby.Dlna/DlnaManager.cs +++ b/Emby.Dlna/DlnaManager.cs @@ -18,6 +18,7 @@ using System.Text; using System.Text.RegularExpressions; using MediaBrowser.Model.IO; using MediaBrowser.Model.Reflection; +using MediaBrowser.Model.Extensions; namespace Emby.Dlna { @@ -106,7 +107,6 @@ namespace Emby.Dlna } else { - _logger.Debug("No matching device profile found. The default will need to be used."); LogUnmatchedProfile(deviceInfo); } @@ -220,12 +220,8 @@ namespace Emby.Dlna } else { - var msg = new StringBuilder(); - foreach (var header in headers) - { - msg.AppendLine(header.Key + ": " + header.Value); - } - _logger.LogMultiline("No matching device profile found. The default will need to be used.", LogSeverity.Info, msg); + var headerString = string.Join(", ", headers.Select(i => string.Format("{0}={1}", i.Key, i.Value)).ToArray(headers.Count)); + _logger.Debug("No matching device profile found. {0}", headerString); } return profile; diff --git a/Emby.Dlna/PlayTo/Device.cs b/Emby.Dlna/PlayTo/Device.cs index e22298010..ff493e365 100644 --- a/Emby.Dlna/PlayTo/Device.cs +++ b/Emby.Dlna/PlayTo/Device.cs @@ -15,6 +15,7 @@ using System.Threading.Tasks; using System.Xml.Linq; using Emby.Dlna.Server; using MediaBrowser.Model.Threading; +using MediaBrowser.Model.Extensions; namespace Emby.Dlna.PlayTo { @@ -890,7 +891,7 @@ namespace Emby.Dlna.PlayTo if (room != null && !string.IsNullOrWhiteSpace(room.Value)) friendlyNames.Add(room.Value); - deviceProperties.Name = string.Join(" ", friendlyNames.ToArray()); + deviceProperties.Name = string.Join(" ", friendlyNames.ToArray(friendlyNames.Count)); var model = document.Descendants(uPnpNamespaces.ud.GetName("modelName")).FirstOrDefault(); if (model != null) diff --git a/Emby.Dlna/Profiles/DefaultProfile.cs b/Emby.Dlna/Profiles/DefaultProfile.cs index 06ce93640..ff025152a 100644 --- a/Emby.Dlna/Profiles/DefaultProfile.cs +++ b/Emby.Dlna/Profiles/DefaultProfile.cs @@ -1,6 +1,7 @@ using MediaBrowser.Model.Dlna; using System.Linq; using System.Xml.Serialization; +using MediaBrowser.Model.Extensions; namespace Emby.Dlna.Profiles { @@ -164,7 +165,7 @@ namespace Emby.Dlna.Profiles public void AddXmlRootAttribute(string name, string value) { var atts = XmlRootAttributes ?? new XmlAttribute[] { }; - var list = atts.ToList(); + var list = atts.ToList(atts.Length); list.Add(new XmlAttribute { @@ -172,7 +173,7 @@ namespace Emby.Dlna.Profiles Value = value }); - XmlRootAttributes = list.ToArray(); + XmlRootAttributes = list.ToArray(list.Count); } } } diff --git a/Emby.Dlna/Server/DescriptionXmlBuilder.cs b/Emby.Dlna/Server/DescriptionXmlBuilder.cs index 2a4a5792f..bba4adc5f 100644 --- a/Emby.Dlna/Server/DescriptionXmlBuilder.cs +++ b/Emby.Dlna/Server/DescriptionXmlBuilder.cs @@ -226,7 +226,7 @@ namespace Emby.Dlna.Server } } - var characters = characterList.ToArray(); + var characters = characterList.ToArray(characterList.Count); var serverName = new string(characters); diff --git a/Emby.Dlna/Service/BaseControlHandler.cs b/Emby.Dlna/Service/BaseControlHandler.cs index 3092589c1..7cd10bd01 100644 --- a/Emby.Dlna/Service/BaseControlHandler.cs +++ b/Emby.Dlna/Service/BaseControlHandler.cs @@ -11,6 +11,7 @@ using System.Xml; using Emby.Dlna.Didl; using MediaBrowser.Controller.Extensions; using MediaBrowser.Model.Xml; +using MediaBrowser.Model.Extensions; namespace Emby.Dlna.Service { @@ -235,26 +236,29 @@ namespace Emby.Dlna.Service private void LogRequest(ControlRequest request) { - var builder = new StringBuilder(); + if (!Config.GetDlnaConfiguration().EnableDebugLog) + { + return; + } - var headers = string.Join(", ", request.Headers.Select(i => string.Format("{0}={1}", i.Key, i.Value)).ToArray()); - builder.AppendFormat("Headers: {0}", headers); - builder.AppendLine(); - //builder.Append(request.InputXml); + var originalHeaders = request.Headers; + var headers = string.Join(", ", originalHeaders.Select(i => string.Format("{0}={1}", i.Key, i.Value)).ToArray(originalHeaders.Count)); - Logger.LogMultiline("Control request", LogSeverity.Debug, builder); + Logger.Debug("Control request. Headers: {0}", headers); } private void LogResponse(ControlResponse response) { - var builder = new StringBuilder(); + if (!Config.GetDlnaConfiguration().EnableDebugLog) + { + return; + } - var headers = string.Join(", ", response.Headers.Select(i => string.Format("{0}={1}", i.Key, i.Value)).ToArray()); - builder.AppendFormat("Headers: {0}", headers); - builder.AppendLine(); - builder.Append(response.Xml); + var originalHeaders = response.Headers; + var headers = string.Join(", ", originalHeaders.Select(i => string.Format("{0}={1}", i.Key, i.Value)).ToArray(originalHeaders.Count)); + //builder.Append(response.Xml); - Logger.LogMultiline("Control response", LogSeverity.Debug, builder); + Logger.Debug("Control response. Headers: {0}", headers); } } } diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs index cc7b77de6..bd23eba7a 100644 --- a/Emby.Drawing/ImageProcessor.cs +++ b/Emby.Drawing/ImageProcessor.cs @@ -17,12 +17,10 @@ using System.Threading; using System.Threading.Tasks; using MediaBrowser.Model.IO; using Emby.Drawing.Common; - -using MediaBrowser.Controller.IO; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Net; using MediaBrowser.Model.Threading; -using TagLib; +using MediaBrowser.Model.Extensions; namespace Emby.Drawing { @@ -662,7 +660,7 @@ namespace Emby.Drawing var cacheKeys = imageEnhancers.Select(i => i.GetConfigurationCacheKey(item, imageType)).ToList(); cacheKeys.Add(originalImagePath + dateModified.Ticks); - return string.Join("|", cacheKeys.ToArray()).GetMD5().ToString("N"); + return string.Join("|", cacheKeys.ToArray(cacheKeys.Count)).GetMD5().ToString("N"); } /// diff --git a/Emby.Photos/PhotoProvider.cs b/Emby.Photos/PhotoProvider.cs index 57047cf81..c3c30ab6d 100644 --- a/Emby.Photos/PhotoProvider.cs +++ b/Emby.Photos/PhotoProvider.cs @@ -111,7 +111,7 @@ namespace Emby.Photos } item.Genres = image.ImageTag.Genres.ToList(); - item.Tags = image.ImageTag.Keywords.ToList(); + item.Tags = image.ImageTag.Keywords; item.Software = image.ImageTag.Software; if (image.ImageTag.Orientation == TagLib.Image.ImageOrientation.None) diff --git a/Emby.Server.Core/ApplicationHost.cs b/Emby.Server.Core/ApplicationHost.cs deleted file mode 100644 index 68cb2a4e3..000000000 --- a/Emby.Server.Core/ApplicationHost.cs +++ /dev/null @@ -1,1772 +0,0 @@ -using MediaBrowser.Api; -using MediaBrowser.Common; -using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.Events; -using MediaBrowser.Common.Extensions; -using Emby.Common.Implementations.ScheduledTasks; -using MediaBrowser.Common.Net; -using MediaBrowser.Common.Progress; -using MediaBrowser.Controller; -using MediaBrowser.Controller.Channels; -using MediaBrowser.Controller.Chapters; -using MediaBrowser.Controller.Collections; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Connect; -using MediaBrowser.Controller.Devices; -using MediaBrowser.Controller.Dlna; -using MediaBrowser.Controller.Drawing; -using MediaBrowser.Controller.Dto; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.LiveTv; -using MediaBrowser.Controller.MediaEncoding; -using MediaBrowser.Controller.Net; -using MediaBrowser.Controller.Notifications; -using MediaBrowser.Controller.Persistence; -using MediaBrowser.Controller.Playlists; -using MediaBrowser.Controller.Plugins; -using MediaBrowser.Controller.Providers; -using MediaBrowser.Controller.Resolvers; -using MediaBrowser.Controller.Security; -using MediaBrowser.Controller.Session; -using MediaBrowser.Controller.Sorting; -using MediaBrowser.Controller.Subtitles; -using MediaBrowser.Controller.Sync; -using MediaBrowser.Controller.TV; -using MediaBrowser.LocalMetadata.Savers; -using MediaBrowser.MediaEncoding.BdInfo; -using MediaBrowser.MediaEncoding.Encoder; -using MediaBrowser.MediaEncoding.Subtitles; -using MediaBrowser.Model.Logging; -using MediaBrowser.Model.MediaInfo; -using MediaBrowser.Model.System; -using MediaBrowser.Model.Updates; -using MediaBrowser.Providers.Chapters; -using MediaBrowser.Providers.Manager; -using MediaBrowser.Providers.Subtitles; -using MediaBrowser.WebDashboard.Api; -using MediaBrowser.XbmcMetadata.Providers; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Net; -using System.Net.Sockets; -using System.Reflection; -using System.Security.Cryptography.X509Certificates; -using System.Threading; -using System.Threading.Tasks; -using Emby.Common.Implementations; -using Emby.Common.Implementations.Archiving; -using Emby.Common.Implementations.IO; -using Emby.Common.Implementations.Reflection; -using Emby.Common.Implementations.Serialization; -using Emby.Common.Implementations.TextEncoding; -using Emby.Common.Implementations.Xml; -using Emby.Photos; -using MediaBrowser.Model.IO; -using MediaBrowser.Api.Playback; -using MediaBrowser.Common.Plugins; -using MediaBrowser.Common.Security; -using MediaBrowser.Common.Updates; -using MediaBrowser.Controller.Entities.Audio; -using MediaBrowser.Controller.Entities.Movies; -using MediaBrowser.Controller.Entities.TV; -using Emby.Dlna; -using Emby.Dlna.ConnectionManager; -using Emby.Dlna.ContentDirectory; -using Emby.Dlna.Main; -using Emby.Dlna.MediaReceiverRegistrar; -using Emby.Dlna.Ssdp; -using Emby.Server.Core; -using Emby.Server.Implementations.Activity; -using Emby.Server.Implementations.Devices; -using Emby.Server.Implementations.FFMpeg; -using Emby.Server.Core.IO; -using Emby.Server.Core.Localization; -using Emby.Server.Implementations.Migrations; -using Emby.Server.Implementations.Security; -using Emby.Server.Implementations.Social; -using Emby.Server.Implementations.Channels; -using Emby.Server.Implementations.Collections; -using Emby.Server.Implementations.Dto; -using Emby.Server.Implementations.IO; -using Emby.Server.Implementations.HttpServer; -using Emby.Server.Implementations.HttpServer.Security; -using Emby.Server.Implementations.Library; -using Emby.Server.Implementations.LiveTv; -using Emby.Server.Implementations.Localization; -using Emby.Server.Implementations.MediaEncoder; -using Emby.Server.Implementations.Notifications; -using Emby.Server.Implementations.Data; -using Emby.Server.Implementations.Playlists; -using Emby.Server.Implementations; -using Emby.Server.Implementations.ServerManager; -using Emby.Server.Implementations.Session; -using Emby.Server.Implementations.TV; -using Emby.Server.Implementations.Updates; -using MediaBrowser.Model.Activity; -using MediaBrowser.Model.Configuration; -using MediaBrowser.Model.Dlna; -using MediaBrowser.Model.Globalization; -using MediaBrowser.Model.Net; -using MediaBrowser.Model.News; -using MediaBrowser.Model.Reflection; -using MediaBrowser.Model.Serialization; -using MediaBrowser.Model.Services; -using MediaBrowser.Model.Social; -using MediaBrowser.Model.Text; -using MediaBrowser.Model.Xml; -using OpenSubtitlesHandler; -using ServiceStack; -using SocketHttpListener.Primitives; -using StringExtensions = MediaBrowser.Controller.Extensions.StringExtensions; -using Emby.Drawing; -using Emby.Server.Implementations.Migrations; -using MediaBrowser.Model.Diagnostics; -using Emby.Common.Implementations.Diagnostics; -using Emby.Server.Implementations.Configuration; - -namespace Emby.Server.Core -{ - /// - /// Class CompositionRoot - /// - public abstract class ApplicationHost : BaseApplicationHost, IServerApplicationHost, IDependencyContainer - { - /// - /// Gets the server configuration manager. - /// - /// The server configuration manager. - public IServerConfigurationManager ServerConfigurationManager - { - get { return (IServerConfigurationManager)ConfigurationManager; } - } - - /// - /// Gets the configuration manager. - /// - /// IConfigurationManager. - protected override IConfigurationManager GetConfigurationManager() - { - return new ServerConfigurationManager(ApplicationPaths, LogManager, XmlSerializer, FileSystemManager); - } - - /// - /// Gets or sets the server manager. - /// - /// The server manager. - private IServerManager ServerManager { get; set; } - /// - /// Gets or sets the user manager. - /// - /// The user manager. - public IUserManager UserManager { get; set; } - /// - /// Gets or sets the library manager. - /// - /// The library manager. - internal ILibraryManager LibraryManager { get; set; } - /// - /// Gets or sets the directory watchers. - /// - /// The directory watchers. - private ILibraryMonitor LibraryMonitor { get; set; } - /// - /// Gets or sets the provider manager. - /// - /// The provider manager. - private IProviderManager ProviderManager { get; set; } - /// - /// Gets or sets the HTTP server. - /// - /// The HTTP server. - private IHttpServer HttpServer { get; set; } - private IDtoService DtoService { get; set; } - public IImageProcessor ImageProcessor { get; set; } - - /// - /// Gets or sets the media encoder. - /// - /// The media encoder. - private IMediaEncoder MediaEncoder { get; set; } - private ISubtitleEncoder SubtitleEncoder { get; set; } - - private IConnectManager ConnectManager { get; set; } - private ISessionManager SessionManager { get; set; } - - private ILiveTvManager LiveTvManager { get; set; } - - public ILocalizationManager LocalizationManager { get; set; } - - private IEncodingManager EncodingManager { get; set; } - private IChannelManager ChannelManager { get; set; } - private ISyncManager SyncManager { get; set; } - - /// - /// Gets or sets the user data repository. - /// - /// The user data repository. - private IUserDataManager UserDataManager { get; set; } - private IUserRepository UserRepository { get; set; } - internal IDisplayPreferencesRepository DisplayPreferencesRepository { get; set; } - internal IItemRepository ItemRepository { get; set; } - private INotificationsRepository NotificationsRepository { get; set; } - - private INotificationManager NotificationManager { get; set; } - private ISubtitleManager SubtitleManager { get; set; } - private IChapterManager ChapterManager { get; set; } - private IDeviceManager DeviceManager { get; set; } - - internal IUserViewManager UserViewManager { get; set; } - - private IAuthenticationRepository AuthenticationRepository { get; set; } - private ISyncRepository SyncRepository { get; set; } - private ITVSeriesManager TVSeriesManager { get; set; } - private ICollectionManager CollectionManager { get; set; } - private IMediaSourceManager MediaSourceManager { get; set; } - private IPlaylistManager PlaylistManager { get; set; } - - /// - /// Gets or sets the installation manager. - /// - /// The installation manager. - protected IInstallationManager InstallationManager { get; private set; } - /// - /// Gets the security manager. - /// - /// The security manager. - protected ISecurityManager SecurityManager { get; private set; } - - /// - /// Gets or sets the zip client. - /// - /// The zip client. - protected IZipClient ZipClient { get; private set; } - - protected IAuthService AuthService { get; private set; } - - protected readonly StartupOptions StartupOptions; - private readonly string _releaseAssetFilename; - - internal IPowerManagement PowerManagement { get; private set; } - internal IImageEncoder ImageEncoder { get; private set; } - - private readonly Action _certificateGenerator; - private readonly Func _defaultUserNameFactory; - - /// - /// Initializes a new instance of the class. - /// - public ApplicationHost(ServerApplicationPaths applicationPaths, - ILogManager logManager, - StartupOptions options, - IFileSystem fileSystem, - IPowerManagement powerManagement, - string releaseAssetFilename, - IEnvironmentInfo environmentInfo, - IImageEncoder imageEncoder, - ISystemEvents systemEvents, - IMemoryStreamFactory memoryStreamFactory, - INetworkManager networkManager, - Action certificateGenerator, - Func defaultUsernameFactory) - : base(applicationPaths, - logManager, - fileSystem, - environmentInfo, - systemEvents, - memoryStreamFactory, - networkManager) - { - StartupOptions = options; - _certificateGenerator = certificateGenerator; - _releaseAssetFilename = releaseAssetFilename; - _defaultUserNameFactory = defaultUsernameFactory; - PowerManagement = powerManagement; - - ImageEncoder = imageEncoder; - - SetBaseExceptionMessage(); - - if (environmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows) - { - fileSystem.AddShortcutHandler(new LnkShortcutHandler()); - } - - fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem)); - } - - private Version _version; - /// - /// Gets the current application version - /// - /// The application version. - public override Version ApplicationVersion - { - get - { - return _version ?? (_version = GetAssembly(GetType()).GetName().Version); - } - } - - public virtual bool SupportsRunningAsService - { - get - { - return false; - } - } - - /// - /// Gets the name. - /// - /// The name. - public override string Name - { - get - { - return "Emby Server"; - } - } - - public virtual bool IsRunningAsService - { - get - { - return false; - } - } - - private Assembly GetAssembly(Type type) - { - return type.GetTypeInfo().Assembly; - } - - public virtual bool SupportsAutoRunAtStartup - { - get - { - return EnvironmentInfo.OperatingSystem == MediaBrowser.Model.System.OperatingSystem.Windows; - } - } - - private void SetBaseExceptionMessage() - { - var builder = GetBaseExceptionMessage(ApplicationPaths); - - // Skip if plugins haven't been loaded yet - //if (Plugins != null) - //{ - // var pluginString = string.Join("|", Plugins.Select(i => i.Name + "-" + i.Version.ToString()).ToArray()); - // builder.Insert(0, string.Format("Plugins: {0}{1}", pluginString, Environment.NewLine)); - //} - - builder.Insert(0, string.Format("Version: {0}{1}", ApplicationVersion, Environment.NewLine)); - builder.Insert(0, "*** Error Report ***" + Environment.NewLine); - - LogManager.ExceptionMessagePrefix = builder.ToString(); - } - - /// - /// Runs the startup tasks. - /// - public override async Task RunStartupTasks() - { - await PerformPreInitMigrations().ConfigureAwait(false); - - await base.RunStartupTasks().ConfigureAwait(false); - - await MediaEncoder.Init().ConfigureAwait(false); - - if (string.IsNullOrWhiteSpace(MediaEncoder.EncoderPath)) - { - if (ServerConfigurationManager.Configuration.IsStartupWizardCompleted) - { - ServerConfigurationManager.Configuration.IsStartupWizardCompleted = false; - ServerConfigurationManager.SaveConfiguration(); - } - } - - Logger.Info("ServerId: {0}", SystemId); - Logger.Info("Core startup complete"); - HttpServer.GlobalResponse = null; - - PerformPostInitMigrations(); - Logger.Info("Post-init migrations complete"); - - foreach (var entryPoint in GetExports().ToList()) - { - var name = entryPoint.GetType().FullName; - Logger.Info("Starting entry point {0}", name); - var now = DateTime.UtcNow; - try - { - entryPoint.Run(); - } - catch (Exception ex) - { - Logger.ErrorException("Error in {0}", ex, name); - } - Logger.Info("Entry point completed: {0}. Duration: {1} seconds", name, (DateTime.UtcNow - now).TotalSeconds.ToString(CultureInfo.InvariantCulture), "ImageInfos"); - } - Logger.Info("All entry points have started"); - - LogManager.RemoveConsoleOutput(); - } - - protected override IJsonSerializer CreateJsonSerializer() - { - try - { - // https://github.com/ServiceStack/ServiceStack/blob/master/tests/ServiceStack.WebHost.IntegrationTests/Web.config#L4 - Licensing.RegisterLicense("1001-e1JlZjoxMDAxLE5hbWU6VGVzdCBCdXNpbmVzcyxUeXBlOkJ1c2luZXNzLEhhc2g6UHVNTVRPclhvT2ZIbjQ5MG5LZE1mUTd5RUMzQnBucTFEbTE3TDczVEF4QUNMT1FhNXJMOWkzVjFGL2ZkVTE3Q2pDNENqTkQyUktRWmhvUVBhYTBiekJGUUZ3ZE5aZHFDYm9hL3lydGlwUHI5K1JsaTBYbzNsUC85cjVJNHE5QVhldDN6QkE4aTlvdldrdTgyTk1relY2eis2dFFqTThYN2lmc0JveHgycFdjPSxFeHBpcnk6MjAxMy0wMS0wMX0="); - } - catch - { - // Failing under mono - } - - var result = new JsonSerializer(FileSystemManager, LogManager.GetLogger("JsonSerializer")); - - ServiceStack.Text.JsConfig.ExcludePropertyNames = new[] { "ProviderIds" }; - ServiceStack.Text.JsConfig.ExcludePropertyNames = new[] { "ProviderIds" }; - ServiceStack.Text.JsConfig.ExcludePropertyNames = new[] { "ProviderIds" }; - ServiceStack.Text.JsConfig.ExcludePropertyNames = new[] { "ProviderIds" }; - ServiceStack.Text.JsConfig.ExcludePropertyNames = new[] { "ProviderIds" }; - ServiceStack.Text.JsConfig