diff options
| author | Luke Pulverenti <luke.pulverenti@gmail.com> | 2013-09-05 15:00:50 -0400 |
|---|---|---|
| committer | Luke Pulverenti <luke.pulverenti@gmail.com> | 2013-09-05 15:00:50 -0400 |
| commit | 44b12c0f9fc81dd10d6f655f341d7df28c5f3e20 (patch) | |
| tree | 520179e21ec80e988e44407b06c2f22f040d9903 | |
| parent | cbf061d5f62a98a977d192bb0117f6c21be7e808 (diff) | |
fixes #520 - Support multiple artists per audio track
| -rw-r--r-- | MediaBrowser.Api/AlbumsService.cs | 29 | ||||
| -rw-r--r-- | MediaBrowser.Api/BaseApiService.cs | 14 | ||||
| -rw-r--r-- | MediaBrowser.Api/ItemRefreshService.cs | 14 | ||||
| -rw-r--r-- | MediaBrowser.Api/ItemUpdateService.cs | 2 | ||||
| -rw-r--r-- | MediaBrowser.Api/SearchService.cs | 5 | ||||
| -rw-r--r-- | MediaBrowser.Api/UserLibrary/ArtistsService.cs | 23 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Entities/Audio/Audio.cs | 6 | ||||
| -rw-r--r-- | MediaBrowser.Controller/Entities/Folder.cs | 4 | ||||
| -rw-r--r-- | MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs | 2 | ||||
| -rw-r--r-- | MediaBrowser.Providers/MediaInfo/FFProbeAudioInfoProvider.cs | 33 | ||||
| -rw-r--r-- | MediaBrowser.Providers/Music/ArtistsPostScanTask.cs | 5 | ||||
| -rw-r--r-- | MediaBrowser.Server.Implementations/Dto/DtoService.cs | 5 | ||||
| -rw-r--r-- | MediaBrowser.Server.Implementations/Library/LibraryManager.cs | 5 | ||||
| -rw-r--r-- | MediaBrowser.Server.Implementations/Library/LuceneSearchEngine.cs | 14 | ||||
| -rw-r--r-- | MediaBrowser.Server.Implementations/Sorting/ArtistComparer.cs | 2 |
15 files changed, 110 insertions, 53 deletions
diff --git a/MediaBrowser.Api/AlbumsService.cs b/MediaBrowser.Api/AlbumsService.cs index e78a30c4a..d31bef428 100644 --- a/MediaBrowser.Api/AlbumsService.cs +++ b/MediaBrowser.Api/AlbumsService.cs @@ -5,6 +5,7 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Persistence; using ServiceStack.ServiceHost; using System; +using System.Collections.Generic; using System.Linq; namespace MediaBrowser.Api @@ -76,15 +77,35 @@ namespace MediaBrowser.Api var artists1 = album1.RecursiveChildren .OfType<Audio>() - .SelectMany(i => new[] { i.AlbumArtist, i.Artist }) - .Where(i => !string.IsNullOrEmpty(i)) + .SelectMany(i => + { + var list = new List<string>(); + + if (!string.IsNullOrEmpty(i.AlbumArtist)) + { + list.Add(i.AlbumArtist); + } + list.AddRange(i.Artists); + + return list; + }) .Distinct(StringComparer.OrdinalIgnoreCase) .ToList(); var artists2 = album2.RecursiveChildren .OfType<Audio>() - .SelectMany(i => new[] { i.AlbumArtist, i.Artist }) - .Where(i => !string.IsNullOrEmpty(i)) + .SelectMany(i => + { + var list = new List<string>(); + + if (!string.IsNullOrEmpty(i.AlbumArtist)) + { + list.Add(i.AlbumArtist); + } + list.AddRange(i.Artists); + + return list; + }) .Distinct(StringComparer.OrdinalIgnoreCase) .ToDictionary(i => i, StringComparer.OrdinalIgnoreCase); diff --git a/MediaBrowser.Api/BaseApiService.cs b/MediaBrowser.Api/BaseApiService.cs index f4b14d5a8..81c2d43e4 100644 --- a/MediaBrowser.Api/BaseApiService.cs +++ b/MediaBrowser.Api/BaseApiService.cs @@ -140,8 +140,18 @@ namespace MediaBrowser.Api return libraryManager.RootFolder.RecursiveChildren .OfType<Audio>() - .SelectMany(i => new[] { i.Artist, i.AlbumArtist }) - .Where(i => !string.IsNullOrEmpty(i)) + .SelectMany(i => + { + var list = new List<string>(); + + if (!string.IsNullOrEmpty(i.AlbumArtist)) + { + list.Add(i.AlbumArtist); + } + list.AddRange(i.Artists); + + return list; + }) .Distinct(StringComparer.OrdinalIgnoreCase) .FirstOrDefault(i => { diff --git a/MediaBrowser.Api/ItemRefreshService.cs b/MediaBrowser.Api/ItemRefreshService.cs index e31292e9d..d71f171a4 100644 --- a/MediaBrowser.Api/ItemRefreshService.cs +++ b/MediaBrowser.Api/ItemRefreshService.cs @@ -1,5 +1,6 @@ using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Library; using ServiceStack.ServiceHost; using System; @@ -111,14 +112,25 @@ namespace MediaBrowser.Api { var item = await GetArtist(request.Name, _libraryManager).ConfigureAwait(false); + var cancellationToken = CancellationToken.None; + try { - await item.RefreshMetadata(CancellationToken.None, forceRefresh: request.Forced).ConfigureAwait(false); + await item.RefreshMetadata(cancellationToken, forceRefresh: request.Forced).ConfigureAwait(false); } catch (Exception ex) { Logger.ErrorException("Error refreshing library", ex); } + + // Refresh albums + var refreshTasks = _libraryManager.RootFolder + .RecursiveChildren + .OfType<MusicAlbum>() + .Where(i => i.HasArtist(item.Name)) + .Select(i => i.ValidateChildren(new Progress<double>(), cancellationToken, true, request.Forced)); + + await Task.WhenAll(refreshTasks).ConfigureAwait(false); } public void Post(RefreshGenre request) diff --git a/MediaBrowser.Api/ItemUpdateService.cs b/MediaBrowser.Api/ItemUpdateService.cs index aff81283d..df5c32b99 100644 --- a/MediaBrowser.Api/ItemUpdateService.cs +++ b/MediaBrowser.Api/ItemUpdateService.cs @@ -275,7 +275,7 @@ namespace MediaBrowser.Api { song.Album = request.Album; song.AlbumArtist = request.AlbumArtist; - song.Artist = request.Artists[0]; + song.Artists = request.Artists.ToList(); } var musicVideo = item as MusicVideo; diff --git a/MediaBrowser.Api/SearchService.cs b/MediaBrowser.Api/SearchService.cs index 33b7422e6..2b3f11761 100644 --- a/MediaBrowser.Api/SearchService.cs +++ b/MediaBrowser.Api/SearchService.cs @@ -196,8 +196,7 @@ namespace MediaBrowser.Api result.SongCount = songs.Count; result.Artists = songs - .Select(i => i.Artist) - .Where(i => !string.IsNullOrEmpty(i)) + .SelectMany(i => i.Artists) .Distinct(StringComparer.OrdinalIgnoreCase) .ToArray(); @@ -210,7 +209,7 @@ namespace MediaBrowser.Api { result.Album = song.Album; result.AlbumArtist = song.AlbumArtist; - result.Artists = !string.IsNullOrEmpty(song.Artist) ? new[] { song.Artist } : new string[] { }; + result.Artists = song.Artists.ToArray(); } return result; diff --git a/MediaBrowser.Api/UserLibrary/ArtistsService.cs b/MediaBrowser.Api/UserLibrary/ArtistsService.cs index 3213b2e67..6bc8a2bea 100644 --- a/MediaBrowser.Api/UserLibrary/ArtistsService.cs +++ b/MediaBrowser.Api/UserLibrary/ArtistsService.cs @@ -181,20 +181,17 @@ namespace MediaBrowser.Api.UserLibrary return itemsList .SelectMany(i => + { + var list = new List<string>(); + + if (!string.IsNullOrEmpty(i.AlbumArtist)) { - var list = new List<string>(); - - if (!string.IsNullOrEmpty(i.AlbumArtist)) - { - list.Add(i.AlbumArtist); - } - if (!string.IsNullOrEmpty(i.Artist)) - { - list.Add(i.Artist); - } - - return list; - }) + list.Add(i.AlbumArtist); + } + list.AddRange(i.Artists); + + return list; + }) .Distinct(StringComparer.OrdinalIgnoreCase) .Select(name => new IbnStub<Artist>(name, () => itemsList.Where(i => i.HasArtist(name)), GetEntity)); } diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs index 5ee1e8152..7c226864b 100644 --- a/MediaBrowser.Controller/Entities/Audio/Audio.cs +++ b/MediaBrowser.Controller/Entities/Audio/Audio.cs @@ -1,6 +1,7 @@ using MediaBrowser.Model.Entities; using System; using System.Collections.Generic; +using System.Linq; using System.Runtime.Serialization; namespace MediaBrowser.Controller.Entities.Audio @@ -13,6 +14,7 @@ namespace MediaBrowser.Controller.Entities.Audio public Audio() { MediaStreams = new List<MediaStream>(); + Artists = new List<string>(); } /// <summary> @@ -57,7 +59,7 @@ namespace MediaBrowser.Controller.Entities.Audio /// Gets or sets the artist. /// </summary> /// <value>The artist.</value> - public string Artist { get; set; } + public List<string> Artists { get; set; } /// <summary> /// Gets or sets the album. @@ -99,7 +101,7 @@ namespace MediaBrowser.Controller.Entities.Audio /// <returns><c>true</c> if the specified name has artist; otherwise, <c>false</c>.</returns> public bool HasArtist(string name) { - return string.Equals(Artist, name, StringComparison.OrdinalIgnoreCase) || string.Equals(AlbumArtist, name, StringComparison.OrdinalIgnoreCase); + return Artists.Contains(name, StringComparer.OrdinalIgnoreCase) || string.Equals(AlbumArtist, name, StringComparison.OrdinalIgnoreCase); } } } diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 91f4504c2..8945a3307 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -257,7 +257,7 @@ namespace MediaBrowser.Controller.Entities { var songs = recursiveChildren.OfType<Audio.Audio>().ToList(); - indexFolders = songs.Select(i => i.Artist ?? string.Empty) + indexFolders = songs.SelectMany(i => i.Artists) .Distinct(StringComparer.OrdinalIgnoreCase) .Select(i => { @@ -278,7 +278,7 @@ namespace MediaBrowser.Controller.Entities }) .Where(i => i != null) .Select(a => new IndexFolder(us, a, - songs.Where(i => string.Equals(i.Artist, a.Name, StringComparison.OrdinalIgnoreCase) + songs.Where(i => i.Artists.Contains(a.Name, StringComparer.OrdinalIgnoreCase) ), currentIndexName)).Concat(indexFolders); } diff --git a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs index 44bc461f3..26c850717 100644 --- a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs @@ -155,7 +155,7 @@ namespace MediaBrowser.Providers.MediaInfo var album = item.Parent as MusicAlbum; var filename = item.Album ?? string.Empty; - filename += item.Artist ?? string.Empty; + filename += item.Artists.FirstOrDefault() ?? string.Empty; filename += album == null ? item.Id.ToString("N") + item.DateModified.Ticks : album.Id.ToString("N") + album.DateModified.Ticks; var path = ImageCache.GetResourcePath(filename + "_primary", ".jpg"); diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfoProvider.cs b/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfoProvider.cs index edaef5b04..3a0640e56 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfoProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfoProvider.cs @@ -128,7 +128,19 @@ namespace MediaBrowser.Providers.MediaInfo audio.Album = GetDictionaryValue(tags, "album"); - audio.Artist = GetDictionaryValue(tags, "artist"); + var artist = GetDictionaryValue(tags, "artist"); + + if (string.IsNullOrWhiteSpace(artist)) + { + audio.Artists.Clear(); + } + else + { + audio.Artists = Split(artist) + .Distinct(StringComparer.OrdinalIgnoreCase) + .ToList(); + + } // Several different forms of albumartist audio.AlbumArtist = GetDictionaryValue(tags, "albumartist") ?? GetDictionaryValue(tags, "album artist") ?? GetDictionaryValue(tags, "album_artist"); @@ -159,6 +171,8 @@ namespace MediaBrowser.Providers.MediaInfo if (!audio.LockedFields.Contains(MetadataFields.Studios)) { + audio.Studios.Clear(); + // There's several values in tags may or may not be present FetchStudios(audio, tags, "organization"); FetchStudios(audio, tags, "ensemble"); @@ -166,6 +180,8 @@ namespace MediaBrowser.Providers.MediaInfo } } + private readonly char[] _nameDelimiters = new[] { '/', '|', ';', '\\' }; + /// <summary> /// Splits the specified val. /// </summary> @@ -175,9 +191,10 @@ namespace MediaBrowser.Providers.MediaInfo { // Only use the comma as a delimeter if there are no slashes or pipes. // We want to be careful not to split names that have commas in them - var delimeter = val.IndexOf('/') == -1 && val.IndexOf('|') == -1 ? new[] { ',' } : new[] { '/', '|' }; + var delimeter = _nameDelimiters.Any(i => val.IndexOf(i) != -1) ? _nameDelimiters : new[] { ',' }; - return val.Split(delimeter, StringSplitOptions.RemoveEmptyEntries); + return val.Split(delimeter, StringSplitOptions.RemoveEmptyEntries) + .Where(i => !string.IsNullOrWhiteSpace(i)); } /// <summary> @@ -194,11 +211,8 @@ namespace MediaBrowser.Providers.MediaInfo { // Sometimes the artist name is listed here, account for that var studios = - val.Split(new[] { '/', '|' }, StringSplitOptions.RemoveEmptyEntries) - .Where(i => !string.IsNullOrWhiteSpace(i)) - .Where(i => !string.Equals(i, audio.Artist, StringComparison.OrdinalIgnoreCase) && !string.Equals(i, audio.AlbumArtist, StringComparison.OrdinalIgnoreCase)); - - audio.Studios.Clear(); + Split(val) + .Where(i => !audio.HasArtist(i)); foreach (var studio in studios) { @@ -221,8 +235,7 @@ namespace MediaBrowser.Providers.MediaInfo { audio.Genres.Clear(); - foreach (var genre in val - .Split(new[] { '/', '|' }, StringSplitOptions.RemoveEmptyEntries) + foreach (var genre in Split(val) .Where(i => !string.IsNullOrWhiteSpace(i))) { // Account for sloppy tags by trimming diff --git a/MediaBrowser.Providers/Music/ArtistsPostScanTask.cs b/MediaBrowser.Providers/Music/ArtistsPostScanTask.cs index dbc57e242..58da610a6 100644 --- a/MediaBrowser.Providers/Music/ArtistsPostScanTask.cs +++ b/MediaBrowser.Providers/Music/ArtistsPostScanTask.cs @@ -135,10 +135,7 @@ namespace MediaBrowser.Providers.Music { list.Add(i.AlbumArtist); } - if (!string.IsNullOrEmpty(i.Artist)) - { - list.Add(i.Artist); - } + list.AddRange(i.Artists); return list; }) diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 66e3613f5..4ad2479e6 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -893,7 +893,7 @@ namespace MediaBrowser.Server.Implementations.Dto { dto.Album = audio.Album; dto.AlbumArtist = audio.AlbumArtist; - dto.Artists = new[] { audio.Artist }; + dto.Artists = audio.Artists.ToArray(); var albumParent = audio.FindParent<MusicAlbum>(); @@ -919,8 +919,7 @@ namespace MediaBrowser.Server.Implementations.Dto dto.AlbumArtist = songs.Select(i => i.AlbumArtist).FirstOrDefault(i => !string.IsNullOrEmpty(i)); dto.Artists = - songs.Select(i => i.Artist ?? string.Empty) - .Where(i => !string.IsNullOrEmpty(i)) + songs.SelectMany(i => i.Artists) .Distinct(StringComparer.OrdinalIgnoreCase) .ToArray(); } diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs index 29a495247..d9ab75397 100644 --- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs +++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs @@ -900,10 +900,7 @@ namespace MediaBrowser.Server.Implementations.Library { list.Add(c.AlbumArtist); } - if (!string.IsNullOrEmpty(c.Artist)) - { - list.Add(c.Artist); - } + list.AddRange(c.Artists); return list; }) diff --git a/MediaBrowser.Server.Implementations/Library/LuceneSearchEngine.cs b/MediaBrowser.Server.Implementations/Library/LuceneSearchEngine.cs index 0fd39a25d..d8b8a18e9 100644 --- a/MediaBrowser.Server.Implementations/Library/LuceneSearchEngine.cs +++ b/MediaBrowser.Server.Implementations/Library/LuceneSearchEngine.cs @@ -120,8 +120,18 @@ namespace MediaBrowser.Server.Implementations.Library // Find artists var artists = items.OfType<Audio>() - .SelectMany(i => new[] { i.Artist, i.AlbumArtist }) - .Where(i => !string.IsNullOrEmpty(i)) + .SelectMany(i => + { + var list = new List<string>(); + + if (!string.IsNullOrEmpty(i.AlbumArtist)) + { + list.Add(i.AlbumArtist); + } + list.AddRange(i.Artists); + + return list; + }) .Distinct(StringComparer.OrdinalIgnoreCase) .ToList(); diff --git a/MediaBrowser.Server.Implementations/Sorting/ArtistComparer.cs b/MediaBrowser.Server.Implementations/Sorting/ArtistComparer.cs index b0a6989e9..e3de0df28 100644 --- a/MediaBrowser.Server.Implementations/Sorting/ArtistComparer.cs +++ b/MediaBrowser.Server.Implementations/Sorting/ArtistComparer.cs @@ -37,7 +37,7 @@ namespace MediaBrowser.Server.Implementations.Sorting return string.Empty; } - return audio.Artist ?? string.Empty; + return audio.Artists.FirstOrDefault() ?? string.Empty; } /// <summary> |
