Use local image files for cover art

I’m trying to show custom cover art for an album that has no art embedded.
I added a cover.jpg to one album’s directory and added ‘cover.jpg’ (among others) to the ‘album_art_files’ config to the mopidy.conf file as seen in the effective config.
I then cleared the entire mopidy db and rescanned my music catalog, but it doesn’t pickup the new cover.

What am I missing?

Running on a RaspberryPi 4B with 4GB with the latest OS, Mopidy and plugins.

cache_dir = /var/cache/mopidy
config_dir = /etc/mopidy
data_dir = /var/lib/mopidy
max_tracklist_length = 10000
restore_state = false

verbosity = 0
format = %(levelname)-8s [%(threadName)s] %(name)s %(message)s
color = true
config_file =

mixer = software
mixer_volume =
output = autoaudiosink
buffer_time =

scheme =
hostname =
port =
username =
password =

enabled = true
timeout = 5000
filter =

enabled = true
stations =
afterhours = false
archive_types =
enabled = true
musicbox = false
websocket_host =
websocket_port =
on_track_click = PLAY_ALL

enabled = false  ; Extension disabled by user config.

enabled = true
max_search_results = 100
media_dir = /mnt/cab/music
scan_timeout = 15000
scan_flush_threshold = 100
scan_follow_symlinks = false
included_file_extensions =
excluded_file_extensions =
directories =
  Albums                  local:directory?type=album
  Artists                 local:directory?type=artist
  Composers               local:directory?type=artist&role=composer
  Genres                  local:directory?type=genre
  Performers              local:directory?type=artist&role=performer
  Release Years           local:directory?type=date&format=%25Y
  Tracks                  local:directory?type=track
  Last Week's Updates     local:directory?max-age=604800
  Last Month's Updates    local:directory?max-age=2592000
timeout = 10
use_artist_sortname = false
album_art_files =
enabled = true
country = US
locale = en_US
verify_certificates = true
snapcast_enabled = false
snapcast_host = localhost
snapcast_port = 1780
snapcast_ssl = false
snapcast_stream = Default
spotify_authorization_url =
lastfm_authorization_url =
genius_authorization_url =
data_dir = $XDG_DATA_DIR/iris

enabled = false  ; Extension disabled by user config.

enabled = true
hostname = ::
port = 6680
zeroconf = Mopidy HTTP server on $hostname
allowed_origins =
csrf_protection = true
default_app = mopidy

enabled = true
base_dir =
default_encoding = latin-1
default_extension = .m3u8
playlists_dir = /mnt/cab/music/playlists

enabled = true

enabled = true
protocols =
metadata_blacklist =
timeout = 5000


Executable: /usr/bin/mopidy
Platform: Linux-5.10.103-v7l+-armv7l-with-glibc2.31
Python: CPython 3.9.2 from /usr/lib/python3.9
Mopidy: 3.2.0 from /usr/lib/python3/dist-packages
Mopidy-TuneIn: 1.1.0 from /usr/local/lib/python3.9/dist-packages
  Pykka: 2.0.3 from /usr/lib/python3/dist-packages
  Mopidy: 3.2.0 from /usr/lib/python3/dist-packages
  setuptools: 52.0.0 from /usr/lib/python3/dist-packages
  requests: 2.25.1 from /usr/lib/python3/dist-packages
Mopidy-Local: 3.2.1 from /usr/local/lib/python3.9/dist-packages
  Pykka: 2.0.3 from /usr/lib/python3/dist-packages
  Mopidy: 3.2.0 from /usr/lib/python3/dist-packages
  uritools: 3.0.2 from /usr/local/lib/python3.9/dist-packages
  setuptools: 52.0.0 from /usr/lib/python3/dist-packages
Mopidy-Muse: 0.0.27 from /usr/local/lib/python3.9/dist-packages
  Pykka: 2.0.3 from /usr/lib/python3/dist-packages
  Mopidy: 3.2.0 from /usr/lib/python3/dist-packages
  setuptools: 52.0.0 from /usr/lib/python3/dist-packages
Mopidy-MusicBox-Webclient: 3.1.0 from /usr/local/lib/python3.9/dist-packages
  Pykka: 2.0.3 from /usr/lib/python3/dist-packages
  Mopidy: 3.2.0 from /usr/lib/python3/dist-packages
  setuptools: 52.0.0 from /usr/lib/python3/dist-packages
Mopidy-ORFRadio: 2.1.0 from /usr/local/lib/python3.9/dist-packages
  Pykka: 2.0.3 from /usr/lib/python3/dist-packages
  python-dateutil: 2.8.2 from /usr/local/lib/python3.9/dist-packages
    six: 1.16.0 from /usr/lib/python3/dist-packages
  Mopidy: 3.2.0 from /usr/lib/python3/dist-packages
  beaker: 1.11.0 from /usr/local/lib/python3.9/dist-packages
  setuptools: 52.0.0 from /usr/lib/python3/dist-packages
Mopidy-Iris: 3.62.0 from /usr/local/lib/python3.9/dist-packages
  Pykka: 2.0.3 from /usr/lib/python3/dist-packages
  Mopidy: 3.2.0 from /usr/lib/python3/dist-packages
  setuptools: 52.0.0 from /usr/lib/python3/dist-packages
GStreamer: from /usr/lib/python3/dist-packages/gi
  Detailed information:
    Python wrapper: python-gi 3.38.0
    Relevant elements:
      Not found:

How are you working out if the new cover.jpg is picked up? If you increase the logging verbosity it should print some messages when copying the image file to Mopidy-Local’s images directory. It’s quite difficult to tell which image file corresponds to which track due to the naming scheme but we might get some hints. Have you verified there are errors during the scan?

I always end up with the same error when scanning even with log level 0 and opened a ticket for that (Scanning with mopidy-local fails)

I updated the log level to 1 and rescanned.

When I pull the log file with sudo journalctl -u mopidy | tee mopidy.log I end up with a 300 mb file with all logs since I setup mopidy. It appears that the logfile isn’t auto rotated. Where can I find the log file so I can remove it and start new? I didn’t see it in /var/log.

And regarding if the cover.jpg was loaded, I figured I can check in Iris UI if that album shows the new cover.

I cranked up the log level to 4 and found that the cover.jpg file was on the exclude list:

DEBUG    [MainThread] mopidy_local.commands Skipped file:///mnt/kabinettle/music/Avishai%20Cohen/As%20Is...%20Live%20at%20the%20Blue%20Note/cover.jpg: File extension on excluded list
DEBUG    [MainThread] mopidy_local.commands Skipped file:///mnt/kabinettle/music/Avishai%20Cohen/As%20Is...%20Live%20at%20the%20Blue%20Note/._cover.jpg: Hidden directory/file

So I removed it from the exclude list, which just found the opposite – which makes sense – that the exclude list only applies to media files and not for cover art

DEBUG    [MainThread] mopidy_local.commands Included file:///mnt/kabinettle/music/Avishai%20Cohen/As%20Is...%20Live%20at%20the%20Blue%20Note/cover.jpg: File extension not on excluded list
DEBUG    [MainThread] mopidy_local.commands Skipped file:///mnt/kabinettle/music/Avishai%20Cohen/As%20Is...%20Live%20at%20the%20Blue%20Note/._cover.jpg: Hidden directory/file
WARNING  [MainThread] mopidy_local.commands Failed scanning file:///mnt/kabinettle/music/Avishai%20Cohen/As%20Is...%20Live%20at%20the%20Blue%20Note/cover.jpg: No audio found in file

But I can find no other mention of ‘cover.jpg’ in the log output

Right, that won’t help, as you’ve found. Folder cover art isn’t picked up by the scanner itself. And as I said, the name is mangled so it’s hard to see what’s going on. What I’ve done in the past is:

  • move the media file out of the media dir
  • rescan so that file is removed from Mopidy-Local database
  • turn the log level way up
  • move the file back into the media dir and rescan

Then go through that smaller log carefully.

The journalctl command you posted will show all runs of Mopidy, as you’ve found. Journalctl is a bit crap and is missing an easy to show the last run but you can give it a --since argument to restrict the output.

I think in general we need to make some improvements to the logging and the debug functionality of Mopidy-Local scanning to better see what happens in situations like this. I’ll take a look, as well as merging the fix for that crash you mentioned.

I’ve had a look and a play around and the logging isn’t that useful here since you’ll never see anything like cover.jpg in the log output. I’m going to push some improvements to that but I think right now the best thing is to either check what’s in the database itself or use JSON-RPC commands to see what Mopidy found. I’m confident it will use cover art from the same folder in addition to anything embedded, I’ve verified that on my system.

For some given album tracks that do not contain embedded image data, but live in a folder containing album art files, you can do:

$ sudo apt install sqlite3
$ sqlite3 /var/lib/mopidy/local/library.db  "SELECT images FROM album WHERE name='Irony Is a Dead Scene'"
/local/a921f26cb6abc4d2f663381e9773ba4e-475x475.jpeg /local/ab8593e54f1d852f6eb56da5bd200226-75x75.jpeg /local/e708e46d949dd83776c2ff2bf8aaa0cb-200x200.jpeg /local/dea1fecf261cf8d570b7498f102cdf9f-475x475.jpeg

You can view them in a browser by appending the hash e.g. http://localhost:6680/local/a921f26cb6abc4d2f663381e9773ba4e-475x475.jpeg

w.r.t to Iris I can see Mopidy returns all 4 images to Iris for a track from the album. And Iris uses the first one.

DEBUG    2022-04-01 17:36:57,572 [1151:HttpServer] mopidy.http.handlers
  Received WebSocket message from '{"method":"core.library.get_images","params":{"uris":["local:track:The%20Dillinger%20Escape%20Plan%20-%20Irony%20Is%20a%20Dead%20Scene/01%20Hollywood%20Squares.mp3"]},"jsonrpc":"2.0","id":157}'
DEBUG    2022-04-01 17:36:57,574 [1151:HttpServer] mopidy.http.handlers
  Sent WebSocket message to '
{"jsonrpc": "2.0", "id": 157, "result": {"local:track:The%20Dillinger%20Escape%20Plan%20-%20Irony%20Is%20a%20Dead%20Scene/01%20Hollywood%20Squares.mp3": 
   {"__model__": "Image", "uri": "/local/a921f26cb6abc4d2f663381e9773ba4e-475x475.jpeg", "width": 475, "height": 475},
   {"__model__": "Image", "uri": "/local/ab8593e54f1d852f6eb56da5bd200226-75x75.jpeg", "width": 75, "height": 75},
   {"__model__": "Image", "uri": "/local/e708e46d949dd83776c2ff2bf8aaa0cb-200x200.jpeg", "width": 200, "height": 200},
   {"__model__": "Image", "uri": "/local/dea1fecf261cf8d570b7498f102cdf9f-475x475.jpeg", "width": 475, "height": 475}

I can see the image now (after the last fix for mopidy-local). Must have been that it never got to that point during the scan.

Thank you.

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.