Explorar o código

add live stream params

Luke Pulverenti %!s(int64=8) %!d(string=hai) anos
pai
achega
6ea8e7868d

+ 1 - 1
Emby.Server.Implementations/Library/MediaSourceManager.cs

@@ -371,7 +371,7 @@ namespace Emby.Server.Implementations.Library
                 var tuple = GetProvider(request.OpenToken);
                 var tuple = GetProvider(request.OpenToken);
                 var provider = tuple.Item1;
                 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;
                 var mediaSource = mediaSourceTuple.Item1;
 
 

+ 34 - 13
Emby.Server.Implementations/LiveTv/LiveTvManager.cs

@@ -1514,7 +1514,7 @@ namespace Emby.Server.Implementations.LiveTv
         }
         }
 
 
         private DateTime _lastRecordingRefreshTime;
         private DateTime _lastRecordingRefreshTime;
-        private async Task RefreshRecordings(CancellationToken cancellationToken)
+        private async Task RefreshRecordings(Guid internalLiveTvFolderId, CancellationToken cancellationToken)
         {
         {
             const int cacheMinutes = 2;
             const int cacheMinutes = 2;
 
 
@@ -1542,10 +1542,8 @@ namespace Emby.Server.Implementations.LiveTv
                 });
                 });
 
 
                 var results = await Task.WhenAll(tasks).ConfigureAwait(false);
                 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);
                 var idList = await Task.WhenAll(recordingTasks).ConfigureAwait(false);
 
 
@@ -1559,7 +1557,7 @@ namespace Emby.Server.Implementations.LiveTv
             }
             }
         }
         }
 
 
-        private QueryResult<BaseItem> GetEmbyRecordings(RecordingQuery query, DtoOptions dtoOptions, User user)
+        private QueryResult<BaseItem> GetEmbyRecordings(RecordingQuery query, DtoOptions dtoOptions, Guid internalLiveTvFolderId, User user)
         {
         {
             if (user == null)
             if (user == null)
             {
             {
@@ -1571,21 +1569,31 @@ namespace Emby.Server.Implementations.LiveTv
                 return new QueryResult<BaseItem>();
                 return new QueryResult<BaseItem>();
             }
             }
 
 
-            var folders = EmbyTV.EmbyTV.Current.GetRecordingFolders()
+            var folderIds = EmbyTV.EmbyTV.Current.GetRecordingFolders()
                 .SelectMany(i => i.Locations)
                 .SelectMany(i => i.Locations)
                 .Distinct(StringComparer.OrdinalIgnoreCase)
                 .Distinct(StringComparer.OrdinalIgnoreCase)
                 .Select(i => _libraryManager.FindByPath(i, true))
                 .Select(i => _libraryManager.FindByPath(i, true))
                 .Where(i => i != null)
                 .Where(i => i != null)
                 .Where(i => i.IsVisibleStandalone(user))
                 .Where(i => i.IsVisibleStandalone(user))
+                .Select(i => i.Id)
                 .ToList();
                 .ToList();
 
 
-            if (folders.Count == 0)
+            var excludeItemTypes = new List<string>();
+
+            if (!query.IsInProgress.HasValue)
+            {
+                folderIds.Add(internalLiveTvFolderId);
+
+                excludeItemTypes.Add(typeof(LiveTvChannel).Name);
+                excludeItemTypes.Add(typeof(LiveTvProgram).Name);
+            }
+
+            if (folderIds.Count == 0)
             {
             {
                 return new QueryResult<BaseItem>();
                 return new QueryResult<BaseItem>();
             }
             }
 
 
             var includeItemTypes = new List<string>();
             var includeItemTypes = new List<string>();
-            var excludeItemTypes = new List<string>();
             var genres = new List<string>();
             var genres = new List<string>();
 
 
             if (query.IsMovie.HasValue)
             if (query.IsMovie.HasValue)
@@ -1631,7 +1639,7 @@ namespace Emby.Server.Implementations.LiveTv
             {
             {
                 MediaTypes = new[] { MediaType.Video },
                 MediaTypes = new[] { MediaType.Video },
                 Recursive = true,
                 Recursive = true,
-                AncestorIds = folders.Select(i => i.Id.ToString("N")).ToArray(),
+                AncestorIds = folderIds.Select(i => i.ToString("N")).ToArray(),
                 IsFolder = false,
                 IsFolder = false,
                 IsVirtualItem = false,
                 IsVirtualItem = false,
                 Limit = query.Limit,
                 Limit = query.Limit,
@@ -1714,12 +1722,24 @@ namespace Emby.Server.Implementations.LiveTv
                 return new QueryResult<BaseItem>();
                 return new QueryResult<BaseItem>();
             }
             }
 
 
-            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<QueryResult<BaseItem>> GetInternalRecordingsFromServices(RecordingQuery query, User user, DtoOptions options, Guid internalLiveTvFolderId, CancellationToken cancellationToken)
+        {
+            await RefreshRecordings(internalLiveTvFolderId, cancellationToken).ConfigureAwait(false);
 
 
             var internalQuery = new InternalItemsQuery(user)
             var internalQuery = new InternalItemsQuery(user)
             {
             {
@@ -2620,7 +2640,8 @@ namespace Emby.Server.Implementations.LiveTv
 
 
             }, new DtoOptions(), cancellationToken).ConfigureAwait(false);
             }, new DtoOptions(), cancellationToken).ConfigureAwait(false);
 
 
-            var recordings = recordingResult.Items.OfType<ILiveTvRecording>().ToList();
+            var embyServiceName = EmbyTV.EmbyTV.Current.Name;
+            var recordings = recordingResult.Items.Where(i => !string.Equals(i.ServiceName, embyServiceName, StringComparison.OrdinalIgnoreCase)).OfType<ILiveTvRecording>().ToList();
 
 
             var groups = new List<BaseItemDto>();
             var groups = new List<BaseItemDto>();
 
 

+ 5 - 0
MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs

@@ -848,6 +848,11 @@ namespace MediaBrowser.Api.Playback.Hls
             {
             {
                 return string.Empty;
                 return string.Empty;
             }
             }
+            // No known video stream
+            if (state.VideoStream == null)
+            {
+                return string.Empty;
+            }
 
 
             var codec = EncodingHelper.GetVideoEncoder(state, ApiEntryPoint.Instance.GetEncodingOptions());
             var codec = EncodingHelper.GetVideoEncoder(state, ApiEntryPoint.Instance.GetEncodingOptions());
 
 

+ 1 - 1
MediaBrowser.Api/Playback/MediaInfoService.cs

@@ -199,7 +199,7 @@ namespace MediaBrowser.Api.Playback
                         SubtitleStreamIndex = request.SubtitleStreamIndex,
                         SubtitleStreamIndex = request.SubtitleStreamIndex,
                         UserId = request.UserId,
                         UserId = request.UserId,
                         OpenToken = mediaSource.OpenToken,
                         OpenToken = mediaSource.OpenToken,
-                        AllowMediaProbe = request.AllowMediaProbe
+                        EnableMediaProbe = request.EnableMediaProbe
 
 
                     }).ConfigureAwait(false);
                     }).ConfigureAwait(false);
 
 

+ 24 - 5
MediaBrowser.Model/Dlna/StreamBuilder.cs

@@ -635,8 +635,10 @@ namespace MediaBrowser.Model.Dlna
             MediaStream videoStream = item.VideoStream;
             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
             // 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}",
             _logger.Info("Profile: {0}, Path: {1}, isEligibleForDirectPlay: {2}, isEligibleForDirectStream: {3}",
                 options.Profile.Name ?? "Unknown Profile",
                 options.Profile.Name ?? "Unknown Profile",
@@ -669,6 +671,16 @@ namespace MediaBrowser.Model.Dlna
                 transcodeReasons.AddRange(directPlayInfo.Item2);
                 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
             // Can't direct play, find the transcoding profile
             TranscodingProfile transcodingProfile = null;
             TranscodingProfile transcodingProfile = null;
             foreach (TranscodingProfile i in options.Profile.TranscodingProfiles)
             foreach (TranscodingProfile i in options.Profile.TranscodingProfiles)
@@ -1136,7 +1148,7 @@ namespace MediaBrowser.Model.Dlna
                 mediaSource.Path ?? "Unknown path");
                 mediaSource.Path ?? "Unknown path");
         }
         }
 
 
-        private bool IsEligibleForDirectPlay(MediaSourceInfo item,
+        private Tuple<bool, TranscodeReason?> IsEligibleForDirectPlay(MediaSourceInfo item,
             long? maxBitrate,
             long? maxBitrate,
             MediaStream subtitleStream,
             MediaStream subtitleStream,
             VideoOptions options,
             VideoOptions options,
@@ -1149,11 +1161,18 @@ namespace MediaBrowser.Model.Dlna
                 if (subtitleProfile.Method != SubtitleDeliveryMethod.External && subtitleProfile.Method != SubtitleDeliveryMethod.Embed)
                 if (subtitleProfile.Method != SubtitleDeliveryMethod.External && subtitleProfile.Method != SubtitleDeliveryMethod.Embed)
                 {
                 {
                     _logger.Info("Not eligible for {0} due to unsupported subtitles", playMethod);
                     _logger.Info("Not eligible for {0} due to unsupported subtitles", playMethod);
-                    return false;
+                    return new Tuple<bool, TranscodeReason?>(false, TranscodeReason.SubtitleCodecNotSupported);
                 }
                 }
             }
             }
 
 
-            return IsAudioEligibleForDirectPlay(item, maxBitrate, playMethod);
+            var result = IsAudioEligibleForDirectPlay(item, maxBitrate, playMethod);
+
+            if (result)
+            {
+                return new Tuple<bool, TranscodeReason?>(result, null);
+            }
+
+            return new Tuple<bool, TranscodeReason?>(result, TranscodeReason.ContainerBitrateExceedsLimit);
         }
         }
 
 
         public static SubtitleProfile GetSubtitleProfile(MediaStream subtitleStream, SubtitleProfile[] subtitleProfiles, PlayMethod playMethod, string transcodingSubProtocol, string transcodingContainer)
         public static SubtitleProfile GetSubtitleProfile(MediaStream subtitleStream, SubtitleProfile[] subtitleProfiles, PlayMethod playMethod, string transcodingSubProtocol, string transcodingContainer)

+ 2 - 2
MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs

@@ -17,13 +17,13 @@ namespace MediaBrowser.Model.MediaInfo
 
 
         public bool EnableDirectPlay { get; set; }
         public bool EnableDirectPlay { get; set; }
         public bool EnableDirectStream { get; set; }
         public bool EnableDirectStream { get; set; }
-        public bool AllowMediaProbe { get; set; }
+        public bool EnableMediaProbe { get; set; }
 
 
         public LiveStreamRequest()
         public LiveStreamRequest()
         {
         {
             EnableDirectPlay = true;
             EnableDirectPlay = true;
             EnableDirectStream = true;
             EnableDirectStream = true;
-            AllowMediaProbe = true;
+            EnableMediaProbe = true;
         }
         }
 
 
         public LiveStreamRequest(AudioOptions options)
         public LiveStreamRequest(AudioOptions options)

+ 2 - 2
MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs

@@ -30,7 +30,7 @@ namespace MediaBrowser.Model.MediaInfo
         public bool AllowVideoStreamCopy { get; set; }
         public bool AllowVideoStreamCopy { get; set; }
         public bool AllowAudioStreamCopy { get; set; }
         public bool AllowAudioStreamCopy { get; set; }
         public bool AutoOpenLiveStream { get; set; }
         public bool AutoOpenLiveStream { get; set; }
-        public bool AllowMediaProbe { get; set; }
+        public bool EnableMediaProbe { get; set; }
 
 
         public PlaybackInfoRequest()
         public PlaybackInfoRequest()
         {
         {
@@ -39,7 +39,7 @@ namespace MediaBrowser.Model.MediaInfo
             EnableTranscoding = true;
             EnableTranscoding = true;
             AllowVideoStreamCopy = true;
             AllowVideoStreamCopy = true;
             AllowAudioStreamCopy = true;
             AllowAudioStreamCopy = true;
-            AllowMediaProbe = true;
+            EnableMediaProbe = true;
         }
         }
     }
     }
 }
 }

+ 2 - 1
MediaBrowser.Model/Session/TranscodingInfo.cs

@@ -48,6 +48,7 @@ namespace MediaBrowser.Model.Session
         VideoFramerateNotSupported = 17,
         VideoFramerateNotSupported = 17,
         VideoLevelNotSupported = 18,
         VideoLevelNotSupported = 18,
         VideoProfileNotSupported = 19,
         VideoProfileNotSupported = 19,
-        AudioBitDepthNotSupported = 20
+        AudioBitDepthNotSupported = 20,
+        SubtitleCodecNotSupported = 21
     }
     }
 }
 }

+ 9 - 12
MediaBrowser.Providers/Music/ArtistMetadataService.cs

@@ -21,7 +21,7 @@ namespace MediaBrowser.Providers.Music
 
 
             if (isFullRefresh || currentUpdateType > ItemUpdateType.None)
             if (isFullRefresh || currentUpdateType > ItemUpdateType.None)
             {
             {
-                if (!item.IsLocked)
+                if (!item.IsLocked && !item.LockedFields.Contains(MetadataFields.Genres))
                 {
                 {
                     var taggedItems = item.IsAccessedByName ?
                     var taggedItems = item.IsAccessedByName ?
                         item.GetTaggedItems(new Controller.Entities.InternalItemsQuery()
                         item.GetTaggedItems(new Controller.Entities.InternalItemsQuery()
@@ -31,22 +31,19 @@ namespace MediaBrowser.Providers.Music
                         }) :
                         }) :
                         item.GetRecursiveChildren(i => i is IHasArtist && !i.IsFolder).ToList();
                         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;
             return updateType;
         }
         }
 
 

+ 30 - 2
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.Library;
 using MediaBrowser.Controller.Playlists;
 using MediaBrowser.Controller.Playlists;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Controller.Providers;
@@ -6,7 +7,7 @@ using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Providers.Manager;
 using MediaBrowser.Providers.Manager;
 using System.Collections.Generic;
 using System.Collections.Generic;
-
+using System.Linq;
 using MediaBrowser.Controller.IO;
 using MediaBrowser.Controller.IO;
 using MediaBrowser.Model.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)
         public PlaylistMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
         {
         {
         }
         }