Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend music parsing #7514

Merged
merged 13 commits into from
Oct 7, 2022
23 changes: 23 additions & 0 deletions Emby.Naming/Common/NamingOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,24 @@ public NamingOptions()
"volume"
};

ArtistSubfolders = new[]
{
"albums",
"broadcasts",
"bootlegs",
"compilations",
"dj-mixes",
"eps",
"live",
"mixtapes",
"others",
"remixes",
"singles",
"soundtracks",
"spokenwords",
"streets"
};

AudioFileExtensions = new[]
{
".669",
Expand Down Expand Up @@ -732,6 +750,11 @@ public NamingOptions()
/// </summary>
public string[] AlbumStackingPrefixes { get; set; }

/// <summary>
/// Gets or sets list of artist subfolders.
/// </summary>
public string[] ArtistSubfolders { get; set; }

/// <summary>
/// Gets or sets list of subtitle file extensions.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
Expand All @@ -18,7 +19,7 @@
namespace Emby.Server.Implementations.Library.Resolvers.Audio
{
/// <summary>
/// Class MusicAlbumResolver.
/// The music album resolver.
/// </summary>
public class MusicAlbumResolver : ItemResolver<MusicAlbum>
{
Expand Down Expand Up @@ -82,7 +83,7 @@ protected override MusicAlbum Resolve(ItemResolveArgs args)
/// </summary>
/// <param name="path">The path to check.</param>
/// <param name="directoryService">The directory service.</param>
/// <returns><c>true</c> if the provided path points to a music album, <c>false</c> otherwise.</returns>
/// <returns><c>true</c> if the provided path points to a music album; otherwise, <c>false</c>.</returns>
public bool IsMusicAlbum(string path, IDirectoryService directoryService)
{
return ContainsMusic(directoryService.GetFileSystemEntries(path), true, directoryService);
Expand All @@ -95,10 +96,19 @@ public bool IsMusicAlbum(string path, IDirectoryService directoryService)
/// <returns><c>true</c> if [is music album] [the specified args]; otherwise, <c>false</c>.</returns>
Shadowghost marked this conversation as resolved.
Show resolved Hide resolved
private bool IsMusicAlbum(ItemResolveArgs args)
{
// Args points to an album if parent is an Artist folder or it directly contains music
if (args.IsDirectory)
{
// if (args.Parent is MusicArtist) return true; // saves us from testing children twice
// If args is a artist subfolder it's not a music album
foreach (var subfolder in _namingOptions.ArtistSubfolders)
{
if (Path.GetDirectoryName(args.Path.AsSpan()).Equals(subfolder, StringComparison.OrdinalIgnoreCase))
{
_logger.LogDebug("Found release folder: {Path}", args.Path);
return false;
}
}
Shadowghost marked this conversation as resolved.
Show resolved Hide resolved

// If args contains music it's a music album
if (ContainsMusic(args.FileSystemChildren, true, args.DirectoryService))
{
return true;
Expand All @@ -111,22 +121,23 @@ private bool IsMusicAlbum(ItemResolveArgs args)
/// <summary>
/// Determine if the supplied list contains what we should consider music.
/// </summary>
/// <returns><c>true</c> if the provided path list contains music; otherwise, <c>false</c>.</returns>
private bool ContainsMusic(
ICollection<FileSystemMetadata> list,
bool allowSubfolders,
IDirectoryService directoryService)
{
// check for audio files before digging down into directories
// Check for audio files before digging down into directories
var foundAudioFile = list.Any(fileSystemInfo => !fileSystemInfo.IsDirectory && AudioFileParser.IsAudioFile(fileSystemInfo.FullName, _namingOptions));
if (foundAudioFile)
{
// at least one audio file exists
// At least one audio file exists
return true;
}

if (!allowSubfolders)
{
// not music since no audio file exists and we're not looking into subfolders
// Not music since no audio file exists and we're not looking into subfolders
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
namespace Emby.Server.Implementations.Library.Resolvers.Audio
{
/// <summary>
/// Class MusicArtistResolver.
/// The music artist resolver.
/// </summary>
public class MusicArtistResolver : ItemResolver<MusicArtist>
{
Expand All @@ -23,8 +23,8 @@ public class MusicArtistResolver : ItemResolver<MusicArtist>
/// <summary>
/// Initializes a new instance of the <see cref="MusicArtistResolver"/> class.
/// </summary>
/// <param name="logger">The logger for the created <see cref="MusicAlbumResolver"/> instances.</param>
/// <param name="namingOptions">The naming options.</param>
/// <param name="logger">Instance of the <see cref="MusicAlbumResolver"/> interface.</param>
/// <param name="namingOptions">The <see cref="NamingOptions"/>.</param>
public MusicArtistResolver(
ILogger<MusicAlbumResolver> logger,
NamingOptions namingOptions)
Expand All @@ -40,10 +40,10 @@ public class MusicArtistResolver : ItemResolver<MusicArtist>
public override ResolverPriority Priority => ResolverPriority.Second;

/// <summary>
/// Resolves the specified args.
/// Resolves the specified resolver arguments.
/// </summary>
/// <param name="args">The args.</param>
/// <returns>MusicArtist.</returns>
/// <param name="args">The resolver arguments.</param>
/// <returns>A <see cref="MusicArtist"/>.</returns>
protected override MusicArtist Resolve(ItemResolveArgs args)
{
if (!args.IsDirectory)
Expand All @@ -61,7 +61,7 @@ protected override MusicArtist Resolve(ItemResolveArgs args)

var isMusicMediaFolder = string.Equals(collectionType, CollectionType.Music, StringComparison.OrdinalIgnoreCase);

// If there's a collection type and it's not music, it can't be a series
// If there's a collection type and it's not music, it can't be a music artist
if (!isMusicMediaFolder)
{
return null;
Expand All @@ -82,14 +82,24 @@ protected override MusicArtist Resolve(ItemResolveArgs args)

var albumResolver = new MusicAlbumResolver(_logger, _namingOptions);

// If we contain an album assume we are an artist folder
var directories = args.FileSystemChildren.Where(i => i.IsDirectory);

var result = Parallel.ForEach(directories, (fileSystemInfo, state) =>
{
// If we contain a artist subfolder assume we are an artist folder
foreach (var subfolder in _namingOptions.ArtistSubfolders)
{
if (fileSystemInfo.Name.Equals(subfolder, StringComparison.OrdinalIgnoreCase))
{
// Stop once we see an artist subfolder
state.Stop();
}
}

// If we contain a music album assume we are an artist folder
if (albumResolver.IsMusicAlbum(fileSystemInfo.FullName, directoryService))
{
// stop once we see a music album
// Stop once we see a music album
state.Stop();
}
});
Expand Down
2 changes: 1 addition & 1 deletion MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public MusicAlbum()
public string AlbumArtist => AlbumArtists.FirstOrDefault();

[JsonIgnore]
public override bool SupportsPeople => false;
public override bool SupportsPeople => true;

/// <summary>
/// Gets the tracks.
Expand Down
6 changes: 3 additions & 3 deletions MediaBrowser.Controller/Providers/ICustomMetadataProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ public interface ICustomMetadataProvider<TItemType> : IMetadataProvider<TItemTyp
/// Fetches the metadata asynchronously.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="options">The options.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{ItemUpdateType}.</returns>
/// <param name="options">The <see cref="MetadataRefreshOptions"/>.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param>
/// <returns>A <see cref="Task"/> fetching the <see cref="ItemUpdateType"/>.</returns>
Task<ItemUpdateType> FetchAsync(TItemType item, MetadataRefreshOptions options, CancellationToken cancellationToken);
}
}
1 change: 1 addition & 0 deletions MediaBrowser.Providers/MediaBrowser.Providers.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="OptimizedPriorityQueue" Version="5.1.0" />
<PackageReference Include="PlaylistsNET" Version="1.2.1" />
<PackageReference Include="TagLibSharp" Version="2.3.0" />
<PackageReference Include="TMDbLib" Version="1.9.2" />
</ItemGroup>

Expand Down