diff --git a/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs b/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs index 0d3f5dfcdf..c143635bfa 100644 --- a/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs +++ b/MediaBrowser.Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs @@ -39,8 +39,6 @@ namespace MediaBrowser.Api.ScheduledTasks TaskManager = taskManager; } - private bool _lastResponseHadTasksRunning = true; - /// /// Gets the data to send. /// @@ -48,25 +46,7 @@ namespace MediaBrowser.Api.ScheduledTasks /// Task{IEnumerable{TaskInfo}}. protected override Task> GetDataToSend(object state) { - var tasks = TaskManager.ScheduledTasks.ToList(); - - var anyRunning = tasks.Any(i => i.State != TaskState.Idle); - - if (anyRunning) - { - _lastResponseHadTasksRunning = true; - } - else - { - if (!_lastResponseHadTasksRunning) - { - return Task.FromResult>(null); - } - - _lastResponseHadTasksRunning = false; - } - - return Task.FromResult(tasks + return Task.FromResult(TaskManager.ScheduledTasks .OrderBy(i => i.Name) .Select(ScheduledTaskHelpers.GetTaskInfo) .Where(i => !i.IsHidden)); diff --git a/MediaBrowser.Model/Dlna/DeviceProfile.cs b/MediaBrowser.Model/Dlna/DeviceProfile.cs index 9f599f3e33..42ba5840cf 100644 --- a/MediaBrowser.Model/Dlna/DeviceProfile.cs +++ b/MediaBrowser.Model/Dlna/DeviceProfile.cs @@ -220,27 +220,39 @@ namespace MediaBrowser.Model.Dlna { container = (container ?? string.Empty).TrimStart('.'); - return ResponseProfiles.FirstOrDefault(i => + foreach (var i in ResponseProfiles) { if (i.Type != DlnaProfileType.Photo) { - return false; + continue; } List containers = i.GetContainers(); if (containers.Count > 0 && !containers.Contains(container, StringComparer.OrdinalIgnoreCase)) { - return false; + continue; } ConditionProcessor conditionProcessor = new ConditionProcessor(); + + var anyOff = false; foreach (ProfileCondition c in i.Conditions) { - if (!conditionProcessor.IsImageConditionSatisfied(c, width, height)) - return false; + if (!conditionProcessor.IsImageConditionSatisfied(c, width, height)) + { + anyOff = true; + break; + } } - return true; - }); + + if (anyOff) + { + continue; + } + + return i; + } + return null; } public ResponseProfile GetVideoMediaProfile(string container, @@ -260,66 +272,90 @@ namespace MediaBrowser.Model.Dlna { container = (container ?? string.Empty).TrimStart('.'); - return ResponseProfiles.FirstOrDefault(i => + foreach (var i in ResponseProfiles) { if (i.Type != DlnaProfileType.Video) { - return false; + continue; } List containers = i.GetContainers(); if (containers.Count > 0 && !containers.Contains(container, StringComparer.OrdinalIgnoreCase)) { - return false; + continue; } List audioCodecs = i.GetAudioCodecs(); if (audioCodecs.Count > 0 && !audioCodecs.Contains(audioCodec ?? string.Empty, StringComparer.OrdinalIgnoreCase)) { - return false; + continue; } List videoCodecs = i.GetVideoCodecs(); if (videoCodecs.Count > 0 && !videoCodecs.Contains(videoCodec ?? string.Empty, StringComparer.OrdinalIgnoreCase)) { - return false; + continue; } ConditionProcessor conditionProcessor = new ConditionProcessor(); + + var anyOff = false; foreach (ProfileCondition c in i.Conditions) { - if (!conditionProcessor.IsVideoConditionSatisfied(c, audioBitrate, audioChannels, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp)) - return false; + if (!conditionProcessor.IsVideoConditionSatisfied(c, audioBitrate, audioChannels, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp)) + { + anyOff = true; + break; + } } - return true; - }); + + if (anyOff) + { + continue; + } + + return i; + } + return null; } public ResponseProfile GetPhotoMediaProfile(string container, int? width, int? height) { container = (container ?? string.Empty).TrimStart('.'); - return ResponseProfiles.FirstOrDefault(i => + foreach (var i in ResponseProfiles) { if (i.Type != DlnaProfileType.Photo) { - return false; + continue; } List containers = i.GetContainers().ToList(); if (containers.Count > 0 && !containers.Contains(container, StringComparer.OrdinalIgnoreCase)) { - return false; + continue; } ConditionProcessor conditionProcessor = new ConditionProcessor(); + + var anyOff = false; foreach (ProfileCondition c in i.Conditions) { - if (!conditionProcessor.IsImageConditionSatisfied(c, width, height)) - return false; + if (!conditionProcessor.IsImageConditionSatisfied(c, width, height)) + { + anyOff = true; + break; + } } - return true; - }); + + if (anyOff) + { + continue; + } + + return i; + } + return null; } } } diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index d87fbb1096..48356ef924 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -109,15 +109,7 @@ namespace MediaBrowser.Model.Dlna int? maxBitrateSetting = options.MaxBitrate ?? options.Profile.MaxBitrate; - MediaStream audioStream = null; - foreach (MediaStream i in item.MediaStreams) - { - if (i.Type == MediaStreamType.Audio) - { - audioStream = i; - break; - } - } + MediaStream audioStream = item.DefaultAudioStream; // Honor the max bitrate setting if (IsAudioEligibleForDirectPlay(item, maxBitrateSetting)) @@ -191,11 +183,20 @@ namespace MediaBrowser.Model.Dlna playlistItem.AudioCodec = transcodingProfile.AudioCodec; playlistItem.Protocol = transcodingProfile.Protocol; - List audioTranscodingConditions = options.Profile.CodecProfiles - .Where(i => i.Type == CodecType.Audio && i.ContainsCodec(transcodingProfile.AudioCodec)) - .Take(1) - .SelectMany(i => i.Conditions) - .ToList(); + List audioCodecProfiles = new List(); + foreach (CodecProfile i in options.Profile.CodecProfiles) + { + if (i.Type == CodecType.Audio && i.ContainsCodec(transcodingProfile.AudioCodec)) + { + audioCodecProfiles.Add(i); + } + + if (audioCodecProfiles.Count >= 1) break; + } + + List audioTranscodingConditions = new List(); + foreach (CodecProfile i in audioCodecProfiles) + audioTranscodingConditions.AddRange(i.Conditions); ApplyTranscodingConditions(playlistItem, audioTranscodingConditions); @@ -229,25 +230,8 @@ namespace MediaBrowser.Model.Dlna RunTimeTicks = item.RunTimeTicks }; - MediaStream audioStream = null; - foreach (MediaStream i in item.MediaStreams) - { - if (i.Type == MediaStreamType.Audio) - { - audioStream = i; - break; - } - } - - MediaStream videoStream = null; - foreach (MediaStream i in item.MediaStreams) - { - if (i.Type == MediaStreamType.Video) - { - videoStream = i; - break; - } - } + MediaStream audioStream = item.DefaultAudioStream; + MediaStream videoStream = item.VideoStream; int? maxBitrateSetting = options.MaxBitrate ?? options.Profile.MaxBitrate; @@ -288,18 +272,26 @@ namespace MediaBrowser.Model.Dlna playlistItem.AudioStreamIndex = options.AudioStreamIndex; playlistItem.SubtitleStreamIndex = options.SubtitleStreamIndex; - IEnumerable videoTranscodingConditions = options.Profile.CodecProfiles - .Where(i => i.Type == CodecType.Video && i.ContainsCodec(transcodingProfile.VideoCodec)) - .Take(1) - .SelectMany(i => i.Conditions); - + List videoTranscodingConditions = new List(); + foreach (CodecProfile i in options.Profile.CodecProfiles) + { + if (i.Type == CodecType.Video && i.ContainsCodec(transcodingProfile.VideoCodec)) + { + videoTranscodingConditions.AddRange(i.Conditions); + break; + } + } ApplyTranscodingConditions(playlistItem, videoTranscodingConditions); - IEnumerable audioTranscodingConditions = options.Profile.CodecProfiles - .Where(i => i.Type == CodecType.VideoAudio && i.ContainsCodec(transcodingProfile.AudioCodec)) - .Take(1) - .SelectMany(i => i.Conditions); - + List audioTranscodingConditions = new List(); + foreach (CodecProfile i in options.Profile.CodecProfiles) + { + if (i.Type == CodecType.VideoAudio && i.ContainsCodec(transcodingProfile.AudioCodec)) + { + audioTranscodingConditions.AddRange(i.Conditions); + break; + } + } ApplyTranscodingConditions(playlistItem, audioTranscodingConditions); // Honor requested max channels @@ -453,12 +445,6 @@ namespace MediaBrowser.Model.Dlna return false; } - if (options.AudioStreamIndex.HasValue && - item.MediaStreams.Count(i => i.Type == MediaStreamType.Audio) > 1) - { - return false; - } - return IsAudioEligibleForDirectPlay(item, maxBitrate); } diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs index ba30059504..e4ec0d8539 100644 --- a/MediaBrowser.Model/Dlna/StreamInfo.cs +++ b/MediaBrowser.Model/Dlna/StreamInfo.cs @@ -143,13 +143,7 @@ namespace MediaBrowser.Model.Dlna return null; } - foreach (MediaStream stream in MediaSource.MediaStreams) - { - if (stream.Type == MediaStreamType.Audio) - return stream; - } - - return null; + return MediaSource.DefaultAudioStream; } return null; @@ -165,12 +159,7 @@ namespace MediaBrowser.Model.Dlna { if (MediaSource != null) { - foreach (MediaStream i in MediaSource.MediaStreams) - { - if (i.Type == MediaStreamType.Video && (i.Codec ?? string.Empty).IndexOf("jpeg", StringComparison.OrdinalIgnoreCase) == -1) - return i; - } - return null; + return MediaSource.VideoStream; } return null; diff --git a/MediaBrowser.Model/Dto/MediaSourceInfo.cs b/MediaBrowser.Model/Dto/MediaSourceInfo.cs index 2e94f4f0c8..4fe5863339 100644 --- a/MediaBrowser.Model/Dto/MediaSourceInfo.cs +++ b/MediaBrowser.Model/Dto/MediaSourceInfo.cs @@ -1,4 +1,6 @@ -using MediaBrowser.Model.Entities; +using System; +using System.Runtime.Serialization; +using MediaBrowser.Model.Entities; using MediaBrowser.Model.MediaInfo; using System.Collections.Generic; @@ -14,9 +16,9 @@ namespace MediaBrowser.Model.Dto public long? Size { get; set; } public LocationType LocationType { get; set; } - + public string Name { get; set; } - + public long? RunTimeTicks { get; set; } public VideoType? VideoType { get; set; } @@ -24,19 +26,61 @@ namespace MediaBrowser.Model.Dto public IsoType? IsoType { get; set; } public Video3DFormat? Video3DFormat { get; set; } - + public List MediaStreams { get; set; } public List Formats { get; set; } - + public int? Bitrate { get; set; } public TransportStreamTimestamp? Timestamp { get; set; } - + public MediaSourceInfo() { Formats = new List(); MediaStreams = new List(); } + + [IgnoreDataMember] + public MediaStream DefaultAudioStream + { + get + { + foreach (MediaStream i in MediaStreams) + { + if (i.Type == MediaStreamType.Audio && i.IsDefault) + { + return i; + } + } + + foreach (MediaStream i in MediaStreams) + { + if (i.Type == MediaStreamType.Audio) + { + return i; + } + } + + return null; + } + } + + [IgnoreDataMember] + public MediaStream VideoStream + { + get + { + foreach (MediaStream i in MediaStreams) + { + if (i.Type == MediaStreamType.Video && (i.Codec ?? string.Empty).IndexOf("jpeg", StringComparison.OrdinalIgnoreCase) == -1) + { + return i; + } + } + + return null; + } + } } } diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 8a0d4ca49b..1da0b3db9b 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -1165,7 +1165,7 @@ namespace MediaBrowser.Server.Implementations.Dto }).ThenBy(i => i.Video3DFormat.HasValue ? 1 : 0) .ThenByDescending(i => { - var stream = i.MediaStreams.FirstOrDefault(m => m.Type == MediaStreamType.Video); + var stream = i.VideoStream; return stream == null || stream.Width == null ? 0 : stream.Width.Value; }) diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index 1c58f3e327..9ad5c77c10 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -741,6 +741,6 @@ "LabelSeasonNumber": "Season number", "LabelEpisodeNumber": "Episode number", "LabelEndingEpisodeNumber": "Ending episode number", - "HeaderTypeText": "Type Text", + "HeaderTypeText": "Enter Text", "LabelTypeText": "Text" } \ No newline at end of file