aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2013-09-05 15:00:50 -0400
committerLuke Pulverenti <luke.pulverenti@gmail.com>2013-09-05 15:00:50 -0400
commit44b12c0f9fc81dd10d6f655f341d7df28c5f3e20 (patch)
tree520179e21ec80e988e44407b06c2f22f040d9903
parentcbf061d5f62a98a977d192bb0117f6c21be7e808 (diff)
fixes #520 - Support multiple artists per audio track
-rw-r--r--MediaBrowser.Api/AlbumsService.cs29
-rw-r--r--MediaBrowser.Api/BaseApiService.cs14
-rw-r--r--MediaBrowser.Api/ItemRefreshService.cs14
-rw-r--r--MediaBrowser.Api/ItemUpdateService.cs2
-rw-r--r--MediaBrowser.Api/SearchService.cs5
-rw-r--r--MediaBrowser.Api/UserLibrary/ArtistsService.cs23
-rw-r--r--MediaBrowser.Controller/Entities/Audio/Audio.cs6
-rw-r--r--MediaBrowser.Controller/Entities/Folder.cs4
-rw-r--r--MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs2
-rw-r--r--MediaBrowser.Providers/MediaInfo/FFProbeAudioInfoProvider.cs33
-rw-r--r--MediaBrowser.Providers/Music/ArtistsPostScanTask.cs5
-rw-r--r--MediaBrowser.Server.Implementations/Dto/DtoService.cs5
-rw-r--r--MediaBrowser.Server.Implementations/Library/LibraryManager.cs5
-rw-r--r--MediaBrowser.Server.Implementations/Library/LuceneSearchEngine.cs14
-rw-r--r--MediaBrowser.Server.Implementations/Sorting/ArtistComparer.cs2
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>