Explorar el Código

More warning fixes

Bond_009 hace 5 años
padre
commit
e4f893a0eb

+ 19 - 18
Emby.Notifications/Notifications.cs

@@ -209,47 +209,48 @@ namespace Emby.Notifications
         public static string GetItemName(BaseItem item)
         {
             var name = item.Name;
-            var episode = item as Episode;
-            if (episode != null)
+            if (item is Episode episode)
             {
                 if (episode.IndexNumber.HasValue)
                 {
-                    name = string.Format("Ep{0} - {1}", episode.IndexNumber.Value.ToString(CultureInfo.InvariantCulture), name);
+                    name = string.Format(
+                        CultureInfo.InvariantCulture,
+                        "Ep{0} - {1}",
+                        episode.IndexNumber.Value,
+                        name);
                 }
                 if (episode.ParentIndexNumber.HasValue)
                 {
-                    name = string.Format("S{0}, {1}", episode.ParentIndexNumber.Value.ToString(CultureInfo.InvariantCulture), name);
+                    name = string.Format(
+                        CultureInfo.InvariantCulture,
+                        "S{0}, {1}",
+                        episode.ParentIndexNumber.Value,
+                        name);
                 }
             }
 
-            var hasSeries = item as IHasSeries;
 
-            if (hasSeries != null)
+            if (item is IHasSeries hasSeries)
             {
                 name = hasSeries.SeriesName + " - " + name;
             }
 
-            var hasAlbumArtist = item as IHasAlbumArtist;
-            if (hasAlbumArtist != null)
+            if (item is IHasAlbumArtist hasAlbumArtist)
             {
                 var artists = hasAlbumArtist.AlbumArtists;
 
-                if (artists.Length > 0)
+                if (artists.Count > 0)
                 {
                     name = artists[0] + " - " + name;
                 }
             }
-            else
+            else if (item is IHasArtist hasArtist)
             {
-                var hasArtist = item as IHasArtist;
-                if (hasArtist != null)
-                {
-                    var artists = hasArtist.Artists;
+                var artists = hasArtist.Artists;
 
-                    if (artists.Length > 0)
-                    {
-                        name = artists[0] + " - " + name;
-                    }
+                if (artists.Count > 0)
+                {
+                    name = artists[0] + " - " + name;
                 }
             }
 

+ 119 - 30
Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs

@@ -96,7 +96,10 @@ namespace Emby.Server.Implementations.Activity
         {
             CreateLogEntry(new ActivityLogEntry
             {
-                Name = string.Format(_localization.GetLocalizedString("CameraImageUploadedFrom"), e.Argument.Device.Name),
+                Name = string.Format(
+                    CultureInfo.InvariantCulture,
+                    _localization.GetLocalizedString("CameraImageUploadedFrom"),
+                    e.Argument.Device.Name),
                 Type = NotificationType.CameraImageUploaded.ToString()
             });
         }
@@ -105,7 +108,10 @@ namespace Emby.Server.Implementations.Activity
         {
             CreateLogEntry(new ActivityLogEntry
             {
-                Name = string.Format(_localization.GetLocalizedString("UserLockedOutWithName"), e.Argument.Name),
+                Name = string.Format(
+                    CultureInfo.InvariantCulture,
+                    _localization.GetLocalizedString("UserLockedOutWithName"),
+                    e.Argument.Name),
                 Type = NotificationType.UserLockedOut.ToString(),
                 UserId = e.Argument.Id
             });
@@ -115,7 +121,11 @@ namespace Emby.Server.Implementations.Activity
         {
             CreateLogEntry(new ActivityLogEntry
             {
-                Name = string.Format(_localization.GetLocalizedString("SubtitleDownloadFailureFromForItem"), e.Provider, Notifications.Notifications.GetItemName(e.Item)),
+                Name = string.Format(
+                    CultureInfo.InvariantCulture,
+                    _localization.GetLocalizedString("SubtitleDownloadFailureFromForItem"),
+                    e.Provider,
+                    Notifications.Notifications.GetItemName(e.Item)),
                 Type = "SubtitleDownloadFailure",
                 ItemId = e.Item.Id.ToString("N", CultureInfo.InvariantCulture),
                 ShortOverview = e.Exception.Message
@@ -178,7 +188,12 @@ namespace Emby.Server.Implementations.Activity
 
             CreateLogEntry(new ActivityLogEntry
             {
-                Name = string.Format(_localization.GetLocalizedString("UserStartedPlayingItemWithValues"), user.Name, GetItemName(item), e.DeviceName),
+                Name = string.Format(
+                    CultureInfo.InvariantCulture,
+                    _localization.GetLocalizedString("UserStartedPlayingItemWithValues"),
+                    user.Name,
+                    GetItemName(item),
+                    e.DeviceName),
                 Type = GetPlaybackNotificationType(item.MediaType),
                 UserId = user.Id
             });
@@ -193,7 +208,7 @@ namespace Emby.Server.Implementations.Activity
                 name = item.SeriesName + " - " + name;
             }
 
-            if (item.Artists != null && item.Artists.Length > 0)
+            if (item.Artists != null && item.Artists.Count > 0)
             {
                 name = item.Artists[0] + " - " + name;
             }
@@ -238,21 +253,31 @@ namespace Emby.Server.Implementations.Activity
 
             if (string.IsNullOrEmpty(session.UserName))
             {
-                name = string.Format(_localization.GetLocalizedString("DeviceOfflineWithName"), session.DeviceName);
+                name = string.Format(
+                    CultureInfo.InvariantCulture,
+                    _localization.GetLocalizedString("DeviceOfflineWithName"),
+                    session.DeviceName);
 
                 // Causing too much spam for now
                 return;
             }
             else
             {
-                name = string.Format(_localization.GetLocalizedString("UserOfflineFromDevice"), session.UserName, session.DeviceName);
+                name = string.Format(
+                    CultureInfo.InvariantCulture,
+                    _localization.GetLocalizedString("UserOfflineFromDevice"),
+                    session.UserName,
+                    session.DeviceName);
             }
 
             CreateLogEntry(new ActivityLogEntry
             {
                 Name = name,
                 Type = "SessionEnded",
-                ShortOverview = string.Format(_localization.GetLocalizedString("LabelIpAddressValue"), session.RemoteEndPoint),
+                ShortOverview = string.Format(
+                    CultureInfo.InvariantCulture,
+                    _localization.GetLocalizedString("LabelIpAddressValue"),
+                    session.RemoteEndPoint),
                 UserId = session.UserId
             });
         }
@@ -263,9 +288,15 @@ namespace Emby.Server.Implementations.Activity
 
             CreateLogEntry(new ActivityLogEntry
             {
-                Name = string.Format(_localization.GetLocalizedString("AuthenticationSucceededWithUserName"), user.Name),
+                Name = string.Format(
+                    CultureInfo.InvariantCulture,
+                    _localization.GetLocalizedString("AuthenticationSucceededWithUserName"),
+                    user.Name),
                 Type = "AuthenticationSucceeded",
-                ShortOverview = string.Format(_localization.GetLocalizedString("LabelIpAddressValue"), e.Argument.SessionInfo.RemoteEndPoint),
+                ShortOverview = string.Format(
+                    CultureInfo.InvariantCulture,
+                    _localization.GetLocalizedString("LabelIpAddressValue"),
+                    e.Argument.SessionInfo.RemoteEndPoint),
                 UserId = user.Id
             });
         }
@@ -274,9 +305,15 @@ namespace Emby.Server.Implementations.Activity
         {
             CreateLogEntry(new ActivityLogEntry
             {
-                Name = string.Format(_localization.GetLocalizedString("FailedLoginAttemptWithUserName"), e.Argument.Username),
+                Name = string.Format(
+                    CultureInfo.InvariantCulture,
+                    _localization.GetLocalizedString("FailedLoginAttemptWithUserName"),
+                    e.Argument.Username),
                 Type = "AuthenticationFailed",
-                ShortOverview = string.Format(_localization.GetLocalizedString("LabelIpAddressValue"), e.Argument.RemoteEndPoint),
+                ShortOverview = string.Format(
+                    CultureInfo.InvariantCulture,
+                    _localization.GetLocalizedString("LabelIpAddressValue"),
+                    e.Argument.RemoteEndPoint),
                 Severity = LogLevel.Error
             });
         }
@@ -285,7 +322,10 @@ namespace Emby.Server.Implementations.Activity
         {
             CreateLogEntry(new ActivityLogEntry
             {
-                Name = string.Format(_localization.GetLocalizedString("UserPolicyUpdatedWithName"), e.Argument.Name),
+                Name = string.Format(
+                    CultureInfo.InvariantCulture,
+                    _localization.GetLocalizedString("UserPolicyUpdatedWithName"),
+                    e.Argument.Name),
                 Type = "UserPolicyUpdated",
                 UserId = e.Argument.Id
             });
@@ -295,7 +335,10 @@ namespace Emby.Server.Implementations.Activity
         {
             CreateLogEntry(new ActivityLogEntry
             {
-                Name = string.Format(_localization.GetLocalizedString("UserDeletedWithName"), e.Argument.Name),
+                Name = string.Format(
+                    CultureInfo.InvariantCulture,
+                    _localization.GetLocalizedString("UserDeletedWithName"),
+                    e.Argument.Name),
                 Type = "UserDeleted"
             });
         }
@@ -304,7 +347,10 @@ namespace Emby.Server.Implementations.Activity
         {
             CreateLogEntry(new ActivityLogEntry
             {
-                Name = string.Format(_localization.GetLocalizedString("UserPasswordChangedWithName"), e.Argument.Name),
+                Name = string.Format(
+                    CultureInfo.InvariantCulture,
+                    _localization.GetLocalizedString("UserPasswordChangedWithName"),
+                    e.Argument.Name),
                 Type = "UserPasswordChanged",
                 UserId = e.Argument.Id
             });
@@ -314,7 +360,10 @@ namespace Emby.Server.Implementations.Activity
         {
             CreateLogEntry(new ActivityLogEntry
             {
-                Name = string.Format(_localization.GetLocalizedString("UserCreatedWithName"), e.Argument.Name),
+                Name = string.Format(
+                    CultureInfo.InvariantCulture,
+                    _localization.GetLocalizedString("UserCreatedWithName"),
+                    e.Argument.Name),
                 Type = "UserCreated",
                 UserId = e.Argument.Id
             });
@@ -327,21 +376,31 @@ namespace Emby.Server.Implementations.Activity
 
             if (string.IsNullOrEmpty(session.UserName))
             {
-                name = string.Format(_localization.GetLocalizedString("DeviceOnlineWithName"), session.DeviceName);
+                name = string.Format(
+                    CultureInfo.InvariantCulture,
+                    _localization.GetLocalizedString("DeviceOnlineWithName"),
+                    session.DeviceName);
 
                 // Causing too much spam for now
                 return;
             }
             else
             {
-                name = string.Format(_localization.GetLocalizedString("UserOnlineFromDevice"), session.UserName, session.DeviceName);
+                name = string.Format(
+                    CultureInfo.InvariantCulture,
+                    _localization.GetLocalizedString("UserOnlineFromDevice"),
+                    session.UserName,
+                    session.DeviceName);
             }
 
             CreateLogEntry(new ActivityLogEntry
             {
                 Name = name,
                 Type = "SessionStarted",
-                ShortOverview = string.Format(_localization.GetLocalizedString("LabelIpAddressValue"), session.RemoteEndPoint),
+                ShortOverview = string.Format(
+                    CultureInfo.InvariantCulture,
+                    _localization.GetLocalizedString("LabelIpAddressValue"),
+                    session.RemoteEndPoint),
                 UserId = session.UserId
             });
         }
@@ -350,9 +409,15 @@ namespace Emby.Server.Implementations.Activity
         {
             CreateLogEntry(new ActivityLogEntry
             {
-                Name = string.Format(_localization.GetLocalizedString("PluginUpdatedWithName"), e.Argument.Item1.Name),
+                Name = string.Format(
+                    CultureInfo.InvariantCulture,
+                    _localization.GetLocalizedString("PluginUpdatedWithName"),
+                    e.Argument.Item1.Name),
                 Type = NotificationType.PluginUpdateInstalled.ToString(),
-                ShortOverview = string.Format(_localization.GetLocalizedString("VersionNumber"), e.Argument.Item2.versionStr),
+                ShortOverview = string.Format(
+                    CultureInfo.InvariantCulture,
+                    _localization.GetLocalizedString("VersionNumber"),
+                    e.Argument.Item2.versionStr),
                 Overview = e.Argument.Item2.description
             });
         }
@@ -361,7 +426,10 @@ namespace Emby.Server.Implementations.Activity
         {
             CreateLogEntry(new ActivityLogEntry
             {
-                Name = string.Format(_localization.GetLocalizedString("PluginUninstalledWithName"), e.Argument.Name),
+                Name = string.Format(
+                    CultureInfo.InvariantCulture,
+                    _localization.GetLocalizedString("PluginUninstalledWithName"),
+                    e.Argument.Name),
                 Type = NotificationType.PluginUninstalled.ToString()
             });
         }
@@ -370,9 +438,15 @@ namespace Emby.Server.Implementations.Activity
         {
             CreateLogEntry(new ActivityLogEntry
             {
-                Name = string.Format(_localization.GetLocalizedString("PluginInstalledWithName"), e.Argument.name),
+                Name = string.Format(
+                    CultureInfo.InvariantCulture,
+                    _localization.GetLocalizedString("PluginInstalledWithName"),
+                    e.Argument.name),
                 Type = NotificationType.PluginInstalled.ToString(),
-                ShortOverview = string.Format(_localization.GetLocalizedString("VersionNumber"), e.Argument.versionStr)
+                ShortOverview = string.Format(
+                    CultureInfo.InvariantCulture,
+                    _localization.GetLocalizedString("VersionNumber"),
+                    e.Argument.versionStr)
             });
         }
 
@@ -382,9 +456,15 @@ namespace Emby.Server.Implementations.Activity
 
             CreateLogEntry(new ActivityLogEntry
             {
-                Name = string.Format(_localization.GetLocalizedString("NameInstallFailed"), installationInfo.Name),
+                Name = string.Format(
+                    CultureInfo.InvariantCulture,
+                    _localization.GetLocalizedString("NameInstallFailed"),
+                    installationInfo.Name),
                 Type = NotificationType.InstallationFailed.ToString(),
-                ShortOverview = string.Format(_localization.GetLocalizedString("VersionNumber"), installationInfo.Version),
+                ShortOverview = string.Format(
+                    CultureInfo.InvariantCulture,
+                    _localization.GetLocalizedString("VersionNumber"),
+                    installationInfo.Version),
                 Overview = e.Exception.Message
             });
         }
@@ -401,7 +481,10 @@ namespace Emby.Server.Implementations.Activity
             }
 
             var time = result.EndTimeUtc - result.StartTimeUtc;
-            var runningTime = string.Format(_localization.GetLocalizedString("LabelRunningTimeValue"), ToUserFriendlyString(time));
+            var runningTime = string.Format(
+                CultureInfo.InvariantCulture,
+                _localization.GetLocalizedString("LabelRunningTimeValue"),
+                ToUserFriendlyString(time));
 
             if (result.Status == TaskCompletionStatus.Failed)
             {
@@ -419,7 +502,10 @@ namespace Emby.Server.Implementations.Activity
 
                 CreateLogEntry(new ActivityLogEntry
                 {
-                    Name = string.Format(_localization.GetLocalizedString("ScheduledTaskFailedWithName"), task.Name),
+                    Name = string.Format(
+                        CultureInfo.InvariantCulture,
+                        _localization.GetLocalizedString("ScheduledTaskFailedWithName"),
+                        task.Name),
                     Type = NotificationType.TaskFailed.ToString(),
                     Overview = string.Join(Environment.NewLine, vals),
                     ShortOverview = runningTime,
@@ -534,8 +620,11 @@ namespace Emby.Server.Implementations.Activity
         /// <param name="description">The name of this item (singular form)</param>
         private static string CreateValueString(int value, string description)
         {
-            return string.Format("{0:#,##0} {1}",
-                value, value == 1 ? description : string.Format("{0}s", description));
+            return string.Format(
+                CultureInfo.InvariantCulture,
+                "{0:#,##0} {1}",
+                value,
+                value == 1 ? description : string.Format(CultureInfo.InvariantCulture, "{0}s", description));
         }
     }
 }

+ 3 - 3
Emby.Server.Implementations/Data/SqliteItemRepository.cs

@@ -979,7 +979,7 @@ namespace Emby.Server.Implementations.Data
             }
 
             string artists = null;
-            if (item is IHasArtist hasArtists && hasArtists.Artists.Length > 0)
+            if (item is IHasArtist hasArtists && hasArtists.Artists.Count > 0)
             {
                 artists = string.Join("|", hasArtists.Artists);
             }
@@ -987,7 +987,7 @@ namespace Emby.Server.Implementations.Data
 
             string albumArtists = null;
             if (item is IHasAlbumArtist hasAlbumArtists
-                && hasAlbumArtists.AlbumArtists.Length > 0)
+                && hasAlbumArtists.AlbumArtists.Count > 0)
             {
                 albumArtists = string.Join("|", hasAlbumArtists.AlbumArtists);
             }
@@ -5731,7 +5731,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
                 {
                     if (isSubsequentRow)
                     {
-                        insertText.Append(",");
+                        insertText.Append(',');
                     }
 
                     insertText.AppendFormat("(@ItemId, @Name{0}, @Role{0}, @PersonType{0}, @SortOrder{0}, @ListOrder{0})", i.ToString(CultureInfo.InvariantCulture));

+ 1 - 2
Emby.Server.Implementations/Dto/DtoService.cs

@@ -886,8 +886,7 @@ namespace Emby.Server.Implementations.Dto
                 //}
             }
 
-            var hasArtist = item as IHasArtist;
-            if (hasArtist != null)
+            if (item is IHasArtist hasArtist)
             {
                 dto.Artists = hasArtist.Artists;
 

+ 11 - 18
Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs

@@ -87,8 +87,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
                 CreateNoWindow = true,
                 UseShellExecute = false,
 
-                // Must consume both stdout and stderr or deadlocks may occur
-                //RedirectStandardOutput = true,
                 RedirectStandardError = true,
                 RedirectStandardInput = true,
 
@@ -120,9 +118,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
 
             cancellationToken.Register(Stop);
 
-            // MUST read both stdout and stderr asynchronously or a deadlock may occurr
-            //process.BeginOutputReadLine();
-
             onStarted();
 
             // Important - don't await the log task or we won't be able to kill ffmpeg when the user stops playback
@@ -138,11 +133,12 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
             string videoArgs;
             if (EncodeVideo(mediaSource))
             {
-                var maxBitrate = 25000000;
+                const int MaxBitrate = 25000000;
                 videoArgs = string.Format(
-                        "-codec:v:0 libx264 -force_key_frames \"expr:gte(t,n_forced*5)\" {0} -pix_fmt yuv420p -preset superfast -crf 23 -b:v {1} -maxrate {1} -bufsize ({1}*2) -vsync -1 -profile:v high -level 41",
-                        GetOutputSizeParam(),
-                        maxBitrate.ToString(CultureInfo.InvariantCulture));
+                    CultureInfo.InvariantCulture,
+                    "-codec:v:0 libx264 -force_key_frames \"expr:gte(t,n_forced*5)\" {0} -pix_fmt yuv420p -preset superfast -crf 23 -b:v {1} -maxrate {1} -bufsize ({1}*2) -vsync -1 -profile:v high -level 41",
+                    GetOutputSizeParam(),
+                    MaxBitrate);
             }
             else
             {
@@ -151,18 +147,17 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
 
             videoArgs += " -fflags +genpts";
 
-            var durationParam = " -t " + _mediaEncoder.GetTimeParameter(duration.Ticks);
-            durationParam = string.Empty;
-
             var flags = new List<string>();
             if (mediaSource.IgnoreDts)
             {
                 flags.Add("+igndts");
             }
+
             if (mediaSource.IgnoreIndex)
             {
                 flags.Add("+ignidx");
             }
+
             if (mediaSource.GenPtsInput)
             {
                 flags.Add("+genpts");
@@ -172,11 +167,9 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
 
             if (flags.Count > 0)
             {
-                inputModifier += " -fflags " + string.Join("", flags.ToArray());
+                inputModifier += " -fflags " + string.Join(string.Empty, flags);
             }
 
-            var videoStream = mediaSource.VideoStream;
-
             if (mediaSource.ReadAtNativeFramerate)
             {
                 inputModifier += " -re";
@@ -200,13 +193,14 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
 
             var outputParam = string.Empty;
 
-            var commandLineArgs = string.Format("-i \"{0}\"{5} {2} -map_metadata -1 -threads 0 {3}{4}{6} -y \"{1}\"",
+            var commandLineArgs = string.Format(
+                CultureInfo.InvariantCulture,
+                "-i \"{0}\" {2} -map_metadata -1 -threads 0 {3}{4}{5} -y \"{1}\"",
                 inputTempFile,
                 targetFile,
                 videoArgs,
                 GetAudioArgs(mediaSource),
                 subtitleArgs,
-                durationParam,
                 outputParam);
 
             return inputModifier + " " + commandLineArgs;
@@ -257,7 +251,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
                 {
                     _logger.LogInformation("Stopping ffmpeg recording process for {path}", _targetPath);
 
-                    //process.Kill();
                     _process.StandardInput.WriteLine("q");
                 }
                 catch (Exception ex)

+ 7 - 17
Emby.Server.Implementations/Sorting/ArtistComparer.cs

@@ -7,16 +7,14 @@ using MediaBrowser.Model.Querying;
 namespace Emby.Server.Implementations.Sorting
 {
     /// <summary>
-    /// Class ArtistComparer
+    /// Class ArtistComparer.
     /// </summary>
     public class ArtistComparer : IBaseItemComparer
     {
-        /// <summary>
-        /// Compares the specified x.
-        /// </summary>
-        /// <param name="x">The x.</param>
-        /// <param name="y">The y.</param>
-        /// <returns>System.Int32.</returns>
+        /// <inheritdoc />
+        public string Name => ItemSortBy.Artist;
+
+        /// <inheritdoc />
         public int Compare(BaseItem x, BaseItem y)
         {
             return string.Compare(GetValue(x), GetValue(y), StringComparison.CurrentCultureIgnoreCase);
@@ -29,20 +27,12 @@ namespace Emby.Server.Implementations.Sorting
         /// <returns>System.String.</returns>
         private static string GetValue(BaseItem x)
         {
-            var audio = x as Audio;
-
-            if (audio == null)
+            if (!(x is Audio audio))
             {
                 return string.Empty;
             }
 
-            return audio.Artists.Length == 0 ? null : audio.Artists[0];
+            return audio.Artists.Count == 0 ? null : audio.Artists[0];
         }
-
-        /// <summary>
-        /// Gets the name.
-        /// </summary>
-        /// <value>The name.</value>
-        public string Name => ItemSortBy.Artist;
     }
 }

+ 5 - 6
MediaBrowser.Api/Music/AlbumsService.cs

@@ -104,16 +104,15 @@ namespace MediaBrowser.Api.Music
             var album2 = (MusicAlbum)item2;
 
             var artists1 = album1
-                .AllArtists
+                .GetAllArtists()
                 .DistinctNames()
                 .ToList();
 
-            var artists2 = album2
-                .AllArtists
-                .DistinctNames()
-                .ToDictionary(i => i, StringComparer.OrdinalIgnoreCase);
+            var artists2 = new HashSet<string>(
+                album2.GetAllArtists().DistinctNames(),
+                StringComparer.OrdinalIgnoreCase);
 
-            return points + artists1.Where(artists2.ContainsKey).Sum(i => 5);
+            return points + artists1.Where(artists2.Contains).Sum(i => 5);
         }
     }
 }

+ 6 - 31
MediaBrowser.Controller/Entities/Audio/Audio.cs

@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Model.Configuration;
@@ -19,15 +20,13 @@ namespace MediaBrowser.Controller.Entities.Audio
         IHasLookupInfo<SongInfo>,
         IHasMediaSources
     {
-        /// <summary>
-        /// Gets or sets the artist.
-        /// </summary>
-        /// <value>The artist.</value>
+        /// <inheritdoc />
         [IgnoreDataMember]
-        public string[] Artists { get; set; }
+        public IReadOnlyList<string> Artists { get; set; }
 
+        /// <inheritdoc />
         [IgnoreDataMember]
-        public string[] AlbumArtists { get; set; }
+        public IReadOnlyList<string> AlbumArtists { get; set; }
 
         public Audio()
         {
@@ -63,30 +62,6 @@ namespace MediaBrowser.Controller.Entities.Audio
             return IsFileProtocol;
         }
 
-        [IgnoreDataMember]
-        public string[] AllArtists
-        {
-            get
-            {
-                var list = new string[AlbumArtists.Length + Artists.Length];
-
-                var index = 0;
-                foreach (var artist in AlbumArtists)
-                {
-                    list[index] = artist;
-                    index++;
-                }
-                foreach (var artist in Artists)
-                {
-                    list[index] = artist;
-                    index++;
-                }
-
-                return list;
-
-            }
-        }
-
         [IgnoreDataMember]
         public MusicAlbum AlbumEntity => FindParent<MusicAlbum>();
 
@@ -125,7 +100,7 @@ namespace MediaBrowser.Controller.Entities.Audio
                 songKey = Album + "-" + songKey;
             }
 
-            var albumArtist = AlbumArtists.Length == 0 ? null : AlbumArtists[0];
+            var albumArtist = AlbumArtists.FirstOrDefault();
             if (!string.IsNullOrEmpty(albumArtist))
             {
                 songKey = albumArtist + "-" + songKey;

+ 24 - 3
MediaBrowser.Controller/Entities/Audio/IHasAlbumArtist.cs

@@ -1,14 +1,35 @@
+using System.Collections.Generic;
+
 namespace MediaBrowser.Controller.Entities.Audio
 {
     public interface IHasAlbumArtist
     {
-        string[] AlbumArtists { get; set; }
+        IReadOnlyList<string> AlbumArtists { get; set; }
     }
 
     public interface IHasArtist
     {
-        string[] AllArtists { get; }
+        /// <summary>
+        /// Gets or sets the artists.
+        /// </summary>
+        /// <value>The artists.</value>
+        IReadOnlyList<string> Artists { get; set; }
+    }
+
+    public static class Extentions
+    {
+        public static IEnumerable<string> GetAllArtists<T>(this T item)
+            where T : IHasArtist, IHasAlbumArtist
+        {
+            foreach (var i in item.AlbumArtists)
+            {
+                yield return i;
+            }
 
-        string[] Artists { get; set; }
+            foreach (var i in item.Artists)
+            {
+                yield return i;
+            }
+        }
     }
 }

+ 8 - 30
MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs

@@ -18,8 +18,11 @@ namespace MediaBrowser.Controller.Entities.Audio
     /// </summary>
     public class MusicAlbum : Folder, IHasAlbumArtist, IHasArtist, IHasMusicGenres, IHasLookupInfo<AlbumInfo>, IMetadataContainer
     {
-        public string[] AlbumArtists { get; set; }
-        public string[] Artists { get; set; }
+        /// <inheritdoc />
+        public IReadOnlyList<string> AlbumArtists { get; set; }
+
+        /// <inheritdoc />
+        public IReadOnlyList<string> Artists { get; set; }
 
         public MusicAlbum()
         {
@@ -41,8 +44,7 @@ namespace MediaBrowser.Controller.Entities.Audio
             var parents = GetParents();
             foreach (var parent in parents)
             {
-                var artist = parent as MusicArtist;
-                if (artist != null)
+                if (parent is MusicArtist artist)
                 {
                     return artist;
                 }
@@ -63,30 +65,7 @@ namespace MediaBrowser.Controller.Entities.Audio
         public override bool SupportsCumulativeRunTimeTicks => true;
 
         [IgnoreDataMember]
-        public string[] AllArtists
-        {
-            get
-            {
-                var list = new string[AlbumArtists.Length + Artists.Length];
-
-                var index = 0;
-                foreach (var artist in AlbumArtists)
-                {
-                    list[index] = artist;
-                    index++;
-                }
-                foreach (var artist in Artists)
-                {
-                    list[index] = artist;
-                    index++;
-                }
-
-                return list;
-            }
-        }
-
-        [IgnoreDataMember]
-        public string AlbumArtist => AlbumArtists.Length == 0 ? null : AlbumArtists[0];
+        public string AlbumArtist => AlbumArtists.FirstOrDefault();
 
         [IgnoreDataMember]
         public override bool SupportsPeople => false;
@@ -216,8 +195,7 @@ namespace MediaBrowser.Controller.Entities.Audio
 
         private async Task RefreshArtists(MetadataRefreshOptions refreshOptions, CancellationToken cancellationToken)
         {
-            var all = AllArtists;
-            foreach (var i in all)
+            foreach (var i in this.GetAllArtists())
             {
                 // This should not be necessary but we're seeing some cases of it
                 if (string.IsNullOrEmpty(i))

+ 3 - 4
MediaBrowser.Controller/Entities/MusicVideo.cs

@@ -1,4 +1,5 @@
 using System;
+using System.Collections.Generic;
 using MediaBrowser.Controller.Entities.Audio;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Model.Configuration;
@@ -8,17 +9,15 @@ namespace MediaBrowser.Controller.Entities
 {
     public class MusicVideo : Video, IHasArtist, IHasMusicGenres, IHasLookupInfo<MusicVideoInfo>
     {
+        /// <inheritdoc />
         [IgnoreDataMember]
-        public string[] Artists { get; set; }
+        public IReadOnlyList<string> Artists { get; set; }
 
         public MusicVideo()
         {
             Artists = Array.Empty<string>();
         }
 
-        [IgnoreDataMember]
-        public string[] AllArtists => Artists;
-
         public override UnratedItem GetBlockUnratedType()
         {
             return UnratedItem.Music;

+ 1 - 1
MediaBrowser.Controller/Providers/AlbumInfo.cs

@@ -9,7 +9,7 @@ namespace MediaBrowser.Controller.Providers
         /// Gets or sets the album artist.
         /// </summary>
         /// <value>The album artist.</value>
-        public string[] AlbumArtists { get; set; }
+        public IReadOnlyList<string> AlbumArtists { get; set; }
 
         /// <summary>
         /// Gets or sets the artist provider ids.

+ 3 - 1
MediaBrowser.Controller/Providers/MusicVideoInfo.cs

@@ -1,7 +1,9 @@
+using System.Collections.Generic;
+
 namespace MediaBrowser.Controller.Providers
 {
     public class MusicVideoInfo : ItemLookupInfo
     {
-        public string[] Artists { get; set; }
+        public IReadOnlyList<string> Artists { get; set; }
     }
 }

+ 5 - 2
MediaBrowser.Controller/Providers/SongInfo.cs

@@ -1,12 +1,15 @@
 using System;
+using System.Collections.Generic;
 
 namespace MediaBrowser.Controller.Providers
 {
     public class SongInfo : ItemLookupInfo
     {
-        public string[] AlbumArtists { get; set; }
+        public IReadOnlyList<string> AlbumArtists { get; set; }
+
         public string Album { get; set; }
-        public string[] Artists { get; set; }
+
+        public IReadOnlyList<string> Artists { get; set; }
 
         public SongInfo()
         {

+ 1 - 1
MediaBrowser.Model/Dto/BaseItemDto.cs

@@ -386,7 +386,7 @@ namespace MediaBrowser.Model.Dto
         /// Gets or sets the artists.
         /// </summary>
         /// <value>The artists.</value>
-        public string[] Artists { get; set; }
+        public IReadOnlyList<string> Artists { get; set; }
 
         /// <summary>
         /// Gets or sets the artist items.

+ 3 - 1
MediaBrowser.Model/Search/SearchHint.cs

@@ -1,4 +1,5 @@
 using System;
+using System.Collections.Generic;
 
 namespace MediaBrowser.Model.Search
 {
@@ -111,6 +112,7 @@ namespace MediaBrowser.Model.Search
         /// </summary>
         /// <value>The album.</value>
         public string Album { get; set; }
+
         public Guid AlbumId { get; set; }
 
         /// <summary>
@@ -123,7 +125,7 @@ namespace MediaBrowser.Model.Search
         /// Gets or sets the artists.
         /// </summary>
         /// <value>The artists.</value>
-        public string[] Artists { get; set; }
+        public IReadOnlyList<string> Artists { get; set; }
 
         /// <summary>
         /// Gets or sets the song count.

+ 19 - 6
MediaBrowser.Providers/Books/AudioBookMetadataService.cs

@@ -11,14 +11,31 @@ namespace MediaBrowser.Providers.Books
 {
     public class AudioBookMetadataService : MetadataService<AudioBook, SongInfo>
     {
-        protected override void MergeData(MetadataResult<AudioBook> source, MetadataResult<AudioBook> target, MetadataFields[] lockedFields, bool replaceData, bool mergeMetadataSettings)
+        public AudioBookMetadataService(
+            IServerConfigurationManager serverConfigurationManager,
+            ILogger logger,
+            IProviderManager providerManager,
+            IFileSystem fileSystem,
+            IUserDataManager userDataManager,
+            ILibraryManager libraryManager)
+            : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
+        {
+        }
+
+        /// <inheritdoc />
+        protected override void MergeData(
+            MetadataResult<AudioBook> source,
+            MetadataResult<AudioBook> target,
+            MetadataFields[] lockedFields,
+            bool replaceData,
+            bool mergeMetadataSettings)
         {
             ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
 
             var sourceItem = source.Item;
             var targetItem = target.Item;
 
-            if (replaceData || targetItem.Artists.Length == 0)
+            if (replaceData || targetItem.Artists.Count == 0)
             {
                 targetItem.Artists = sourceItem.Artists;
             }
@@ -28,9 +45,5 @@ namespace MediaBrowser.Providers.Books
                 targetItem.Album = sourceItem.Album;
             }
         }
-
-        public AudioBookMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
-        {
-        }
     }
 }

+ 3 - 5
MediaBrowser.Providers/Manager/ProviderUtils.cs

@@ -252,12 +252,10 @@ namespace MediaBrowser.Providers.Manager
 
         private static void MergeAlbumArtist(BaseItem source, BaseItem target, MetadataFields[] lockedFields, bool replaceData)
         {
-            var sourceHasAlbumArtist = source as IHasAlbumArtist;
-            var targetHasAlbumArtist = target as IHasAlbumArtist;
-
-            if (sourceHasAlbumArtist != null && targetHasAlbumArtist != null)
+            if (source is IHasAlbumArtist sourceHasAlbumArtist
+                && target is IHasAlbumArtist targetHasAlbumArtist)
             {
-                if (replaceData || targetHasAlbumArtist.AlbumArtists.Length == 0)
+                if (replaceData || targetHasAlbumArtist.AlbumArtists.Count == 0)
                 {
                     targetHasAlbumArtist.AlbumArtists = sourceHasAlbumArtist.AlbumArtists;
                 }

+ 30 - 12
MediaBrowser.Providers/Music/AlbumMetadataService.cs

@@ -15,12 +15,34 @@ namespace MediaBrowser.Providers.Music
 {
     public class AlbumMetadataService : MetadataService<MusicAlbum, AlbumInfo>
     {
+        public AlbumMetadataService(
+            IServerConfigurationManager serverConfigurationManager,
+            ILogger logger,
+            IProviderManager providerManager,
+            IFileSystem fileSystem,
+            IUserDataManager userDataManager,
+            ILibraryManager libraryManager)
+            : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
+        {
+        }
+
+        /// <inheritdoc />
+        protected override bool EnableUpdatingPremiereDateFromChildren => true;
+
+        /// <inheritdoc />
+        protected override bool EnableUpdatingGenresFromChildren => true;
+
+        /// <inheritdoc />
+        protected override bool EnableUpdatingStudiosFromChildren => true;
+
+        /// <inheritdoc />
         protected override IList<BaseItem> GetChildrenForMetadataUpdates(MusicAlbum item)
         {
             return item.GetRecursiveChildren(i => i is Audio)
                         .ToList();
         }
 
+        /// <inheritdoc />
         protected override ItemUpdateType UpdateMetadataFromChildren(MusicAlbum item, IList<BaseItem> children, bool isFullRefresh, ItemUpdateType currentUpdateType)
         {
             var updateType = base.UpdateMetadataFromChildren(item, children, isFullRefresh, currentUpdateType);
@@ -50,12 +72,6 @@ namespace MediaBrowser.Providers.Music
             return updateType;
         }
 
-        protected override bool EnableUpdatingPremiereDateFromChildren => true;
-
-        protected override bool EnableUpdatingGenresFromChildren => true;
-
-        protected override bool EnableUpdatingStudiosFromChildren => true;
-
         private ItemUpdateType SetAlbumArtistFromSongs(MusicAlbum item, IEnumerable<Audio> songs)
         {
             var updateType = ItemUpdateType.None;
@@ -94,21 +110,23 @@ namespace MediaBrowser.Providers.Music
             return updateType;
         }
 
-        protected override void MergeData(MetadataResult<MusicAlbum> source, MetadataResult<MusicAlbum> target, MetadataFields[] lockedFields, bool replaceData, bool mergeMetadataSettings)
+        /// <inheritdoc />
+        protected override void MergeData(
+            MetadataResult<MusicAlbum> source,
+            MetadataResult<MusicAlbum> target,
+            MetadataFields[] lockedFields,
+            bool replaceData,
+            bool mergeMetadataSettings)
         {
             ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
 
             var sourceItem = source.Item;
             var targetItem = target.Item;
 
-            if (replaceData || targetItem.Artists.Length == 0)
+            if (replaceData || targetItem.Artists.Count == 0)
             {
                 targetItem.Artists = sourceItem.Artists;
             }
         }
-
-        public AlbumMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
-        {
-        }
     }
 }

+ 13 - 5
MediaBrowser.Providers/Music/AudioMetadataService.cs

@@ -11,6 +11,18 @@ namespace MediaBrowser.Providers.Music
 {
     public class AudioMetadataService : MetadataService<Audio, SongInfo>
     {
+        public AudioMetadataService(
+            IServerConfigurationManager serverConfigurationManager,
+            ILogger logger,
+            IProviderManager providerManager,
+            IFileSystem fileSystem,
+            IUserDataManager userDataManager,
+            ILibraryManager libraryManager)
+            : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
+        {
+        }
+
+        /// <inheritdoc />
         protected override void MergeData(MetadataResult<Audio> source, MetadataResult<Audio> target, MetadataFields[] lockedFields, bool replaceData, bool mergeMetadataSettings)
         {
             ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
@@ -18,7 +30,7 @@ namespace MediaBrowser.Providers.Music
             var sourceItem = source.Item;
             var targetItem = target.Item;
 
-            if (replaceData || targetItem.Artists.Length == 0)
+            if (replaceData || targetItem.Artists.Count == 0)
             {
                 targetItem.Artists = sourceItem.Artists;
             }
@@ -28,9 +40,5 @@ namespace MediaBrowser.Providers.Music
                 targetItem.Album = sourceItem.Album;
             }
         }
-
-        public AudioMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
-        {
-        }
     }
 }

+ 19 - 6
MediaBrowser.Providers/Music/MusicVideoMetadataService.cs

@@ -11,7 +11,24 @@ namespace MediaBrowser.Providers.Music
 {
     public class MusicVideoMetadataService : MetadataService<MusicVideo, MusicVideoInfo>
     {
-        protected override void MergeData(MetadataResult<MusicVideo> source, MetadataResult<MusicVideo> target, MetadataFields[] lockedFields, bool replaceData, bool mergeMetadataSettings)
+        public MusicVideoMetadataService(
+            IServerConfigurationManager serverConfigurationManager,
+            ILogger logger,
+            IProviderManager providerManager,
+            IFileSystem fileSystem,
+            IUserDataManager userDataManager,
+            ILibraryManager libraryManager)
+            : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
+        {
+        }
+
+        /// <inheritdoc />
+        protected override void MergeData(
+            MetadataResult<MusicVideo> source,
+            MetadataResult<MusicVideo> target,
+            MetadataFields[] lockedFields,
+            bool replaceData,
+            bool mergeMetadataSettings)
         {
             ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
 
@@ -23,14 +40,10 @@ namespace MediaBrowser.Providers.Music
                 targetItem.Album = sourceItem.Album;
             }
 
-            if (replaceData || targetItem.Artists.Length == 0)
+            if (replaceData || targetItem.Artists.Count == 0)
             {
                 targetItem.Artists = sourceItem.Artists;
             }
         }
-
-        public MusicVideoMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IFileSystem fileSystem, IUserDataManager userDataManager, ILibraryManager libraryManager) : base(serverConfigurationManager, logger, providerManager, fileSystem, userDataManager, libraryManager)
-        {
-        }
     }
 }