`replaygain` plugin hangs for a few minutes doing nothing, before actually generating tags
Problem
Command that generates replay gain tags hangs after this log for a couple of minutes:
Parsed query: AndQuery([TrueQuery()])
Parsed sort: NullSort()
Running this command in verbose (-vv) mode:
$ beet -vv replaygain -t 10 -w
user configuration: /home/xbt573/.config/beets/config.yaml
data directory: /home/xbt573/.config/beets
plugin paths:
fetchart: google: Disabling art source due to missing key
fetchart: lastfm: Disabling art source due to missing key
Sending event: pluginload
library database: /media/hdd/subsonic/beets.db
library directory: /media/hdd/subsonic/music
Sending event: library_opened
Parsed query: AndQuery([TrueQuery()])
Parsed sort: NullSort()
... 1-2 minutes of no output ...
-- log of successful replay gain generation --
Setup
- OS: Fedora Linux 40
- Python version: 3.12.6
- beets version: 2.0.0 (installed from pipx)
- Turning off plugins made problem go away (yes/no): no
My configuration (output of beet config) is:
lyrics:
bing_lang_from: []
sources: lrclib genius
synced: yes
fallback: ''
auto: yes
bing_client_secret: REDACTED
bing_lang_to:
google_API_key: REDACTED
google_engine_ID: REDACTED
genius_api_key: REDACTED
force: no
local: no
dist_thresh: 0.1
directory: /media/hdd/subsonic/music
# --------------- Main ---------------
library: /media/hdd/subsonic/beets.db
# --------------- Plugins ---------------
plugins: lyrics lastgenre fetchart embedart replaygain
paths:
default: $albumartist/$album%aunique{}/$track. $title
lastgenre:
fallback: yes
whitelist: yes
min_weight: 10
count: 1
canonical: no
source: album
force: yes
auto: yes
separator: ', '
prefer_specific: no
title_case: yes
fetchart:
maxwidth: 1200
auto: yes
minwidth: 0
quality: 0
max_filesize: 0
enforce_ratio: no
cautious: no
cover_names:
- cover
- front
- art
- album
- folder
sources:
- filesystem
- coverart
- itunes
- amazon
- albumart
- cover_art_url
store_source: no
high_resolution: no
deinterlace: no
cover_format:
google_key: REDACTED
google_engine: 001442825323518660753:hrh5ch1gjzm
fanarttv_key: REDACTED
lastfm_key: REDACTED
replaygain:
auto: no
backend: ffmpeg
overwrite: no
threads: 20
parallel_on_import: no
per_disc: no
peak: 'true'
targetlevel: 89
r128: [Opus]
r128_targetlevel: 84
replace:
'[\\/]': _
^\.: _
'[\x00-\x1f]': _
\s+$: ''
^\s+: ''
from_scratch: yes
embedart:
maxwidth: 0
auto: yes
compare_threshold: 0
ifempty: no
remove_art_file: no
quality: 0
Some debugging led me to conclusion that slowdown is caused because of database, it happens on beets/dbcore/db.py:1246
Argument that enables matching by album makes this a lot faster
I am also observing this. beet is using 100CPU for hours, the replaygain command (aacgain in my case) does not run. (At some point it did run, but only for a small part of the library).
(Probably) Related:
- https://github.com/beetbox/beets/issues/5809
- https://github.com/beetbox/beets/pull/5784
I just took a look at the replaygain plugin, as it was mentioned in the performance issue I raised earlier and I can confirm they are related!
The replaygain plugin iterates all albums in an outer loop and than all items in an inner loop. This matches exactly the benchmark I shared in the issue. If you add the indexes as described in #5809, you should definitely see noticeable improvements (depending on your database size n as this lookup now scales with O(log n) instead of an O(n))
From a quick scan of the code, it also looks straightforward to add a progress bar. That could help users identify slowdowns or bottlenecks during processing.