namespace Music; public sealed class MusicAudioTransientException : Exception { public string ProviderId { get; } public MusicAudioTransientException(string providerId, string operation, Exception innerException) : base($"{providerId} {operation} temporarily failed.", innerException) { ProviderId = providerId; } } public interface IMusicMetadataProvider { string Id { get; } string Name { get; } bool Enabled { get; } Task SearchAsync(string query, bool expanded = false, CancellationToken cancellationToken = default); Task GetArtistAsync(string id, CancellationToken cancellationToken = default); Task GetAlbumAsync(string id, CancellationToken cancellationToken = default); Task GetTrackAsync(string id, CancellationToken cancellationToken = default); } public interface IMusicDiscoveryProvider { string Id { get; } string Name { get; } bool Enabled { get; } Task> GetHomeSectionsAsync(int limit, CancellationToken cancellationToken = default); Task GetSectionAsync(string sectionId, int limit, CancellationToken cancellationToken = default); } public interface IMusicAudioProvider { string Id { get; } string Name { get; } bool Enabled { get; } bool RequiresAuth { get; } bool CacheMissingMatches { get; } Task> MatchTrackAsync(MusicTrack track, string playbackMode = null, string profileId = null, CancellationToken cancellationToken = default); Task> SearchMatchesByQueryAsync(string query, CancellationToken cancellationToken = default); Task> GetStreamsAsync(MusicAudioMatch match, string playbackMode = null, string profileId = null, CancellationToken cancellationToken = default); Task TryGetPreferredStreamAsync(MusicAudioMatch match, string playbackMode = null, string profileId = null, CancellationToken cancellationToken = default); bool IsRelevantMatch(MusicTrack track, MusicAudioMatch match); bool ShouldValidatePinnedMatch(MusicTrack track, MusicAudioMatch match); IReadOnlyList GetFallbackProviderIds(MusicTrack track); } public interface IMusicAuthProvider { string Id { get; } string Name { get; } bool Enabled { get; } Task GetStateAsync(string profileId = null, CancellationToken cancellationToken = default); Task SaveAsync(string payload, string profileId = null, CancellationToken cancellationToken = default); Task LogoutAsync(string profileId = null, CancellationToken cancellationToken = default); }