Apple Music.app album artwork is a trainwreck

Music.app icon It’s almost two years since Music.app was launched on macOS devices and album artwork for self-stored music is still broken.

How can this be? We all know album art is important for people’s experience of their music.

But it turns out that this is a local-only, self-stored music problem. iCloud Music Library, when matched to your local music, isn’t affected; once it’s matched, Apple have their own artwork online.

I can’t help coming to the conclusion that self-stored music collections are not a profitable enough use case for Apple.

TL;DR: (to save you the time scrolling through this) I didn’t manage to fix album artwork not showing for the Albums browser. If you know how to fix it, please drop a comment or send me an email!

What prompted this? A bunch of emails to my inbox, a bunch of online discussions I’ve gradually noticed over the months, and a dead-simple replication of the same problem myself. If I could replicate this with no effort, other users must be experiencing the same thing. A lot.

Screenshot of missing album artwork

I should be clear here: we’re talking about album artwork. Music.app seems to have no problem showing artwork on individual songs. But we want the artwork to show when browsing albums too because - guess what big tech? - some of us listen to albums.

Lessons from the past

We used to have similar issues in iTunes. Just getting iTunes to see artwork you have added to your library would, historically, take more effort than it should. However, at worst, the Get Info dance would fix this, and iTunes would show any artwork that has been added.

Get Info is still there on Music.app, but it appears to have no effect, at least not at retrieving artwork that has been added.

The next resolution I used often with iTunes was the excellent repository of Apple Scripts at Doug’s Scripts. I tried using the popular Re-Embed Artwork script, essentially to refresh Music’s view of the file. Again - no dice. Artwork was still not shown.

So much for the user-level fixes. Let’s open the hood. This gets gnarly quickly, so if you glaze over at the merest mention of code, scripting, databases or the like I don’t blame you if you click the back button now. After all, it shouldn’t be this hard.

Scripting Music.app

First I tried using the Music.app API. To actually write code to import and use the API I had a quick look around for a scripting language with an interactive prompt and I found Swift has a REPL.

% swift  
Welcome to Apple Swift version 5.2.4 (swiftlang-1103.0.32.9 clang-1103.0.32.53).
Type :help for assistance.
  1>

You can use the Swift based API to interrogate the data model within Music.app. So I began hacking some commands. Here, I tried to get the artwork for one album, 19:

1> import iTunesLibrary
2. let library = try ITLibrary(apiVersion: "1.1")
3. let nineteen = library.allMediaItems.map { $0.album }.filter { $0.title=="19" }

(Note the apiVersion: "1.1" bit is important to work with Music.app, as opposed to iTunes where you use 1.0).

This retuns:

nineteen: [ITLibAlbum] = 12 values {
  [0] = {
    [email protected] = {
      isa = ITLibAlbum
    }
    _title = "19"
    _sortTitle = nil
    _compilation = '\0'
    _discCount = 1
    _discNumber = 1
    _rating = 0
    _ratingComputed = '\0'
    _gapless = '\0'
    _trackCount = 12
    _albumArtist = nil
    _sortAlbumArtist = nil
    _persistentID = Int64(5145411346023457685)
  }
  [1] = {
    [email protected] = {
      isa = ITLibAlbum
    }
    _title = "19"
  ...

An ITLibAlbum, it turns out, is just a representation of an album from a “media item”’s (a track’s) perspective. Pertinently, this doesn’t work:


4> nineteen.artwork
error: repl.swift:4:10: error: value of type '[ITLibAlbum]' has no member 'artwork'
nineteen.artwork
~~~~~~~~ ^~~~~~~

But this does, where we use an individual song instead:

5> let firstTrack = library.allMediaItems.filter { $0.album.title=="19" }[0] 
firstTrack: ITLibMediaItem = {
  [email protected] = {
    [email protected] = {
      isa = ITLibMediaItem
    }
    _fields = 23 key/value pairs {
      [0] = {
        key = "Title"
        value = "Melt My Heart to Stone"
      }
      ...
6> firstTrack.artwork
$R0: ITLibArtwork? = 0x0000000100307a60 {
  [email protected] = {
    isa = ITLibArtwork
  }
  _impl = {}
  _cachedImage = nil
}

So we can retrieve artwork information for a track. For the album this doesn’t work because artwork is not an album level concept in Music.app. Instead, it’s stored at a “media item” (i.e. a track) level. This is consistent with artwork showing for individual tracks, but not in the album browser.

This makes some sense from a user’s point of view, where you might want to see artwork for individual tracks. It’s a bit incongruous with the music industry though given that artwork really is a release-level concept.

Meanwhile,

7> library.allMediaItems.map { ($0.title, $0.artwork) }

This shows that some items have “null” artwork, but there’s no obvious pattern here. For some albums it’s a subset of tracks that show it, which seems really weird (all tracks have embedded artwork).

Regardless of all this, most importantly there is no ability in this API to update the object model. This makes it not obvious how I might fix this via the API.

So I decided to give up on that.

Opening the Music.app database

The next step was to get even dirtier and open up the database used by Music.app to store this information. If I could find and understand the underlying data maybe I could reason how the album artwork metadata is stored?

Opening the database also potentially means I could write back and update the data itself. I could potentially temporarily fix the connections between albums, tracks and their album art.

The database storing album artwork metadata is in ~/Library/Containers/com.apple.AMPArtworkAgent/Data/Documents/artworkd.sqlite. Additionally, artwork is stored with generated references inside the artwork sub folder.

I used DB Browser for SQLite to open up the database. It contains information that looks promising and maps to concepts in the API.

ZDATABASEITEMINFO contains a track’s persistent ID. This row is referred to in two other places until it reaches ZIMAGEINFO which appears to be able to reference an image file:

Screenshot of DB Browser showing tables

But the database was woefully unpopulated. This is consistent with a lack of album art. So, I thought: if I add references to images here and link the ZDATABASEITEMINFO media items to it, the artwork should show… shouldn’t it?

It would not. I tried restarting Music.app, restarting the Mac, and more, but it just didn’t appear to take. I’m guessing there is a way of doing this, but I just didn’t quite understand the schema and the format or values that are required to populate the tables.

Possible causes

What might be the causes of Music.app refusing to load embedded art? From my experience on multiple different hardware devices and software applications, it could be any of multiple of:

  • The music is in the incorrect format.
  • The artwork resolution is too large.
  • The artwork storage size is too large.
  • The artwork is in the incorrect format.
  • There are multiple embedded artworks inside the file.
  • Artwork metadata that isn’t quite correct (in many file formats the artwork can be described, e.g. “Front cover”).

All of these drew blanks - when made consistent with those albums that did show the artwork there was no improvement.

And the thing is: it’s not like Music.app is incapable of showing the artwork. The artwork does show for tracks, just not albums.

Conclusion (so far)

There’s a bug inside Music.app.

It’s been almost two years now, so it suggests Apple really doesn’t care about the local storage use case (or people that browse for Albums). This is unsurprising given they make more money by selling a service.

If anyone has any more insights, let me know in the comments.

tags: apple self-stored cover art hacking macos

The Music Library Management blog

Dan Gravell

I'm Dan, the founder and programmer of bliss. I write bliss to solve my own problems with my digital music collection.