From 5cafb17e8f7502ba463f2c6d36e27d2a28aa108d Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sat, 1 Jul 2017 14:00:43 -0400 Subject: fix stream builder error --- MediaBrowser.Model/Dlna/StreamBuilder.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'MediaBrowser.Model') diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index 342796a10..de6cbf4bb 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -605,6 +605,11 @@ namespace MediaBrowser.Model.Dlna private StreamInfo BuildVideoItem(MediaSourceInfo item, VideoOptions options) { + if (item == null) + { + throw new ArgumentNullException("item"); + } + List transcodeReasons = new List(); StreamInfo playlistItem = new StreamInfo @@ -993,7 +998,12 @@ namespace MediaBrowser.Model.Dlna { LogConditionFailure(profile, "VideoContainerProfile", i, mediaSource); - return null; + var transcodeReason = GetTranscodeReasonForFailedCondition(i); + var transcodeReasons = transcodeReason.HasValue + ? new List { transcodeReason.Value } + : new List { }; + + return new Tuple>(null, transcodeReasons); } } -- cgit v1.2.3 From 15947c2a4cd1588b30d6932eea5be0f41951af5b Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 2 Jul 2017 14:58:56 -0400 Subject: update opening of live streams --- .../Channels/ChannelDynamicMediaSourceProvider.cs | 2 +- Emby.Server.Implementations/Data/CleanDatabaseScheduledTask.cs | 4 ++-- Emby.Server.Implementations/Library/MediaSourceManager.cs | 2 +- Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs | 4 ++-- MediaBrowser.Api/Playback/MediaInfoService.cs | 8 ++++---- MediaBrowser.Controller/Library/IMediaSourceProvider.cs | 5 +---- MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs | 4 ++-- MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs | 4 ++-- Nuget/MediaBrowser.Common.nuspec | 2 +- Nuget/MediaBrowser.Server.Core.nuspec | 4 ++-- 10 files changed, 18 insertions(+), 21 deletions(-) (limited to 'MediaBrowser.Model') diff --git a/Emby.Server.Implementations/Channels/ChannelDynamicMediaSourceProvider.cs b/Emby.Server.Implementations/Channels/ChannelDynamicMediaSourceProvider.cs index 98011ddd4..7be4101c8 100644 --- a/Emby.Server.Implementations/Channels/ChannelDynamicMediaSourceProvider.cs +++ b/Emby.Server.Implementations/Channels/ChannelDynamicMediaSourceProvider.cs @@ -30,7 +30,7 @@ namespace Emby.Server.Implementations.Channels return Task.FromResult>(new List()); } - public Task> OpenMediaSource(string openToken, CancellationToken cancellationToken) + public Task> OpenMediaSource(string openToken, bool allowLiveStreamProbe, CancellationToken cancellationToken) { throw new NotImplementedException(); } diff --git a/Emby.Server.Implementations/Data/CleanDatabaseScheduledTask.cs b/Emby.Server.Implementations/Data/CleanDatabaseScheduledTask.cs index df8d1ac45..f43e45441 100644 --- a/Emby.Server.Implementations/Data/CleanDatabaseScheduledTask.cs +++ b/Emby.Server.Implementations/Data/CleanDatabaseScheduledTask.cs @@ -17,7 +17,7 @@ using MediaBrowser.Model.Tasks; namespace Emby.Server.Implementations.Data { - public class CleanDatabaseScheduledTask : IScheduledTask + public class CleanDatabaseScheduledTask : ILibraryPostScanTask { private readonly ILibraryManager _libraryManager; private readonly IItemRepository _itemRepo; @@ -49,7 +49,7 @@ namespace Emby.Server.Implementations.Data get { return "Library"; } } - public async Task Execute(CancellationToken cancellationToken, IProgress progress) + public async Task Run(IProgress progress, CancellationToken cancellationToken) { // Ensure these objects are lazy loaded. // Without this there is a deadlock that will need to be investigated diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs index 4857008f3..e4bc2962b 100644 --- a/Emby.Server.Implementations/Library/MediaSourceManager.cs +++ b/Emby.Server.Implementations/Library/MediaSourceManager.cs @@ -371,7 +371,7 @@ namespace Emby.Server.Implementations.Library var tuple = GetProvider(request.OpenToken); var provider = tuple.Item1; - var mediaSourceTuple = await provider.OpenMediaSource(tuple.Item2, cancellationToken).ConfigureAwait(false); + var mediaSourceTuple = await provider.OpenMediaSource(tuple.Item2, request.AllowMediaProbe, cancellationToken).ConfigureAwait(false); var mediaSource = mediaSourceTuple.Item1; diff --git a/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs b/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs index 0329ea606..919c0f10d 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs @@ -118,7 +118,7 @@ namespace Emby.Server.Implementations.LiveTv return list; } - public async Task> OpenMediaSource(string openToken, CancellationToken cancellationToken) + public async Task> OpenMediaSource(string openToken, bool allowLiveStreamProbe, CancellationToken cancellationToken) { MediaSourceInfo stream = null; const bool isAudio = false; @@ -140,7 +140,7 @@ namespace Emby.Server.Implementations.LiveTv try { - if (!stream.SupportsProbing || stream.MediaStreams.Any(i => i.Index != -1)) + if (!allowLiveStreamProbe || !stream.SupportsProbing || stream.MediaStreams.Any(i => i.Index != -1)) { AddMediaInfo(stream, isAudio, cancellationToken); } diff --git a/MediaBrowser.Api/Playback/MediaInfoService.cs b/MediaBrowser.Api/Playback/MediaInfoService.cs index 6853ddbeb..ae7271844 100644 --- a/MediaBrowser.Api/Playback/MediaInfoService.cs +++ b/MediaBrowser.Api/Playback/MediaInfoService.cs @@ -134,7 +134,7 @@ namespace MediaBrowser.Api.Playback SetDeviceSpecificData(item, result.MediaSource, profile, authInfo, request.MaxStreamingBitrate, request.StartTimeTicks ?? 0, result.MediaSource.Id, request.AudioStreamIndex, - request.SubtitleStreamIndex, request.MaxAudioChannels, request.PlaySessionId, request.UserId, request.EnableDirectPlay, request.ForceDirectPlayRemoteMediaSource, request.EnableDirectStream, true, true, true); + request.SubtitleStreamIndex, request.MaxAudioChannels, request.PlaySessionId, request.UserId, request.EnableDirectPlay, true, request.EnableDirectStream, true, true, true); } else { @@ -176,7 +176,7 @@ namespace MediaBrowser.Api.Playback { var mediaSourceId = request.MediaSourceId; - SetDeviceSpecificData(request.Id, info, profile, authInfo, request.MaxStreamingBitrate ?? profile.MaxStreamingBitrate, request.StartTimeTicks ?? 0, mediaSourceId, request.AudioStreamIndex, request.SubtitleStreamIndex, request.MaxAudioChannels, request.UserId, request.EnableDirectPlay, request.ForceDirectPlayRemoteMediaSource, request.EnableDirectStream, request.EnableTranscoding, request.AllowVideoStreamCopy, request.AllowAudioStreamCopy); + SetDeviceSpecificData(request.Id, info, profile, authInfo, request.MaxStreamingBitrate ?? profile.MaxStreamingBitrate, request.StartTimeTicks ?? 0, mediaSourceId, request.AudioStreamIndex, request.SubtitleStreamIndex, request.MaxAudioChannels, request.UserId, request.EnableDirectPlay, true, request.EnableDirectStream, request.EnableTranscoding, request.AllowVideoStreamCopy, request.AllowAudioStreamCopy); } if (request.AutoOpenLiveStream) @@ -191,7 +191,6 @@ namespace MediaBrowser.Api.Playback DeviceProfile = request.DeviceProfile, EnableDirectPlay = request.EnableDirectPlay, EnableDirectStream = request.EnableDirectStream, - ForceDirectPlayRemoteMediaSource = request.ForceDirectPlayRemoteMediaSource, ItemId = request.Id, MaxAudioChannels = request.MaxAudioChannels, MaxStreamingBitrate = request.MaxStreamingBitrate, @@ -199,7 +198,8 @@ namespace MediaBrowser.Api.Playback StartTimeTicks = request.StartTimeTicks, SubtitleStreamIndex = request.SubtitleStreamIndex, UserId = request.UserId, - OpenToken = mediaSource.OpenToken + OpenToken = mediaSource.OpenToken, + AllowMediaProbe = request.AllowMediaProbe }).ConfigureAwait(false); diff --git a/MediaBrowser.Controller/Library/IMediaSourceProvider.cs b/MediaBrowser.Controller/Library/IMediaSourceProvider.cs index b0881ba7c..4ec9adf4e 100644 --- a/MediaBrowser.Controller/Library/IMediaSourceProvider.cs +++ b/MediaBrowser.Controller/Library/IMediaSourceProvider.cs @@ -20,10 +20,7 @@ namespace MediaBrowser.Controller.Library /// /// Opens the media source. /// - /// The open token. - /// The cancellation token. - /// Task<MediaSourceInfo>. - Task> OpenMediaSource(string openToken, CancellationToken cancellationToken); + Task> OpenMediaSource(string openToken, bool allowLiveStreamProbe, CancellationToken cancellationToken); /// /// Closes the media source. diff --git a/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs b/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs index 025f1bc7a..303340030 100644 --- a/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs +++ b/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs @@ -17,13 +17,13 @@ namespace MediaBrowser.Model.MediaInfo public bool EnableDirectPlay { get; set; } public bool EnableDirectStream { get; set; } - public bool ForceDirectPlayRemoteMediaSource { get; set; } + public bool AllowMediaProbe { get; set; } public LiveStreamRequest() { - ForceDirectPlayRemoteMediaSource = true; EnableDirectPlay = true; EnableDirectStream = true; + AllowMediaProbe = true; } public LiveStreamRequest(AudioOptions options) diff --git a/MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs b/MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs index 1843fb69a..afffe9b14 100644 --- a/MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs +++ b/MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs @@ -27,19 +27,19 @@ namespace MediaBrowser.Model.MediaInfo public bool EnableDirectPlay { get; set; } public bool EnableDirectStream { get; set; } public bool EnableTranscoding { get; set; } - public bool ForceDirectPlayRemoteMediaSource { get; set; } public bool AllowVideoStreamCopy { get; set; } public bool AllowAudioStreamCopy { get; set; } public bool AutoOpenLiveStream { get; set; } + public bool AllowMediaProbe { get; set; } public PlaybackInfoRequest() { - ForceDirectPlayRemoteMediaSource = true; EnableDirectPlay = true; EnableDirectStream = true; EnableTranscoding = true; AllowVideoStreamCopy = true; AllowAudioStreamCopy = true; + AllowMediaProbe = true; } } } diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec index ff58c13ac..cb4d372a5 100644 --- a/Nuget/MediaBrowser.Common.nuspec +++ b/Nuget/MediaBrowser.Common.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common - 3.0.704 + 3.0.705 Emby.Common Emby Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec index a5707a265..76846b98c 100644 --- a/Nuget/MediaBrowser.Server.Core.nuspec +++ b/Nuget/MediaBrowser.Server.Core.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Server.Core - 3.0.704 + 3.0.705 Emby.Server.Core Emby Team ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains core components required to build plugins for Emby Server. Copyright © Emby 2013 - + -- cgit v1.2.3 From 6ea8e7868df95cea54216a5dbf927b3b4069bde5 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 3 Jul 2017 13:16:01 -0400 Subject: add live stream params --- .../Library/MediaSourceManager.cs | 2 +- .../LiveTv/LiveTvManager.cs | 47 ++++++++++++++++------ MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs | 5 +++ MediaBrowser.Api/Playback/MediaInfoService.cs | 2 +- MediaBrowser.Model/Dlna/StreamBuilder.cs | 29 ++++++++++--- MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs | 4 +- .../MediaInfo/PlaybackInfoRequest.cs | 4 +- MediaBrowser.Model/Session/TranscodingInfo.cs | 3 +- .../Music/ArtistMetadataService.cs | 21 +++++----- .../Playlists/PlaylistMetadataService.cs | 32 ++++++++++++++- 10 files changed, 110 insertions(+), 39 deletions(-) (limited to 'MediaBrowser.Model') diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs index e4bc2962b..c1360c887 100644 --- a/Emby.Server.Implementations/Library/MediaSourceManager.cs +++ b/Emby.Server.Implementations/Library/MediaSourceManager.cs @@ -371,7 +371,7 @@ namespace Emby.Server.Implementations.Library var tuple = GetProvider(request.OpenToken); var provider = tuple.Item1; - var mediaSourceTuple = await provider.OpenMediaSource(tuple.Item2, request.AllowMediaProbe, cancellationToken).ConfigureAwait(false); + var mediaSourceTuple = await provider.OpenMediaSource(tuple.Item2, request.EnableMediaProbe, cancellationToken).ConfigureAwait(false); var mediaSource = mediaSourceTuple.Item1; diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs index 24afc03da..bf11b7d3a 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs @@ -1514,7 +1514,7 @@ namespace Emby.Server.Implementations.LiveTv } private DateTime _lastRecordingRefreshTime; - private async Task RefreshRecordings(CancellationToken cancellationToken) + private async Task RefreshRecordings(Guid internalLiveTvFolderId, CancellationToken cancellationToken) { const int cacheMinutes = 2; @@ -1542,10 +1542,8 @@ namespace Emby.Server.Implementations.LiveTv }); var results = await Task.WhenAll(tasks).ConfigureAwait(false); - var folder = await GetInternalLiveTvFolder(cancellationToken).ConfigureAwait(false); - var parentFolderId = folder.Id; - var recordingTasks = results.SelectMany(i => i.ToList()).Select(i => CreateRecordingRecord(i.Item1, i.Item2.Name, parentFolderId, cancellationToken)); + var recordingTasks = results.SelectMany(i => i.ToList()).Select(i => CreateRecordingRecord(i.Item1, i.Item2.Name, internalLiveTvFolderId, cancellationToken)); var idList = await Task.WhenAll(recordingTasks).ConfigureAwait(false); @@ -1559,7 +1557,7 @@ namespace Emby.Server.Implementations.LiveTv } } - private QueryResult GetEmbyRecordings(RecordingQuery query, DtoOptions dtoOptions, User user) + private QueryResult GetEmbyRecordings(RecordingQuery query, DtoOptions dtoOptions, Guid internalLiveTvFolderId, User user) { if (user == null) { @@ -1571,21 +1569,31 @@ namespace Emby.Server.Implementations.LiveTv return new QueryResult(); } - var folders = EmbyTV.EmbyTV.Current.GetRecordingFolders() + var folderIds = EmbyTV.EmbyTV.Current.GetRecordingFolders() .SelectMany(i => i.Locations) .Distinct(StringComparer.OrdinalIgnoreCase) .Select(i => _libraryManager.FindByPath(i, true)) .Where(i => i != null) .Where(i => i.IsVisibleStandalone(user)) + .Select(i => i.Id) .ToList(); - if (folders.Count == 0) + var excludeItemTypes = new List(); + + if (!query.IsInProgress.HasValue) + { + folderIds.Add(internalLiveTvFolderId); + + excludeItemTypes.Add(typeof(LiveTvChannel).Name); + excludeItemTypes.Add(typeof(LiveTvProgram).Name); + } + + if (folderIds.Count == 0) { return new QueryResult(); } var includeItemTypes = new List(); - var excludeItemTypes = new List(); var genres = new List(); if (query.IsMovie.HasValue) @@ -1631,7 +1639,7 @@ namespace Emby.Server.Implementations.LiveTv { MediaTypes = new[] { MediaType.Video }, Recursive = true, - AncestorIds = folders.Select(i => i.Id.ToString("N")).ToArray(), + AncestorIds = folderIds.Select(i => i.ToString("N")).ToArray(), IsFolder = false, IsVirtualItem = false, Limit = query.Limit, @@ -1714,12 +1722,24 @@ namespace Emby.Server.Implementations.LiveTv return new QueryResult(); } - if (_services.Count == 1 && !(query.IsInProgress ?? false) && (!query.IsLibraryItem.HasValue || query.IsLibraryItem.Value)) + var folder = await GetInternalLiveTvFolder(cancellationToken).ConfigureAwait(false); + + if (_services.Count == 1 && (!query.IsInProgress.HasValue || !query.IsInProgress.Value) && (!query.IsLibraryItem.HasValue || query.IsLibraryItem.Value)) { - return GetEmbyRecordings(query, options, user); + if (!query.IsInProgress.HasValue) + { + await RefreshRecordings(folder.Id, cancellationToken).ConfigureAwait(false); + } + + return GetEmbyRecordings(query, options, folder.Id, user); } - await RefreshRecordings(cancellationToken).ConfigureAwait(false); + return await GetInternalRecordingsFromServices(query, user, options, folder.Id, cancellationToken).ConfigureAwait(false); + } + + private async Task> GetInternalRecordingsFromServices(RecordingQuery query, User user, DtoOptions options, Guid internalLiveTvFolderId, CancellationToken cancellationToken) + { + await RefreshRecordings(internalLiveTvFolderId, cancellationToken).ConfigureAwait(false); var internalQuery = new InternalItemsQuery(user) { @@ -2620,7 +2640,8 @@ namespace Emby.Server.Implementations.LiveTv }, new DtoOptions(), cancellationToken).ConfigureAwait(false); - var recordings = recordingResult.Items.OfType().ToList(); + var embyServiceName = EmbyTV.EmbyTV.Current.Name; + var recordings = recordingResult.Items.Where(i => !string.Equals(i.ServiceName, embyServiceName, StringComparison.OrdinalIgnoreCase)).OfType().ToList(); var groups = new List(); diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index c6282bbad..664735dfe 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -848,6 +848,11 @@ namespace MediaBrowser.Api.Playback.Hls { return string.Empty; } + // No known video stream + if (state.VideoStream == null) + { + return string.Empty; + } var codec = EncodingHelper.GetVideoEncoder(state, ApiEntryPoint.Instance.GetEncodingOptions()); diff --git a/MediaBrowser.Api/Playback/MediaInfoService.cs b/MediaBrowser.Api/Playback/MediaInfoService.cs index ae7271844..536236f5f 100644 --- a/MediaBrowser.Api/Playback/MediaInfoService.cs +++ b/MediaBrowser.Api/Playback/MediaInfoService.cs @@ -199,7 +199,7 @@ namespace MediaBrowser.Api.Playback SubtitleStreamIndex = request.SubtitleStreamIndex, UserId = request.UserId, OpenToken = mediaSource.OpenToken, - AllowMediaProbe = request.AllowMediaProbe + EnableMediaProbe = request.EnableMediaProbe }).ConfigureAwait(false); diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index de6cbf4bb..3536b17b2 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -635,8 +635,10 @@ namespace MediaBrowser.Model.Dlna MediaStream videoStream = item.VideoStream; // TODO: This doesn't accout for situation of device being able to handle media bitrate, but wifi connection not fast enough - bool isEligibleForDirectPlay = options.EnableDirectPlay && (options.ForceDirectPlay || IsEligibleForDirectPlay(item, GetBitrateForDirectPlayCheck(item, options, true), subtitleStream, options, PlayMethod.DirectPlay)); - bool isEligibleForDirectStream = options.EnableDirectStream && (options.ForceDirectStream || IsEligibleForDirectPlay(item, options.GetMaxBitrate(false), subtitleStream, options, PlayMethod.DirectStream)); + var directPlayEligibilityResult = IsEligibleForDirectPlay(item, GetBitrateForDirectPlayCheck(item, options, true), subtitleStream, options, PlayMethod.DirectPlay); + var directStreamEligibilityResult = IsEligibleForDirectPlay(item, options.GetMaxBitrate(false), subtitleStream, options, PlayMethod.DirectStream); + bool isEligibleForDirectPlay = options.EnableDirectPlay && (options.ForceDirectPlay || directPlayEligibilityResult.Item1); + bool isEligibleForDirectStream = options.EnableDirectStream && (options.ForceDirectStream || directStreamEligibilityResult.Item1); _logger.Info("Profile: {0}, Path: {1}, isEligibleForDirectPlay: {2}, isEligibleForDirectStream: {3}", options.Profile.Name ?? "Unknown Profile", @@ -669,6 +671,16 @@ namespace MediaBrowser.Model.Dlna transcodeReasons.AddRange(directPlayInfo.Item2); } + if (directPlayEligibilityResult.Item2.HasValue) + { + transcodeReasons.Add(directPlayEligibilityResult.Item2.Value); + } + + if (directStreamEligibilityResult.Item2.HasValue) + { + transcodeReasons.Add(directStreamEligibilityResult.Item2.Value); + } + // Can't direct play, find the transcoding profile TranscodingProfile transcodingProfile = null; foreach (TranscodingProfile i in options.Profile.TranscodingProfiles) @@ -1136,7 +1148,7 @@ namespace MediaBrowser.Model.Dlna mediaSource.Path ?? "Unknown path"); } - private bool IsEligibleForDirectPlay(MediaSourceInfo item, + private Tuple IsEligibleForDirectPlay(MediaSourceInfo item, long? maxBitrate, MediaStream subtitleStream, VideoOptions options, @@ -1149,11 +1161,18 @@ namespace MediaBrowser.Model.Dlna if (subtitleProfile.Method != SubtitleDeliveryMethod.External && subtitleProfile.Method != SubtitleDeliveryMethod.Embed) { _logger.Info("Not eligible for {0} due to unsupported subtitles", playMethod); - return false; + return new Tuple(false, TranscodeReason.SubtitleCodecNotSupported); } } - return IsAudioEligibleForDirectPlay(item, maxBitrate, playMethod); + var result = IsAudioEligibleForDirectPlay(item, maxBitrate, playMethod); + + if (result) + { + return new Tuple(result, null); + } + + return new Tuple(result, TranscodeReason.ContainerBitrateExceedsLimit); } public static SubtitleProfile GetSubtitleProfile(MediaStream subtitleStream, SubtitleProfile[] subtitleProfiles, PlayMethod playMethod, string transcodingSubProtocol, string transcodingContainer) diff --git a/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs b/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs index 303340030..dedbb428d 100644 --- a/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs +++ b/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs @@ -17,13 +17,13 @@ namespace MediaBrowser.Model.MediaInfo public bool EnableDirectPlay { get; set; } public bool EnableDirectStream { get; set; } - public bool AllowMediaProbe { get; set; } + public bool EnableMediaProbe { get; set; } public LiveStreamRequest() { EnableDirectPlay = true; EnableDirectStream = true; - AllowMediaProbe = true; + EnableMediaProbe = true; } public LiveStreamRequest(AudioOptions options) diff --git a/MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs b/MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs index afffe9b14..df39f0556 100644 --- a/MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs +++ b/MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs @@ -30,7 +30,7 @@ namespace MediaBrowser.Model.MediaInfo public bool AllowVideoStreamCopy { get; set; } public bool AllowAudioStreamCopy { get; set; } public bool AutoOpenLiveStream { get; set; } - public bool AllowMediaProbe { get; set; } + public bool EnableMediaProbe { get; set; } public PlaybackInfoRequest() { @@ -39,7 +39,7 @@ namespace MediaBrowser.Model.MediaInfo EnableTranscoding = true; AllowVideoStreamCopy = true; AllowAudioStreamCopy = true; - AllowMediaProbe = true; + EnableMediaProbe = true; } } } diff --git a/MediaBrowser.Model/Session/TranscodingInfo.cs b/MediaBrowser.Model/Session/TranscodingInfo.cs index f1cbacd90..f58e605b2 100644 --- a/MediaBrowser.Model/Session/TranscodingInfo.cs +++ b/MediaBrowser.Model/Session/TranscodingInfo.cs @@ -48,6 +48,7 @@ namespace MediaBrowser.Model.Session VideoFramerateNotSupported = 17, VideoLevelNotSupported = 18, VideoProfileNotSupported = 19, - AudioBitDepthNotSupported = 20 + AudioBitDepthNotSupported = 20, + SubtitleCodecNotSupported = 21 } } \ No newline at end of file diff --git a/MediaBrowser.Providers/Music/ArtistMetadataService.cs b/MediaBrowser.Providers/Music/ArtistMetadataService.cs index d4e580871..98fe766e0 100644 --- a/MediaBrowser.Providers/Music/ArtistMetadataService.cs +++ b/MediaBrowser.Providers/Music/ArtistMetadataService.cs @@ -21,7 +21,7 @@ namespace MediaBrowser.Providers.Music if (isFullRefresh || currentUpdateType > ItemUpdateType.None) { - if (!item.IsLocked) + if (!item.IsLocked && !item.LockedFields.Contains(MetadataFields.Genres)) { var taggedItems = item.IsAccessedByName ? item.GetTaggedItems(new Controller.Entities.InternalItemsQuery() @@ -31,22 +31,19 @@ namespace MediaBrowser.Providers.Music }) : item.GetRecursiveChildren(i => i is IHasArtist && !i.IsFolder).ToList(); - if (!item.LockedFields.Contains(MetadataFields.Genres)) - { - var currentList = item.Genres.ToList(); + var currentList = item.Genres.ToList(); - item.Genres = taggedItems.SelectMany(i => i.Genres) - .DistinctNames() - .ToList(); + item.Genres = taggedItems.SelectMany(i => i.Genres) + .DistinctNames() + .ToList(); - if (currentList.Count != item.Genres.Count || !currentList.OrderBy(i => i).SequenceEqual(item.Genres.OrderBy(i => i), StringComparer.OrdinalIgnoreCase)) - { - updateType = updateType | ItemUpdateType.MetadataEdit; - } + if (currentList.Count != item.Genres.Count || !currentList.OrderBy(i => i).SequenceEqual(item.Genres.OrderBy(i => i), StringComparer.OrdinalIgnoreCase)) + { + updateType = updateType | ItemUpdateType.MetadataEdit; } } } - + return updateType; } diff --git a/MediaBrowser.Providers/Playlists/PlaylistMetadataService.cs b/MediaBrowser.Providers/Playlists/PlaylistMetadataService.cs index 235fd8c8a..c4ea106fb 100644 --- a/MediaBrowser.Providers/Playlists/PlaylistMetadataService.cs +++ b/MediaBrowser.Providers/Playlists/PlaylistMetadataService.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Controller.Configuration; +using System; +using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Playlists; using MediaBrowser.Controller.Providers; @@ -6,7 +7,7 @@ using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; using MediaBrowser.Providers.Manager; using System.Collections.Generic; - +using System.Linq; using MediaBrowser.Controller.IO; using MediaBrowser.Model.IO; @@ -33,6 +34,33 @@ namespace MediaBrowser.Providers.Playlists } } + protected override ItemUpdateType BeforeSave(Playlist item, bool isFullRefresh, ItemUpdateType currentUpdateType) + { + var updateType = base.BeforeSave(item, isFullRefresh, currentUpdateType); + + if (isFullRefresh || currentUpdateType > ItemUpdateType.None) + { + if (!item.IsLocked && !item.LockedFields.Contains(MetadataFields.Genres)) + { + var items = item.GetLinkedChildren() + .ToList(); + + var currentList = item.Genres.ToList(); + + item.Genres = items.SelectMany(i => i.Genres) + .Distinct(StringComparer.OrdinalIgnoreCase) + .ToList(); + + if (currentList.Count != item.Genres.Count || !currentList.OrderBy(i => i).SequenceEqual(item.Genres.OrderBy(i => i), StringComparer.OrdinalIgnoreCase)) + { + updateType = updateType | ItemUpdateType.MetadataEdit; + } + } + } + + return updateType; + } + public PlaylistMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager) { } -- cgit v1.2.3 From 07ab6a19e25b722513cf4731427ca04a08c6cb86 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Mon, 10 Jul 2017 03:37:00 -0400 Subject: 3.2.24.1 --- Emby.Common.Implementations/BaseApplicationHost.cs | 21 ++++++++++++++++----- .../Localization/Ratings/es.txt | 5 +++++ MediaBrowser.Controller/Entities/Video.cs | 16 ++++++++++++++++ MediaBrowser.Model/Sync/SyncJob.cs | 5 ++++- .../TV/TheMovieDb/MovieDbEpisodeProvider.cs | 2 -- SharedVersion.cs | 2 +- 6 files changed, 42 insertions(+), 9 deletions(-) create mode 100644 Emby.Server.Implementations/Localization/Ratings/es.txt (limited to 'MediaBrowser.Model') diff --git a/Emby.Common.Implementations/BaseApplicationHost.cs b/Emby.Common.Implementations/BaseApplicationHost.cs index d16afbce3..847eeca64 100644 --- a/Emby.Common.Implementations/BaseApplicationHost.cs +++ b/Emby.Common.Implementations/BaseApplicationHost.cs @@ -169,14 +169,15 @@ namespace Emby.Common.Implementations { _deviceId = new DeviceId(ApplicationPaths, LogManager.GetLogger("SystemId"), FileSystemManager); } - + return _deviceId.Value; } } public PackageVersionClass SystemUpdateLevel { - get { + get + { #if BETA return PackageVersionClass.Beta; @@ -216,7 +217,7 @@ namespace Emby.Common.Implementations // hack alert, until common can target .net core BaseExtensions.CryptographyProvider = CryptographyProvider; - + XmlSerializer = new MyXmlSerializer(fileSystem, logManager.GetLogger("XmlSerializer")); FailedAssemblies = new List(); @@ -565,7 +566,10 @@ namespace Emby.Common.Implementations try { - return assembly.GetTypes(); + // This null checking really shouldn't be needed but adding it due to some + // unhandled exceptions in mono 5.0 that are a little hard to hunt down + var types = assembly.GetTypes() ?? new Type[] { }; + return types.Where(t => t != null); } catch (ReflectionTypeLoadException ex) { @@ -578,7 +582,14 @@ namespace Emby.Common.Implementations } // If it fails we can still get a list of the Types it was able to resolve - return ex.Types.Where(t => t != null); + var types = ex.Types ?? new Type[] { }; + return types.Where(t => t != null); + } + catch (Exception ex) + { + Logger.ErrorException("Error loading types from assembly", ex); + + return new List(); } } diff --git a/Emby.Server.Implementations/Localization/Ratings/es.txt b/Emby.Server.Implementations/Localization/Ratings/es.txt new file mode 100644 index 000000000..1ba24fb99 --- /dev/null +++ b/Emby.Server.Implementations/Localization/Ratings/es.txt @@ -0,0 +1,5 @@ +ES-A,1 +ES-7,3 +ES-12,6 +ES-16,8 +ES-18,11 \ No newline at end of file diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs index 7978f4761..c5d9b9203 100644 --- a/MediaBrowser.Controller/Entities/Video.cs +++ b/MediaBrowser.Controller/Entities/Video.cs @@ -57,6 +57,22 @@ namespace MediaBrowser.Controller.Entities { get { + var extraType = ExtraType; + if (extraType.HasValue) + { + if (extraType.Value == Model.Entities.ExtraType.Sample) + { + return false; + } + if (extraType.Value == Model.Entities.ExtraType.ThemeVideo) + { + return false; + } + if (extraType.Value == Model.Entities.ExtraType.Trailer) + { + return false; + } + } return true; } } diff --git a/MediaBrowser.Model/Sync/SyncJob.cs b/MediaBrowser.Model/Sync/SyncJob.cs index 6709426b8..f0e262c50 100644 --- a/MediaBrowser.Model/Sync/SyncJob.cs +++ b/MediaBrowser.Model/Sync/SyncJob.cs @@ -59,7 +59,7 @@ namespace MediaBrowser.Model.Sync /// Gets or sets the status. /// /// The status. - public SyncJobStatus Status { get; set; } + public SyncJobStatus Status { get; set; } /// /// Gets or sets the user identifier. /// @@ -105,9 +105,12 @@ namespace MediaBrowser.Model.Sync public string PrimaryImageItemId { get; set; } public string PrimaryImageTag { get; set; } + public bool EnableAutomaticResync { get; set; } + public SyncJob() { RequestedItemIds = new List(); + EnableAutomaticResync = true; } } } diff --git a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbEpisodeProvider.cs b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbEpisodeProvider.cs index 2e549f610..618a4df45 100644 --- a/MediaBrowser.Providers/TV/TheMovieDb/MovieDbEpisodeProvider.cs +++ b/MediaBrowser.Providers/TV/TheMovieDb/MovieDbEpisodeProvider.cs @@ -196,8 +196,6 @@ namespace MediaBrowser.Providers.TV } catch (HttpException ex) { - Logger.Error("No metadata found for {0}", seasonNumber.Value); - if (ex.StatusCode.HasValue && ex.StatusCode.Value == HttpStatusCode.NotFound) { return result; diff --git a/SharedVersion.cs b/SharedVersion.cs index 0e07c788d..42b8a9abb 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,3 +1,3 @@ using System.Reflection; -[assembly: AssemblyVersion("3.2.23.1")] +[assembly: AssemblyVersion("3.2.24.1")] -- cgit v1.2.3 From a0e7cdd2dc364b10d717b805c576c4294144a99a Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 14 Jul 2017 11:57:44 -0400 Subject: support all inclusive direct play profile --- Emby.Dlna/PlayTo/PlaylistItemFactory.cs | 5 +- MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs | 5 - MediaBrowser.Api/Playback/Hls/VideoHlsService.cs | 5 - MediaBrowser.Model/Dlna/DirectPlayProfile.cs | 18 +++- MediaBrowser.Model/Dlna/StreamBuilder.cs | 105 +++++++-------------- SharedVersion.cs | 2 +- 6 files changed, 56 insertions(+), 84 deletions(-) (limited to 'MediaBrowser.Model') diff --git a/Emby.Dlna/PlayTo/PlaylistItemFactory.cs b/Emby.Dlna/PlayTo/PlaylistItemFactory.cs index 3eb2bc1d5..d31dc155e 100644 --- a/Emby.Dlna/PlayTo/PlaylistItemFactory.cs +++ b/Emby.Dlna/PlayTo/PlaylistItemFactory.cs @@ -56,8 +56,9 @@ namespace Emby.Dlna.PlayTo if (profile.Container.Length > 0) { // Check container type - var mediaContainer = Path.GetExtension(mediaPath); - if (!profile.GetContainers().Any(i => string.Equals("." + i.TrimStart('.'), mediaContainer, StringComparison.OrdinalIgnoreCase))) + var mediaContainer = (Path.GetExtension(mediaPath) ?? string.Empty).TrimStart('.'); + + if (!profile.SupportsContainer(mediaContainer)) { return false; } diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index 93ccd3cb2..2fc8fccbe 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -855,11 +855,6 @@ namespace MediaBrowser.Api.Playback.Hls { return string.Empty; } - // No known video stream - if (state.VideoStream == null) - { - return string.Empty; - } var codec = EncodingHelper.GetVideoEncoder(state, ApiEntryPoint.Instance.GetEncodingOptions()); diff --git a/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs b/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs index d11e6f215..227b55b1b 100644 --- a/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs @@ -79,11 +79,6 @@ namespace MediaBrowser.Api.Playback.Hls { return string.Empty; } - // No known video stream - if (state.VideoStream == null) - { - return string.Empty; - } var codec = EncodingHelper.GetVideoEncoder(state, ApiEntryPoint.Instance.GetEncodingOptions()); diff --git a/MediaBrowser.Model/Dlna/DirectPlayProfile.cs b/MediaBrowser.Model/Dlna/DirectPlayProfile.cs index 0b6ecf385..df511b0da 100644 --- a/MediaBrowser.Model/Dlna/DirectPlayProfile.cs +++ b/MediaBrowser.Model/Dlna/DirectPlayProfile.cs @@ -1,6 +1,7 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using System.Linq; using System.Xml.Serialization; -using MediaBrowser.Model.Dlna; namespace MediaBrowser.Model.Dlna { @@ -28,6 +29,19 @@ namespace MediaBrowser.Model.Dlna return list; } + public bool SupportsContainer(string container) + { + var all = GetContainers(); + + // Only allow unknown container if the profile is all inclusive + if (string.IsNullOrWhiteSpace(container)) + { + return all.Count == 0; + } + + return all.Count == 0 || all.Contains(container, StringComparer.OrdinalIgnoreCase); + } + public List GetAudioCodecs() { List list = new List(); diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index 3536b17b2..48f9a4212 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -492,52 +492,45 @@ namespace MediaBrowser.Model.Dlna foreach (var profile in directPlayProfiles) { - if (profile.Container.Length > 0) + // Check container type + if (profile.SupportsContainer(item.Container)) { - // Check container type - string mediaContainer = item.Container ?? string.Empty; - foreach (string i in profile.GetContainers()) + containerSupported = true; + + if (videoStream != null) { - if (StringHelper.EqualsIgnoreCase(i, mediaContainer)) + // Check video codec + List videoCodecs = profile.GetVideoCodecs(); + if (videoCodecs.Count > 0) { - containerSupported = true; - - if (videoStream != null) + string videoCodec = videoStream.Codec; + if (!string.IsNullOrEmpty(videoCodec) && ListHelper.ContainsIgnoreCase(videoCodecs, videoCodec)) { - // Check video codec - List videoCodecs = profile.GetVideoCodecs(); - if (videoCodecs.Count > 0) - { - string videoCodec = videoStream.Codec; - if (!string.IsNullOrEmpty(videoCodec) && ListHelper.ContainsIgnoreCase(videoCodecs, videoCodec)) - { - videoSupported = true; - } - } - else - { - videoSupported = true; - } + videoSupported = true; } + } + else + { + videoSupported = true; + } + } - if (audioStream != null) + if (audioStream != null) + { + // Check audio codec + List audioCodecs = profile.GetAudioCodecs(); + if (audioCodecs.Count > 0) + { + string audioCodec = audioStream.Codec; + if (!string.IsNullOrEmpty(audioCodec) && ListHelper.ContainsIgnoreCase(audioCodecs, audioCodec)) { - // Check audio codec - List audioCodecs = profile.GetAudioCodecs(); - if (audioCodecs.Count > 0) - { - string audioCodec = audioStream.Codec; - if (!string.IsNullOrEmpty(audioCodec) && ListHelper.ContainsIgnoreCase(audioCodecs, audioCodec)) - { - audioSupported = true; - } - } - else - { - audioSupported = true; - } + audioSupported = true; } } + else + { + audioSupported = true; + } } } } @@ -1538,23 +1531,10 @@ namespace MediaBrowser.Model.Dlna private bool IsAudioDirectPlaySupported(DirectPlayProfile profile, MediaSourceInfo item, MediaStream audioStream) { - if (profile.Container.Length > 0) + // Check container type + if (!profile.SupportsContainer(item.Container)) { - // Check container type - string mediaContainer = item.Container ?? string.Empty; - bool any = false; - foreach (string i in profile.GetContainers()) - { - if (StringHelper.EqualsIgnoreCase(i, mediaContainer)) - { - any = true; - break; - } - } - if (!any) - { - return false; - } + return false; } // Check audio codec @@ -1574,23 +1554,10 @@ namespace MediaBrowser.Model.Dlna private bool IsVideoDirectPlaySupported(DirectPlayProfile profile, MediaSourceInfo item, MediaStream videoStream, MediaStream audioStream) { - if (profile.Container.Length > 0) + // Check container type + if (!profile.SupportsContainer(item.Container)) { - // Check container type - string mediaContainer = item.Container ?? string.Empty; - bool any = false; - foreach (string i in profile.GetContainers()) - { - if (StringHelper.EqualsIgnoreCase(i, mediaContainer)) - { - any = true; - break; - } - } - if (!any) - { - return false; - } + return false; } // Check video codec diff --git a/SharedVersion.cs b/SharedVersion.cs index bbac8d0c8..a12afc2e9 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,3 +1,3 @@ using System.Reflection; -[assembly: AssemblyVersion("3.2.25.3")] +[assembly: AssemblyVersion("3.2.25.4")] -- cgit v1.2.3