beets icon indicating copy to clipboard operation
beets copied to clipboard

`replaygain` plugin hangs for a few minutes doing nothing, before actually generating tags

Open xbt573 opened this issue 1 year ago • 1 comments

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

xbt573 avatar Sep 30 '24 07:09 xbt573

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

xbt573 avatar Oct 16 '24 18:10 xbt573

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).

dschrempf avatar Apr 03 '25 17:04 dschrempf

(Probably) Related:

  • https://github.com/beetbox/beets/issues/5809
  • https://github.com/beetbox/beets/pull/5784

wisp3rwind avatar Jul 10 '25 09:07 wisp3rwind

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.

semohr avatar Jul 15 '25 11:07 semohr