Getting Started
Shiny.Music provides a unified API for accessing the device music library on Android and iOS. It supports permission management, querying track metadata, playing music files, and copying tracks (where platform restrictions allow).
Features
Section titled “Features”- Request and check music library permissions on both platforms
- Query all music tracks or search by title, artist, or album
- Browse by genre, year, or decade — each with track counts
- Browse playlists and their tracks
- Filter tracks by any combination of genre, year, decade, and search query via
MusicFilter - Cross-dimensional browsing — genres by decade, years by genre, etc.
- Play, pause, resume, stop, and seek within tracks
- Stream Apple Music subscription tracks via
MPMusicPlayerControlleron iOS - Check for active streaming subscriptions
- Copy music files to app storage (non-DRM content only on iOS)
- Event-driven playback state changes and completion notifications
Platform Support
Section titled “Platform Support”| Feature | Android | iOS |
|---|---|---|
| Permission Request | ✅ | ✅ |
| Query Tracks | ✅ | ✅ |
| Search Tracks | ✅ | ✅ |
| Browse by Genre | ✅ | ✅ |
| Browse by Year / Decade | ✅ | ✅ |
| Browse Playlists | ✅ | ✅ |
| Filter by Genre + Year/Decade | ✅ | ✅ |
| Local Playback | ✅ | ✅ (AVAudioPlayer) |
| Streaming Playback | ❌ | ✅ (MPMusicPlayerController via StoreId) |
| Copy Track | ✅ | ✅ (non-DRM only) |
| Streaming Subscription Check | ❌ (always false) | ✅ (SKCloudServiceController) |
| Album Art URI | ✅ | ❌ (use MPMediaItem.Artwork) |
| Explicit Flag | ❌ | ✅ (via MPMediaItem.IsExplicitItem) |
Installation
Section titled “Installation”Add a project reference to Shiny.Music in your .NET MAUI or platform-specific project.
Register the services in your MauiProgram.cs:
using Shiny.Music;
public static class MauiProgram{ public static MauiApp CreateMauiApp() { var builder = MauiApp.CreateBuilder(); builder.UseMauiApp<App>();
builder.Services.AddShinyMusic();
return builder.Build(); }}Quick Example
Section titled “Quick Example”public class MyPage{ readonly IMediaLibrary _library; readonly IMusicPlayer _player;
public MyPage(IMediaLibrary library, IMusicPlayer player) { _library = library; _player = player; }
async Task PlayFirstTrack() { // 1. Request permission var status = await _library.RequestPermissionAsync(); if (status != PermissionStatus.Granted) return;
// 2. Get all tracks var tracks = await _library.GetAllTracksAsync(); if (tracks.Count == 0) return;
// 3. Play the first track await _player.PlayAsync(tracks[0]);
// 4. Listen for completion _player.PlaybackCompleted += (s, e) => { Console.WriteLine("Track finished!"); }; }
async Task BrowseAndFilter() { // Browse genres with track counts var genres = await _library.GetGenresAsync(); foreach (var g in genres) Console.WriteLine($"{g.Value} ({g.Count} tracks)");
// Browse decades var decades = await _library.GetDecadesAsync(); foreach (var d in decades) Console.WriteLine($"{d.Value}s ({d.Count} tracks)");
// Get rock tracks from the 1990s var tracks = await _library.GetTracksAsync(new MusicFilter { Genre = "Rock", Decade = 1990 });
// Get genres within the 2000s var genresIn2000s = await _library.GetGenresAsync(new MusicFilter { Decade = 2000 });
// Browse playlists var playlists = await _library.GetPlaylistsAsync(); foreach (var p in playlists) Console.WriteLine($"{p.Name} ({p.SongCount} songs)");
// Get tracks in a playlist var playlistTracks = await _library.GetPlaylistTracksAsync(playlists[0].Id); }}Samples
Section titled “Samples”AI Coding Assistant
Section titled “AI Coding Assistant”An AI skill is available for Shiny Music to help generate music library code, configure permissions, and follow best practices directly in your IDE.
Claude Code
claude plugin add github:shinyorg/skillsGitHub Copilot — Copy the shiny-music skill file into your repository’s custom instructions.