Standalone scrobbler program, not a continuously running process, written in Python 3 that works together with cmus. Allows offline mode, scrobbling multiple servers simultaneously, sending a now playing request and handles pause status well.
  • Python 99.3%
  • Makefile 0.7%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Vjeran Crnjak 37376e66d9
All checks were successful
ci / Python 3.10 (push) Successful in 32s
ci / Python 3.11 (push) Successful in 31s
ci / Python 3.12 (push) Successful in 33s
ci / Python 3.13 (push) Successful in 33s
ci / Python 3.9 (push) Successful in 32s
bugfix: paused track needs to use earliest start_time
* using start_time of latest status creates chances for dropping on
  server,
* added tests which demonstrate the failure,
* rewritten the calculate_scrobbles loop to handle all previous tests
  and the new edge case,
* added additional hardening e2e tests.
2026-09-24 09:22:47 +02:00
.forgejo/workflows Use the shared checkout action in Forgejo CI 2026-09-23 14:39:11 +02:00
.github Type safety rewrite with e2e tests (#17) 2026-01-11 11:03:41 +01:00
.gitignore update .gitignore 2021-05-10 23:53:13 +02:00
.style.yapf add ugly style 2025-06-16 08:44:17 +02:00
cmus_status_scrobbler.ini now_playing no longer results in duplicate scrobbles on ListenBrainz 2023-05-12 08:55:41 +02:00
cmus_status_scrobbler.py bugfix: paused track needs to use earliest start_time 2026-09-24 09:22:47 +02:00
LICENSE Initial commit 2021-05-16 22:29:09 +02:00
Makefile Type safety rewrite with e2e tests (#17) 2026-01-11 11:03:41 +01:00
README.md Add Forgejo Actions test coverage 2026-09-23 14:33:25 +02:00
requirements-dev.txt Type safety rewrite with e2e tests (#17) 2026-01-11 11:03:41 +01:00
test_cmus_status_scrobbler.py bugfix: paused track needs to use earliest start_time 2026-09-24 09:22:47 +02:00
tests.py bugfix: paused track needs to use earliest start_time 2026-09-24 09:22:47 +02:00

cmus-status-scrobbler

tests passing status Forgejo checks

Works with cmus. Requires Python 3.9+ and has no additional dependencies.

Features:

  • offline mode,
  • multiple servers,
  • now playing request,
  • uses MusicBrainz id if present,
  • handles pause status well and
  • is a short-lived program (not a continuously running process).

How to use?

Leave cmus_status_scrobbler.ini file as is after removing servers you don't use.

  1. Call the program with --auth option and follow instructions.
  2. After authenticating with services, cmus_status_scrobbler.ini file is edited and saved with new credentials.
  3. Set cmus_status_scrobbler.py as your only status display program by invoking :set status_display_program=path/to/cmus_status_scrobbler.py in cmus or add it to your existing script for cmus.

Bash script example:

# some other display programs
cmus_status_scrobbler.py "$@" &
# more display programs

Termux

https://github.com/vjeranc/cmus-status-scrobbler/issues/10#issuecomment-1970103562 Make sure to run chmod +rx status_display_program.sh (or chmod +rx cmus_status_scrobbler.py) before :set status_display_program=....

Arch Linux (AUR)

https://aur.archlinux.org/packages/cmus-status-scrobbler-git

Configuration

Example file cmus_status_scrobbler.ini is in the repository.

It is assumed that this configuration file is stored in ~/.config/cmus/ directory. You can configure db_path and other options if you do not like the defaults.

Delete the block for the service that you aren't using.

Handling pause

Pausing a track will not make it scrobble. Continuing the paused track and finishing or stopping it will result in a scrobble if new playing time and playing time before pause satisfy the scrobble requirement (playing time >= 50% of track duration or at least 4 minutes).

Implementation details

Uses sqlite3 to support offline mode and to synchronize the processes in case of multiple status updates (like holding the pause/play button too long).

My own usage

I use this Python script to scrobble to librefm, lastfm, listenbrainz and my own family scrobbling service.