2
0
Luke Pulverenti 9 жил өмнө
parent
commit
023b12a798

+ 1 - 1
MediaBrowser.Api/StartupWizardService.cs

@@ -114,7 +114,7 @@ namespace MediaBrowser.Api
             config.EnableStandaloneMusicKeys = true;
             config.EnableCaseSensitiveItemIds = true;
             config.EnableFolderView = true;
-            config.SchemaVersion = 91;
+            config.SchemaVersion = 92;
         }
 
         public void Post(UpdateStartupConfiguration request)

+ 6 - 4
MediaBrowser.Controller/Entities/Folder.cs

@@ -1413,14 +1413,14 @@ namespace MediaBrowser.Controller.Entities
                 return;
             }
 
-            var playedQueryResult = GetItems(new InternalItemsQuery(user)
+            var unplayedQueryResult = GetItems(new InternalItemsQuery(user)
             {
                 Recursive = true,
                 IsFolder = false,
                 IsVirtualItem = false,
                 EnableTotalRecordCount = true,
                 Limit = 0,
-                IsPlayed = true
+                IsPlayed = false
 
             }).Result;
 
@@ -1435,12 +1435,14 @@ namespace MediaBrowser.Controller.Entities
             }).Result;
 
             double recursiveItemCount = allItemsQueryResult.TotalRecordCount;
-            double playedCount = playedQueryResult.TotalRecordCount;
+            double unplayedCount = unplayedQueryResult.TotalRecordCount;
 
             if (recursiveItemCount > 0)
             {
-                dto.PlayedPercentage = (playedCount / recursiveItemCount) * 100;
+                var unplayedPercentage = (unplayedCount / recursiveItemCount) * 100;
+                dto.PlayedPercentage = 100 - unplayedPercentage;
                 dto.Played = dto.PlayedPercentage.Value >= 100;
+                dto.UnplayedItemCount = unplayedQueryResult.TotalRecordCount;
             }
         }
     }

+ 16 - 7
MediaBrowser.Controller/Entities/TV/Series.cs

@@ -186,16 +186,25 @@ namespace MediaBrowser.Controller.Entities.TV
 
             var user = query.User;
 
-            Func<BaseItem, bool> filter = i => UserViewBuilder.Filter(i, user, query, UserDataManager, LibraryManager);
-
-            IEnumerable<BaseItem> items;
+            if (query.Recursive)
+            {
+                query.AncestorWithPresentationUniqueKey = PresentationUniqueKey;
+                if (query.SortBy.Length == 0)
+                {
+                    query.SortBy = new[] { ItemSortBy.SortName };
+                }
+                if (query.IncludeItemTypes.Length == 0)
+                {
+                    query.IncludeItemTypes = new[] { typeof(Episode).Name, typeof(Season).Name };
+                }
+                query.IsVirtualItem = false;
+                return Task.FromResult(LibraryManager.GetItemsResult(query));
+            }
 
-            items = query.Recursive
-               ? GetSeasons(user).Cast<BaseItem>().Concat(GetEpisodes(user)).Where(filter)
-               : GetSeasons(user).Where(filter);
+            Func<BaseItem, bool> filter = i => UserViewBuilder.Filter(i, user, query, UserDataManager, LibraryManager);
 
+            var items = GetSeasons(user).Where(filter);
             var result = PostFilterAndSort(items, query);
-
             return Task.FromResult(result);
         }
 

+ 25 - 12
MediaBrowser.Server.Implementations/Dto/DtoService.cs

@@ -469,22 +469,31 @@ namespace MediaBrowser.Server.Implementations.Dto
         {
             if (item.IsFolder)
             {
-                var userData = _userDataRepository.GetUserData(user, item);
-
-                // Skip the user data manager because we've already looped through the recursive tree and don't want to do it twice
-                // TODO: Improve in future
-                dto.UserData = GetUserItemDataDto(userData);
-
                 var folder = (Folder)item;
 
-                if (item.SourceType == SourceType.Library)
+                if (fields.Contains(ItemFields.SyncInfo))
                 {
-                    dto.ChildCount = GetChildCount(folder, user);
+                    var userData = _userDataRepository.GetUserData(user, item);
+
+                    // Skip the user data manager because we've already looped through the recursive tree and don't want to do it twice
+                    // TODO: Improve in future
+                    dto.UserData = GetUserItemDataDto(userData);
 
-                    if (folder.SupportsUserDataFromChildren)
+                    if (item.SourceType == SourceType.Library && folder.SupportsUserDataFromChildren)
                     {
                         SetSpecialCounts(folder, user, dto, fields, syncProgress);
                     }
+
+                    dto.UserData.Played = dto.UserData.PlayedPercentage.HasValue && dto.UserData.PlayedPercentage.Value >= 100;
+                }
+                else
+                {
+                    dto.UserData = _userDataRepository.GetUserDataDto(item, user);
+                }
+
+                if (item.SourceType == SourceType.Library)
+                {
+                    dto.ChildCount = GetChildCount(folder, user);
                 }
 
                 if (fields.Contains(ItemFields.CumulativeRunTimeTicks))
@@ -496,8 +505,6 @@ namespace MediaBrowser.Server.Implementations.Dto
                 {
                     dto.DateLastMediaAdded = folder.DateLastMediaAdded;
                 }
-
-                dto.UserData.Played = dto.UserData.PlayedPercentage.HasValue && dto.UserData.PlayedPercentage.Value >= 100;
             }
 
             else
@@ -1586,12 +1593,18 @@ namespace MediaBrowser.Server.Implementations.Dto
         /// <returns>Task.</returns>
         private void SetSpecialCounts(Folder folder, User user, BaseItemDto dto, List<ItemFields> fields, Dictionary<string, SyncedItemProgress> syncProgress)
         {
+            var addSyncInfo = fields.Contains(ItemFields.SyncInfo);
+
+            if (!addSyncInfo)
+            {
+                return;
+            }
+
             var recursiveItemCount = 0;
             var unplayed = 0;
 
             double totalPercentPlayed = 0;
             double totalSyncPercent = 0;
-            var addSyncInfo = fields.Contains(ItemFields.SyncInfo);
 
             var children = folder.GetItems(new InternalItemsQuery
             {

+ 9 - 12
MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs

@@ -44,16 +44,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
 
         public string GetOutputPath(MediaSourceInfo mediaSource, string targetFile)
         {
-            if (_liveTvOptions.EnableOriginalAudioWithEncodedRecordings)
-            {
-                // if the audio is aac_latm, stream copying to mp4 will fail
-                var streams = mediaSource.MediaStreams ?? new List<MediaStream>();
-                if (streams.Any(i => i.Type == MediaStreamType.Audio && (i.Codec ?? string.Empty).IndexOf("aac", StringComparison.OrdinalIgnoreCase) != -1))
-                {
-                    return Path.ChangeExtension(targetFile, ".ts");
-                }
-            }
-
             return Path.ChangeExtension(targetFile, ".mp4");
         }
 
@@ -159,9 +149,16 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
 
         private string GetAudioArgs(MediaSourceInfo mediaSource)
         {
-            var copyAudio = new[] { "aac", "mp3" };
+            // do not copy aac because many players have difficulty with aac_latm
+            var copyAudio = new[] { "mp3" };
             var mediaStreams = mediaSource.MediaStreams ?? new List<MediaStream>();
-            if (_liveTvOptions.EnableOriginalAudioWithEncodedRecordings || mediaStreams.Any(i => i.Type == MediaStreamType.Audio && copyAudio.Contains(i.Codec, StringComparer.OrdinalIgnoreCase)))
+            var inputAudioCodec = mediaStreams.Where(i => i.Type == MediaStreamType.Audio).Select(i => i.Codec).FirstOrDefault() ?? string.Empty;
+
+            if (copyAudio.Contains(inputAudioCodec, StringComparer.OrdinalIgnoreCase))
+            {
+                return "-codec:a:0 copy";
+            }
+            if (_liveTvOptions.EnableOriginalAudioWithEncodedRecordings && !string.Equals(inputAudioCodec, "aac", StringComparison.OrdinalIgnoreCase))
             {
                 return "-codec:a:0 copy";
             }

+ 6 - 2
MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs

@@ -26,6 +26,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
                 throw new ArgumentNullException("dbPath");
             }
 
+            SQLiteConnection.SetMemoryStatus(false);
+
             var connectionstr = new SQLiteConnectionStringBuilder
             {
                 PageSize = 4096,
@@ -41,8 +43,10 @@ namespace MediaBrowser.Server.Implementations.Persistence
 
             var connectionString = connectionstr.ConnectionString;
 
-            //logger.Info("Sqlite {0} opening {1}", SQLiteConnection.SQLiteVersion, connectionString);
-            SQLiteConnection.SetMemoryStatus(false);
+            if (!enablePooling)
+            {
+                logger.Info("Sqlite {0} opening {1}", SQLiteConnection.SQLiteVersion, connectionString);
+            }
 
             var connection = new SQLiteConnection(connectionString);
 

+ 33 - 14
MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs

@@ -94,7 +94,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
         private IDbCommand _updateInheritedRatingCommand;
         private IDbCommand _updateInheritedTagsCommand;
 
-        public const int LatestSchemaVersion = 89;
+        public const int LatestSchemaVersion = 92;
 
         /// <summary>
         /// Initializes a new instance of the <see cref="SqliteItemRepository"/> class.
@@ -122,7 +122,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
 
         protected override async Task<IDbConnection> CreateConnection(bool isReadOnly = false)
         {
-            var connection = await DbConnector.Connect(DbFilePath, false, false, 6000).ConfigureAwait(false);
+            var connection = await DbConnector.Connect(DbFilePath, false, false, 20000).ConfigureAwait(false);
 
             connection.RunQueries(new[]
             {
@@ -1789,7 +1789,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
             var slowThreshold = 1000;
 
 #if DEBUG
-            slowThreshold = 100;
+            slowThreshold = 80;
 #endif
 
             if (elapsed >= slowThreshold)
@@ -1857,13 +1857,22 @@ namespace MediaBrowser.Server.Implementations.Persistence
                     }
                 }
 
+                cmd.CommandText += ";";
+
+                var isReturningZeroItems = query.Limit.HasValue && query.Limit <= 0;
+
+                if (isReturningZeroItems)
+                {
+                    cmd.CommandText = "";
+                }
+
                 if (EnableGroupByPresentationUniqueKey(query))
                 {
-                    cmd.CommandText += "; select count (distinct PresentationUniqueKey)" + GetFromText();
+                    cmd.CommandText += " select count (distinct PresentationUniqueKey)" + GetFromText();
                 }
                 else
                 {
-                    cmd.CommandText += "; select count (guid)" + GetFromText();
+                    cmd.CommandText += " select count (guid)" + GetFromText();
                 }
 
                 cmd.CommandText += GetJoinUserDataText(query);
@@ -1876,18 +1885,28 @@ namespace MediaBrowser.Server.Implementations.Persistence
                 {
                     LogQueryTime("GetItems", cmd, now);
 
-                    while (reader.Read())
+                    if (isReturningZeroItems)
                     {
-                        var item = GetItem(reader);
-                        if (item != null)
+                        if (reader.Read())
                         {
-                            list.Add(item);
+                            count = reader.GetInt32(0);
                         }
                     }
-
-                    if (reader.NextResult() && reader.Read())
+                    else
                     {
-                        count = reader.GetInt32(0);
+                        while (reader.Read())
+                        {
+                            var item = GetItem(reader);
+                            if (item != null)
+                            {
+                                list.Add(item);
+                            }
+                        }
+
+                        if (reader.NextResult() && reader.Read())
+                        {
+                            count = reader.GetInt32(0);
+                        }
                     }
                 }
 
@@ -2388,8 +2407,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
             }
             if (query.ParentIndexNumberNotEquals.HasValue)
             {
-                whereClauses.Add("(ParentIndexNumber<>@ParentIndexNumber or ParentIndexNumber is null)");
-                cmd.Parameters.Add(cmd, "@ParentIndexNumber", DbType.Int32).Value = query.ParentIndexNumberNotEquals.Value;
+                whereClauses.Add("(ParentIndexNumber<>@ParentIndexNumberNotEquals or ParentIndexNumber is null)");
+                cmd.Parameters.Add(cmd, "@ParentIndexNumberNotEquals", DbType.Int32).Value = query.ParentIndexNumberNotEquals.Value;
             }
             if (query.MinEndDate.HasValue)
             {

+ 13 - 0
MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs

@@ -39,6 +39,19 @@ namespace MediaBrowser.Server.Implementations.Persistence
             }
         }
 
+        protected override async Task<IDbConnection> CreateConnection(bool isReadOnly = false)
+        {
+            var connection = await DbConnector.Connect(DbFilePath, false, false, 10000).ConfigureAwait(false);
+
+            connection.RunQueries(new[]
+            {
+                "pragma temp_store = memory"
+
+            }, Logger);
+
+            return connection;
+        }
+
         /// <summary>
         /// Opens the connection to the database
         /// </summary>

+ 20 - 0
MediaBrowser.Server.Startup.Common/Migrations/DbMigration.cs

@@ -18,6 +18,7 @@ namespace MediaBrowser.Server.Startup.Common.Migrations
 
         public void Run()
         {
+            // If a forced migration is required, do that now
             if (_config.Configuration.MigrationVersion < CleanDatabaseScheduledTask.MigrationVersion)
             {
                 if (!_config.Configuration.IsStartupWizardCompleted)
@@ -36,6 +37,25 @@ namespace MediaBrowser.Server.Startup.Common.Migrations
 
                     _taskManager.Execute<CleanDatabaseScheduledTask>();
                 });
+
+                return;
+            }
+            
+            if (_config.Configuration.SchemaVersion < SqliteItemRepository.LatestSchemaVersion)
+            {
+                if (!_config.Configuration.IsStartupWizardCompleted)
+                {
+                    _config.Configuration.SchemaVersion = SqliteItemRepository.LatestSchemaVersion;
+                    _config.SaveConfiguration();
+                    return;
+                }
+
+                Task.Run(async () =>
+                {
+                    await Task.Delay(1000).ConfigureAwait(false);
+
+                    _taskManager.Execute<CleanDatabaseScheduledTask>();
+                });
             }
         }
     }