Przeglądaj źródła

Merge pull request #2362 from MediaBrowser/beta

Beta
Luke 8 lat temu
rodzic
commit
9782f5665c

+ 91 - 28
Emby.Dlna/ContentDirectory/ControlHandler.cs

@@ -23,6 +23,7 @@ using System.Text;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Xml;
+using MediaBrowser.Controller.Entities.Audio;
 using MediaBrowser.Controller.MediaEncoding;
 using MediaBrowser.Model.Globalization;
 using MediaBrowser.Model.Xml;
@@ -464,6 +465,16 @@ namespace Emby.Dlna.ContentDirectory
 
         private async Task<QueryResult<ServerItem>> GetUserItems(BaseItem item, StubType? stubType, User user, SortCriteria sort, int? startIndex, int? limit)
         {
+            if (item is MusicGenre)
+            {
+                return GetMusicGenreItems(item, null, user, sort, startIndex, limit);
+            }
+
+            if (item is MusicArtist)
+            {
+                return GetMusicArtistItems(item, null, user, sort, startIndex, limit);
+            }
+
             if (stubType.HasValue)
             {
                 if (stubType.Value == StubType.People)
@@ -476,7 +487,7 @@ namespace Emby.Dlna.ContentDirectory
 
                     var result = new QueryResult<ServerItem>
                     {
-                        Items = items.Select(i => new ServerItem { Item = i, StubType = StubType.Folder }).ToArray(),
+                        Items = items.Select(i => new ServerItem(i)).ToArray(),
                         TotalRecordCount = items.Length
                     };
 
@@ -494,41 +505,88 @@ namespace Emby.Dlna.ContentDirectory
 
             var folder = (Folder)item;
 
-            var sortOrders = new List<string>();
-            if (!folder.IsPreSorted)
-            {
-                sortOrders.Add(ItemSortBy.SortName);
-            }
-
-            var queryResult = await folder.GetItems(new InternalItemsQuery
+            var query = new InternalItemsQuery
             {
                 Limit = limit,
                 StartIndex = startIndex,
-                SortBy = sortOrders.ToArray(),
-                SortOrder = sort.SortOrder,
                 User = user,
                 IsMissing = false,
-                PresetViews = new[] { CollectionType.Movies, CollectionType.TvShows, CollectionType.Music },
-                ExcludeItemTypes = new[] { typeof(Game).Name, typeof(Book).Name },
+                PresetViews = new[] {CollectionType.Movies, CollectionType.TvShows, CollectionType.Music},
+                ExcludeItemTypes = new[] {typeof (Game).Name, typeof (Book).Name},
                 IsPlaceHolder = false
+            };
+
+            SetSorting(query, sort, folder.IsPreSorted);
+
+            var queryResult = await folder.GetItems(query).ConfigureAwait(false);
+
+            return ToResult(queryResult);
+        }
+
+        private QueryResult<ServerItem> GetMusicArtistItems(BaseItem item, Guid? parentId, User user, SortCriteria sort, int? startIndex, int? limit)
+        {
+            var query = new InternalItemsQuery(user)
+            {
+                Recursive = true,
+                ParentId = parentId,
+                ArtistIds = new[] { item.Id.ToString("N") },
+                IncludeItemTypes = new[] { typeof(MusicAlbum).Name },
+                Limit = limit,
+                StartIndex = startIndex
+            };
+
+            SetSorting(query, sort, false);
+
+            var result = _libraryManager.GetItemsResult(query);
 
-            }).ConfigureAwait(false);
+            return ToResult(result);
+        }
+
+        private QueryResult<ServerItem> GetMusicGenreItems(BaseItem item, Guid? parentId, User user, SortCriteria sort, int? startIndex, int? limit)
+        {
+            var query = new InternalItemsQuery(user)
+            {
+                Recursive = true,
+                ParentId = parentId,
+                GenreIds = new[] {item.Id.ToString("N")},
+                IncludeItemTypes = new[] {typeof (MusicAlbum).Name},
+                Limit = limit,
+                StartIndex = startIndex
+            };
 
-            var serverItems = queryResult
+            SetSorting(query, sort, false);
+
+            var result = _libraryManager.GetItemsResult(query);
+
+            return ToResult(result);
+        }
+
+        private QueryResult<ServerItem> ToResult(QueryResult<BaseItem> result)
+        {
+            var serverItems = result
                 .Items
-                .Select(i => new ServerItem
-                {
-                    Item = i
-                })
+                .Select(i => new ServerItem(i))
                 .ToArray();
 
             return new QueryResult<ServerItem>
             {
-                TotalRecordCount = queryResult.TotalRecordCount,
+                TotalRecordCount = result.TotalRecordCount,
                 Items = serverItems
             };
         }
 
+        private void SetSorting(InternalItemsQuery query, SortCriteria sort, bool isPreSorted)
+        {
+            var sortOrders = new List<string>();
+            if (!isPreSorted)
+            {
+                sortOrders.Add(ItemSortBy.SortName);
+            }
+
+            query.SortBy = sortOrders.ToArray();
+            query.SortOrder = sort.SortOrder;
+        }
+
         private QueryResult<ServerItem> GetItemsFromPerson(Person person, User user, int? startIndex, int? limit)
         {
             var itemsResult = _libraryManager.GetItemsResult(new InternalItemsQuery(user)
@@ -541,11 +599,7 @@ namespace Emby.Dlna.ContentDirectory
 
             });
 
-            var serverItems = itemsResult.Items.Select(i => new ServerItem
-            {
-                Item = i,
-                StubType = null
-            })
+            var serverItems = itemsResult.Items.Select(i => new ServerItem(i))
             .ToArray();
 
             return new QueryResult<ServerItem>
@@ -566,7 +620,7 @@ namespace Emby.Dlna.ContentDirectory
         {
             return DidlBuilder.IsIdRoot(id)
 
-                 ? new ServerItem { Item = user.RootFolder }
+                 ? new ServerItem(user.RootFolder)
                  : ParseItemId(id, user);
         }
 
@@ -601,16 +655,15 @@ namespace Emby.Dlna.ContentDirectory
             {
                 var item = _libraryManager.GetItemById(itemId);
 
-                return new ServerItem
+                return new ServerItem(item)
                 {
-                    Item = item,
                     StubType = stubType
                 };
             }
 
             Logger.Error("Error parsing item Id: {0}. Returning user root folder.", id);
 
-            return new ServerItem { Item = user.RootFolder };
+            return new ServerItem(user.RootFolder);
         }
     }
 
@@ -618,6 +671,16 @@ namespace Emby.Dlna.ContentDirectory
     {
         public BaseItem Item { get; set; }
         public StubType? StubType { get; set; }
+
+        public ServerItem(BaseItem item)
+        {
+            Item = item;
+
+            if (item is IItemByName && !(item is Folder))
+            {
+                StubType = Dlna.ContentDirectory.StubType.Folder;
+            }
+        }
     }
 
     public enum StubType

+ 6 - 21
Emby.Server.Implementations/Data/SqliteItemRepository.cs

@@ -3855,16 +3855,18 @@ namespace Emby.Server.Implementations.Data
                 }
             }
 
-            if (query.ArtistNames.Length > 0)
+            if (query.ArtistIds.Length > 0)
             {
                 var clauses = new List<string>();
                 var index = 0;
-                foreach (var artist in query.ArtistNames)
+                foreach (var artistId in query.ArtistIds)
                 {
-                    clauses.Add("@ArtistName" + index + " in (select CleanValue from itemvalues where ItemId=Guid and Type <= 1)");
+                    var paramName = "@ArtistIds" + index;
+
+                    clauses.Add("(select CleanName from TypedBaseItems where guid=" + paramName + ") in (select CleanValue from itemvalues where ItemId=Guid and Type<=1)");
                     if (statement != null)
                     {
-                        statement.TryBind("@ArtistName" + index, GetCleanValue(artist));
+                        statement.TryBind(paramName, artistId.ToGuidParamValue());
                     }
                     index++;
                 }
@@ -3963,23 +3965,6 @@ namespace Emby.Server.Implementations.Data
                 whereClauses.Add(clause);
             }
 
-            if (query.Studios.Length > 0)
-            {
-                var clauses = new List<string>();
-                var index = 0;
-                foreach (var item in query.Studios)
-                {
-                    clauses.Add("@Studio" + index + " in (select CleanValue from itemvalues where ItemId=Guid and Type=3)");
-                    if (statement != null)
-                    {
-                        statement.TryBind("@Studio" + index, GetCleanValue(item));
-                    }
-                    index++;
-                }
-                var clause = "(" + string.Join(" OR ", clauses.ToArray()) + ")";
-                whereClauses.Add(clause);
-            }
-
             if (query.Keywords.Length > 0)
             {
                 var clauses = new List<string>();

+ 13 - 10
Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs

@@ -326,7 +326,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
                 {
                     epgData = GetEpgDataForChannel(timer.ChannelId);
                 }
-                await UpdateTimersForSeriesTimer(epgData, timer, true).ConfigureAwait(false);
+                await UpdateTimersForSeriesTimer(epgData, timer, false, true).ConfigureAwait(false);
             }
         }
 
@@ -573,7 +573,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
             }
 
             _seriesTimerProvider.Add(info);
-            await UpdateTimersForSeriesTimer(epgData, info, false).ConfigureAwait(false);
+            await UpdateTimersForSeriesTimer(epgData, info, true, false).ConfigureAwait(false);
 
             return info.Id;
         }
@@ -614,7 +614,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
                     epgData = GetEpgDataForChannel(instance.ChannelId);
                 }
 
-                await UpdateTimersForSeriesTimer(epgData, instance, true).ConfigureAwait(false);
+                await UpdateTimersForSeriesTimer(epgData, instance, true, true).ConfigureAwait(false);
             }
         }
 
@@ -2159,7 +2159,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
             }
         }
 
-        private async Task UpdateTimersForSeriesTimer(List<ProgramInfo> epgData, SeriesTimerInfo seriesTimer, bool deleteInvalidTimers)
+        private async Task UpdateTimersForSeriesTimer(List<ProgramInfo> epgData, SeriesTimerInfo seriesTimer, bool updateTimerSettings, bool deleteInvalidTimers)
         {
             var allTimers = GetTimersForSeries(seriesTimer, epgData)
                 .ToList();
@@ -2204,12 +2204,15 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
                                 enabledTimersForSeries.Add(existingTimer);
                             }
 
-                            existingTimer.KeepUntil = seriesTimer.KeepUntil;
-                            existingTimer.IsPostPaddingRequired = seriesTimer.IsPostPaddingRequired;
-                            existingTimer.IsPrePaddingRequired = seriesTimer.IsPrePaddingRequired;
-                            existingTimer.PostPaddingSeconds = seriesTimer.PostPaddingSeconds;
-                            existingTimer.PrePaddingSeconds = seriesTimer.PrePaddingSeconds;
-                            existingTimer.Priority = seriesTimer.Priority;
+                            if (updateTimerSettings)
+                            {
+                                existingTimer.KeepUntil = seriesTimer.KeepUntil;
+                                existingTimer.IsPostPaddingRequired = seriesTimer.IsPostPaddingRequired;
+                                existingTimer.IsPrePaddingRequired = seriesTimer.IsPrePaddingRequired;
+                                existingTimer.PostPaddingSeconds = seriesTimer.PostPaddingSeconds;
+                                existingTimer.PrePaddingSeconds = seriesTimer.PrePaddingSeconds;
+                                existingTimer.Priority = seriesTimer.Priority;
+                            }
 
                             existingTimer.SeriesTimerId = seriesTimer.Id;
                             _timerProvider.Update(existingTimer);

+ 1 - 1
Emby.Server.Implementations/LiveTv/LiveTvManager.cs

@@ -1681,7 +1681,7 @@ namespace Emby.Server.Implementations.LiveTv
                 return new QueryResult<BaseItem>();
             }
 
-            if (_services.Count == 1 && !(query.IsInProgress ?? false))
+            if (_services.Count == 1 && !(query.IsInProgress ?? false) && (!query.IsLibraryItem.HasValue || query.IsLibraryItem.Value))
             {
                 return GetEmbyRecordings(query, new DtoOptions(), user);
             }

+ 4 - 4
Emby.Server.Implementations/Migrations/LibraryScanMigration.cs

@@ -33,10 +33,10 @@ namespace Emby.Server.Implementations.Migrations
             {
                 Task.Run(() =>
                 {
-                    var task = _taskManager.ScheduledTasks.Select(i => i.ScheduledTask)
-                            .First(i => string.Equals(i.Key, "RefreshLibrary", StringComparison.OrdinalIgnoreCase));
-
-                    _taskManager.QueueScheduledTask(task);
+                    _taskManager.QueueScheduledTask(_taskManager.ScheduledTasks.Select(i => i.ScheduledTask)
+                            .First(i => string.Equals(i.Key, "RefreshLibrary", StringComparison.OrdinalIgnoreCase)));
+                    _taskManager.QueueScheduledTask(_taskManager.ScheduledTasks.Select(i => i.ScheduledTask)
+                            .First(i => string.Equals(i.Key, "RefreshGuide", StringComparison.OrdinalIgnoreCase)));
                 });
 
                 var list = _config.Configuration.Migrations.ToList();

+ 3 - 1
MediaBrowser.Api/LiveTv/LiveTvService.cs

@@ -202,6 +202,7 @@ namespace MediaBrowser.Api.LiveTv
         public bool? IsKids { get; set; }
         public bool? IsSports { get; set; }
         public bool? IsNews { get; set; }
+        public bool? IsLibraryItem { get; set; }
 
         public GetRecordings()
         {
@@ -1057,7 +1058,8 @@ namespace MediaBrowser.Api.LiveTv
                 IsNews = request.IsNews,
                 IsSeries = request.IsSeries,
                 IsKids = request.IsKids,
-                IsSports = request.IsSports
+                IsSports = request.IsSports,
+                IsLibraryItem = request.IsLibraryItem
 
             }, options, CancellationToken.None).ConfigureAwait(false);
 

+ 2 - 2
MediaBrowser.Api/Playback/BaseStreamingService.cs

@@ -818,7 +818,7 @@ namespace MediaBrowser.Api.Playback
 
             if (state.VideoStream != null && state.VideoStream.Width.HasValue && state.VideoStream.Height.HasValue)
             {
-                videoSizeParam = string.Format(",scale={0}:{1}", state.VideoStream.Width.Value.ToString(UsCulture), state.VideoStream.Height.Value.ToString(UsCulture));
+                videoSizeParam = string.Format("scale={0}:{1}", state.VideoStream.Width.Value.ToString(UsCulture), state.VideoStream.Height.Value.ToString(UsCulture));
             }
 
             var mapPrefix = state.SubtitleStream.IsExternal ?
@@ -829,7 +829,7 @@ namespace MediaBrowser.Api.Playback
                 ? 0
                 : state.SubtitleStream.Index;
 
-            return string.Format(" -filter_complex \"[{0}:{1}]format=yuva444p{4},lut=u=128:v=128:y=gammaval(.3)[sub] ; [0:{2}] [sub] overlay{3}\"",
+            return string.Format(" -filter_complex \"[{0}:{1}]{4}[sub] ; [0:{2}] [sub] overlay{3}\"",
                 mapPrefix.ToString(UsCulture),
                 subtitleStreamIndex.ToString(UsCulture),
                 state.VideoStream.Index.ToString(UsCulture),

+ 0 - 16
MediaBrowser.Api/Reports/ReportsService.cs

@@ -209,7 +209,6 @@ namespace MediaBrowser.Api.Reports
                 OfficialRatings = request.GetOfficialRatings(),
                 Genres = request.GetGenres(),
                 GenreIds = request.GetGenreIds(),
-                Studios = request.GetStudios(),
                 StudioIds = request.GetStudioIds(),
                 Person = request.Person,
                 PersonIds = request.GetPersonIds(),
@@ -314,21 +313,6 @@ namespace MediaBrowser.Api.Reports
                 query.MaxParentalRating = _localization.GetRatingLevel(request.MaxOfficialRating);
             }
 
-            // Artists
-            if (!string.IsNullOrEmpty(request.ArtistIds))
-            {
-                var artistIds = request.ArtistIds.Split(new[] { '|', ',' });
-
-                var artistItems = artistIds.Select(_libraryManager.GetItemById).Where(i => i != null).ToList();
-                query.ArtistNames = artistItems.Select(i => i.Name).ToArray();
-            }
-
-            // Artists
-            if (!string.IsNullOrEmpty(request.Artists))
-            {
-                query.ArtistNames = request.Artists.Split('|');
-            }
-
             // Albums
             if (!string.IsNullOrEmpty(request.Albums))
             {

+ 16 - 1
MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs

@@ -124,7 +124,6 @@ namespace MediaBrowser.Api.UserLibrary
                 OfficialRatings = request.GetOfficialRatings(),
                 Genres = request.GetGenres(),
                 GenreIds = request.GetGenreIds(),
-                Studios = request.GetStudios(),
                 StudioIds = request.GetStudioIds(),
                 Person = request.Person,
                 PersonIds = request.GetPersonIds(),
@@ -145,6 +144,22 @@ namespace MediaBrowser.Api.UserLibrary
                 }
             }
 
+            // Studios
+            if (!string.IsNullOrEmpty(request.Studios))
+            {
+                query.StudioIds = request.Studios.Split('|').Select(i =>
+                {
+                    try
+                    {
+                        return LibraryManager.GetStudio(i);
+                    }
+                    catch
+                    {
+                        return null;
+                    }
+                }).Where(i => i != null).Select(i => i.Id.ToString("N")).ToArray();
+            }
+
             foreach (var filter in request.GetFilters())
             {
                 switch (filter)

+ 5 - 0
MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs

@@ -394,6 +394,11 @@ namespace MediaBrowser.Api.UserLibrary
             return (Studios ?? string.Empty).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
         }
 
+        public string[] GetArtistIds()
+        {
+            return (ArtistIds ?? string.Empty).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
+        }
+
         public string[] GetStudioIds()
         {
             return (StudioIds ?? string.Empty).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);

+ 28 - 11
MediaBrowser.Api/UserLibrary/ItemsService.cs

@@ -230,8 +230,8 @@ namespace MediaBrowser.Api.UserLibrary
                 Tags = request.GetTags(),
                 OfficialRatings = request.GetOfficialRatings(),
                 Genres = request.GetGenres(),
+                ArtistIds = request.GetArtistIds(),
                 GenreIds = request.GetGenreIds(),
-                Studios = request.GetStudios(),
                 StudioIds = request.GetStudioIds(),
                 Person = request.Person,
                 PersonIds = request.GetPersonIds(),
@@ -338,19 +338,20 @@ namespace MediaBrowser.Api.UserLibrary
                 query.MaxParentalRating = _localization.GetRatingLevel(request.MaxOfficialRating);
             }
 
-            // Artists
-            if (!string.IsNullOrEmpty(request.ArtistIds))
-            {
-                var artistIds = request.ArtistIds.Split(new[] { '|', ',' });
-
-                var artistItems = artistIds.Select(_libraryManager.GetItemById).Where(i => i != null).ToList();
-                query.ArtistNames = artistItems.Select(i => i.Name).ToArray();
-            }
-
             // Artists
             if (!string.IsNullOrEmpty(request.Artists))
             {
-                query.ArtistNames = request.Artists.Split('|');
+                query.ArtistIds = request.Artists.Split('|').Select(i =>
+                {
+                    try
+                    {
+                        return _libraryManager.GetArtist(i);
+                    }
+                    catch
+                    {
+                        return null;
+                    }
+                }).Where(i => i != null).Select(i => i.Id.ToString("N")).ToArray();
             }
 
             // ExcludeArtistIds
@@ -365,6 +366,22 @@ namespace MediaBrowser.Api.UserLibrary
                 query.AlbumNames = request.Albums.Split('|');
             }
 
+            // Studios
+            if (!string.IsNullOrEmpty(request.Studios))
+            {
+                query.StudioIds = request.Studios.Split('|').Select(i =>
+                {
+                    try
+                    {
+                        return _libraryManager.GetStudio(i);
+                    }
+                    catch
+                    {
+                        return null;
+                    }
+                }).Where(i => i != null).Select(i => i.Id.ToString("N")).ToArray();
+            }
+
             return query;
         }
     }

+ 1 - 1
MediaBrowser.Controller/Entities/Audio/MusicArtist.cs

@@ -69,7 +69,7 @@ namespace MediaBrowser.Controller.Entities.Audio
             if (query.IncludeItemTypes.Length == 0)
             {
                 query.IncludeItemTypes = new[] { typeof(Audio).Name, typeof(MusicVideo).Name, typeof(MusicAlbum).Name };
-                query.ArtistNames = new[] { Name };
+                query.ArtistIds = new[] { Id.ToString("N") };
             }
 
             return LibraryManager.GetItemList(query);

+ 2 - 4
MediaBrowser.Controller/Entities/InternalItemsQuery.cs

@@ -83,7 +83,6 @@ namespace MediaBrowser.Controller.Entities
         public bool? HasTrailer { get; set; }
         public bool? HasParentalRating { get; set; }
 
-        public string[] Studios { get; set; }
         public string[] StudioIds { get; set; }
         public string[] GenreIds { get; set; }
         public ImageType[] ImageTypes { get; set; }
@@ -144,7 +143,7 @@ namespace MediaBrowser.Controller.Entities
         public string ExternalId { get; set; }
 
         public string[] AlbumNames { get; set; }
-        public string[] ArtistNames { get; set; }
+        public string[] ArtistIds { get; set; }
         public string[] ExcludeArtistIds { get; set; }
         public string AncestorWithPresentationUniqueKey { get; set; }
         public string SeriesPresentationUniqueKey { get; set; }
@@ -203,7 +202,7 @@ namespace MediaBrowser.Controller.Entities
 
             DtoOptions = new DtoOptions();
             AlbumNames = new string[] { };
-            ArtistNames = new string[] { };
+            ArtistIds = new string[] { };
             ExcludeArtistIds = new string[] { };
             ExcludeProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
 
@@ -216,7 +215,6 @@ namespace MediaBrowser.Controller.Entities
             IncludeItemTypes = new string[] { };
             ExcludeItemTypes = new string[] { };
             Genres = new string[] { };
-            Studios = new string[] { };
             StudioIds = new string[] { };
             GenreIds = new string[] { };
             ImageTypes = new ImageType[] { };

+ 1 - 1
MediaBrowser.Controller/Entities/Studio.cs

@@ -83,7 +83,7 @@ namespace MediaBrowser.Controller.Entities
 
         public IEnumerable<BaseItem> GetTaggedItems(InternalItemsQuery query)
         {
-            query.Studios = new[] { Name };
+            query.StudioIds = new[] { Id.ToString("N") };
 
             return LibraryManager.GetItemList(query);
         }

+ 15 - 13
MediaBrowser.Controller/Entities/TV/Series.cs

@@ -248,19 +248,25 @@ namespace MediaBrowser.Controller.Entities.TV
         }
 
         public IEnumerable<Season> GetSeasons(User user)
+        {
+            var query = new InternalItemsQuery(user);
+
+            SetSeasonQueryOptions(query, user);
+
+            return LibraryManager.GetItemList(query).Cast<Season>();
+        }
+
+        private void SetSeasonQueryOptions(InternalItemsQuery query, User user)
         {
             var config = user.Configuration;
 
             var enableSeriesPresentationKey = ConfigurationManager.Configuration.EnableSeriesPresentationUniqueKey;
             var seriesKey = GetUniqueSeriesKey(this);
 
-            var query = new InternalItemsQuery(user)
-            {
-                AncestorWithPresentationUniqueKey = enableSeriesPresentationKey ? null : seriesKey,
-                SeriesPresentationUniqueKey = enableSeriesPresentationKey ? seriesKey : null,
-                IncludeItemTypes = new[] { typeof(Season).Name },
-                SortBy = new[] { ItemSortBy.SortName }
-            };
+            query.AncestorWithPresentationUniqueKey = enableSeriesPresentationKey ? null : seriesKey;
+            query.SeriesPresentationUniqueKey = enableSeriesPresentationKey ? seriesKey : null;
+            query.IncludeItemTypes = new[] { typeof(Season).Name };
+            query.SortBy = new[] {ItemSortBy.SortName};
 
             if (!config.DisplayMissingEpisodes && !config.DisplayUnairedEpisodes)
             {
@@ -274,8 +280,6 @@ namespace MediaBrowser.Controller.Entities.TV
             {
                 query.IsVirtualUnaired = false;
             }
-
-            return LibraryManager.GetItemList(query).Cast<Season>();
         }
 
         protected override Task<QueryResult<BaseItem>> GetItemsInternal(InternalItemsQuery query)
@@ -306,11 +310,9 @@ namespace MediaBrowser.Controller.Entities.TV
                 return Task.FromResult(LibraryManager.GetItemsResult(query));
             }
 
-            Func<BaseItem, bool> filter = i => UserViewBuilder.Filter(i, user, query, UserDataManager, LibraryManager);
+            SetSeasonQueryOptions(query, user);
 
-            var items = GetSeasons(user).Where(filter);
-            var result = PostFilterAndSort(items, query, false, true);
-            return Task.FromResult(result);
+            return Task.FromResult(LibraryManager.GetItemsResult(query));
         }
 
         public IEnumerable<Episode> GetEpisodes(User user)

+ 5 - 31
MediaBrowser.Controller/Entities/UserViewBuilder.cs

@@ -203,9 +203,6 @@ namespace MediaBrowser.Controller.Entities
                 case SpecialFolder.MusicGenres:
                     return GetMusicGenres(queryParent, user, query);
 
-                case SpecialFolder.MusicGenre:
-                    return await GetMusicGenreItems(queryParent, displayParent, user, query).ConfigureAwait(false);
-
                 case SpecialFolder.MusicLatest:
                     return GetMusicLatest(queryParent, user, query);
 
@@ -306,18 +303,6 @@ namespace MediaBrowser.Controller.Entities
             };
         }
 
-        private async Task<QueryResult<BaseItem>> GetMusicGenreItems(Folder queryParent, Folder displayParent, User user, InternalItemsQuery query)
-        {
-            query.Recursive = true;
-            query.ParentId = queryParent.Id;
-            query.Genres = new[] { displayParent.Name };
-            query.SetUser(user);
-
-            query.IncludeItemTypes = new[] { typeof(MusicAlbum).Name };
-
-            return _libraryManager.GetItemsResult(query);
-        }
-
         private QueryResult<BaseItem> GetMusicAlbumArtists(Folder parent, User user, InternalItemsQuery query)
         {
             var artists = _libraryManager.GetAlbumArtists(new InternalItemsQuery(user)
@@ -1020,11 +1005,6 @@ namespace MediaBrowser.Controller.Entities
                 return false;
             }
 
-            if (request.Studios.Length > 0)
-            {
-                return false;
-            }
-
             if (request.StudioIds.Length > 0)
             {
                 return false;
@@ -1529,12 +1509,6 @@ namespace MediaBrowser.Controller.Entities
                 return false;
             }
 
-            // Apply studio filter
-            if (query.Studios.Length > 0 && !query.Studios.Any(v => item.Studios.Contains(v, StringComparer.OrdinalIgnoreCase)))
-            {
-                return false;
-            }
-
             // Apply studio filter
             if (query.StudioIds.Length > 0 && !query.StudioIds.Any(id =>
             {
@@ -1748,14 +1722,14 @@ namespace MediaBrowser.Controller.Entities
             }
 
             // Artists
-            if (query.ArtistNames.Length > 0)
+            if (query.ArtistIds.Length > 0)
             {
                 var audio = item as IHasArtist;
 
-                if (!(audio != null && query.ArtistNames.Any(audio.HasAnyArtist)))
-                {
-                    return false;
-                }
+                //if (!(audio != null && query.ArtistNames.Any(audio.HasAnyArtist)))
+                //{
+                //    return false;
+                //}
             }
 
             // Albums

+ 1 - 1
MediaBrowser.Controller/Playlists/Playlist.cs

@@ -153,7 +153,7 @@ namespace MediaBrowser.Controller.Playlists
                     : user.RootFolder.GetRecursiveChildren(user, new InternalItemsQuery(user)
                     {
                         IncludeItemTypes = new[] { typeof(Audio).Name },
-                        ArtistNames = new[] { musicArtist.Name }
+                        ArtistIds = new[] { musicArtist.Id.ToString("N") }
                     });
 
                 return LibraryManager.Sort(items, user, new[] { ItemSortBy.AlbumArtist, ItemSortBy.Album, ItemSortBy.SortName }, SortOrder.Ascending);

+ 11 - 0
MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs

@@ -180,6 +180,17 @@ namespace MediaBrowser.MediaEncoding.Probing
                 {
                     info.Video3DFormat = Video3DFormat.FullSideBySide;
                 }
+
+                var videoStreamsBitrate = info.MediaStreams.Where(i => i.Type == MediaStreamType.Video).Select(i => i.BitRate ?? 0).Sum();
+                // If ffprobe reported the container bitrate as being the same as the video stream bitrate, then it's wrong
+                if (videoStreamsBitrate == (info.Bitrate ?? 0))
+                {
+                    var streamBitrates = info.MediaStreams.Where(i => !i.IsExternal).Select(i => i.BitRate ?? 0).Sum();
+                    if (streamBitrates > (info.Bitrate ?? 0))
+                    {
+                        info.Bitrate = streamBitrates;
+                    }
+                }
             }
 
             return info;

+ 0 - 8
MediaBrowser.Model/Entities/CollectionType.cs

@@ -48,18 +48,10 @@
         public const string MovieGenres = "MovieGenres";
         public const string MovieGenre = "MovieGenre";
 
-        public const string LatestGames = "LatestGames";
-        public const string RecentlyPlayedGames = "RecentlyPlayedGames";
-        public const string GameSystems = "GameSystems";
-        public const string GameGenres = "GameGenres";
-        public const string GameFavorites = "GameFavorites";
-        public const string GameGenre = "GameGenre";
-
         public const string MusicArtists = "MusicArtists";
         public const string MusicAlbumArtists = "MusicAlbumArtists";
         public const string MusicAlbums = "MusicAlbums";
         public const string MusicGenres = "MusicGenres";
-        public const string MusicGenre = "MusicGenre";
         public const string MusicLatest = "MusicLatest";
         public const string MusicPlaylists = "MusicPlaylists";
         public const string MusicSongs = "MusicSongs";

+ 1 - 0
MediaBrowser.Model/LiveTv/RecordingQuery.cs

@@ -68,6 +68,7 @@ namespace MediaBrowser.Model.LiveTv
         /// <value>The fields.</value>
         public ItemFields[] Fields { get; set; }
         public bool? EnableImages { get; set; }
+        public bool? IsLibraryItem { get; set; }
         public bool? IsNews { get; set; }
         public bool? IsMovie { get; set; }
         public bool? IsSeries { get; set; }

+ 1 - 1
Nuget/MediaBrowser.Common.nuspec

@@ -2,7 +2,7 @@
 <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
     <metadata>
         <id>MediaBrowser.Common</id>
-        <version>3.0.691</version>
+        <version>3.0.692</version>
         <title>Emby.Common</title>
         <authors>Emby Team</authors>
         <owners>ebr,Luke,scottisafool</owners>

+ 2 - 2
Nuget/MediaBrowser.Server.Core.nuspec

@@ -2,7 +2,7 @@
 <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
     <metadata>
         <id>MediaBrowser.Server.Core</id>
-        <version>3.0.691</version>
+        <version>3.0.692</version>
         <title>Emby.Server.Core</title>
         <authors>Emby Team</authors>
         <owners>ebr,Luke,scottisafool</owners>
@@ -12,7 +12,7 @@
         <description>Contains core components required to build plugins for Emby Server.</description>
         <copyright>Copyright © Emby 2013</copyright>
         <dependencies>
-            <dependency id="MediaBrowser.Common" version="3.0.691" />
+            <dependency id="MediaBrowser.Common" version="3.0.692" />
         </dependencies>
     </metadata>
     <files>

+ 4 - 0
RSSDP/SsdpCommunicationsServer.cs

@@ -182,6 +182,10 @@ namespace Rssdp.Infrastructure
             try
             {
                 await socket.SendAsync(messageData, messageData.Length, destination).ConfigureAwait(false);
+            }
+            catch (ObjectDisposedException)
+            {
+
             }
             catch (Exception ex)
             {

+ 4 - 1
SocketHttpListener.Portable/Net/EndPointListener.cs

@@ -71,7 +71,10 @@ namespace SocketHttpListener.Net
             }
             catch (SocketCreateException ex)
             {
-                if (_enableDualMode && endpoint.IpAddress.Equals(IpAddressInfo.IPv6Any) && string.Equals(ex.ErrorCode, "AddressFamilyNotSupported", StringComparison.OrdinalIgnoreCase))
+                if (_enableDualMode && endpoint.IpAddress.Equals(IpAddressInfo.IPv6Any) && 
+                    (string.Equals(ex.ErrorCode, "AddressFamilyNotSupported", StringComparison.OrdinalIgnoreCase) || 
+                    // mono on bsd is throwing this
+                    string.Equals(ex.ErrorCode, "ProtocolNotSupported", StringComparison.OrdinalIgnoreCase)))
                 {
                     endpoint = new IpEndPointInfo(IpAddressInfo.Any, endpoint.Port);
                     _enableDualMode = false;