Skip to main content

listenbrainz-scrobbler

CI PyPI Python Platform

Automatically submit Apple Music listens on macOS to ListenBrainz, including streamed songs outside your library.

Setup

On macOS, install uv, then install the PyPI package with Python 3.13:

uv tool install --python 3.13 listenbrainz-scrobbler
lb-scrobbler install --dry-run
lb-scrobbler status

If uv reports that its executable directory is missing from PATH, run uv tool update-shell and restart your shell. For a declaratively managed service, use Nix / Home Manager.

Play a song and allow the background Python process to control Music when macOS asks. Check status for fresh observations and an advancing playback position. If access is denied, enable it in System Settings → Privacy & Security → Automation, then reinstall the agent. A successful foreground probe may still require a separate permission for the background service.

After the dry run works, quit other scrobblers to avoid duplicate submissions. Save your ListenBrainz token in the login Keychain:

lb-scrobbler auth
lb-scrobbler install

For an existing SmashTunes setup, lb-scrobbler auth --from-smashtunes explicitly transfers its stored ListenBrainz token into this service's Keychain entry after validating it. Neither command prints the token. Do not put tokens in command arguments, project files, or Git.

install starts the service immediately and at future logins. Keep the uv tool installation in place: the service depends on its Python environment. Avoid installing the service through temporary uvx environments. Python upgrades may require fresh macOS Automation or Keychain consent.

To upgrade, restart the agent against the updated tool environment:

lb-scrobbler stop
uv tool upgrade listenbrainz-scrobbler
lb-scrobbler install

Operation

lb-scrobbler probe       # Read Music without submitting
lb-scrobbler status      # Last observation and submission queue
lb-scrobbler stop        # Stop until reinstalled or the next login
lb-scrobbler uninstall   # Remove the launch agent
lb-scrobbler retry       # Retry retained failures after fixing their cause

lb-scrobbler run --dry-run runs in the foreground. Stop the LaunchAgent first, since only one process may own the playback tracker.

State and logs live in ~/Library/Application Support/listenbrainz-scrobbler/. Queued listens are stored there with user-only permissions. The submission token is held separately in login Keychain under xyz.hakula.listenbrainz-scrobbler. Uninstalling the agent preserves both the queue and Keychain entry.

The current song appears on ListenBrainz as soon as playback is observed. Pausing or stopping playback clears this service's playing-now notification. These temporary updates are not saved as listening history and are discarded when playback changes. If the service is stopped or offline, an existing notification remains until ListenBrainz expires it.

A listen is submitted after observing half a track or four minutes of playback, whichever comes first, following ListenBrainz's submission rule. Pauses, seeks, and observation gaps longer than ten seconds do not contribute listening time. Starting the service halfway through a song does not credit playback it did not observe.

Failed submissions stay queued with their original timestamps. Network and server errors are retried automatically. Inspect other failures with status, fix their cause, then run retry. After changing the token, restart the agent. For a manual installation, run lb-scrobbler install. A crash during submission can occasionally cause a duplicate listen.

Dry runs never submit listens.

Limits

Only playback observed on this Mac is captured. There is no history import or iPhone synchronization.

Polling cannot distinguish a natural repeat from manually seeking from the very end to the very beginning. It also cannot identify different recordings with identical title, artist, and album metadata. Track-start timestamps are estimated from the observed position, so seeking before the first observation can skew that estimate. Missing metadata is skipped.

Nix / Home Manager

Add a versioned flake input such as github:hakula139/listenbrainz-scrobbler/v0.2.0, then import the module in your Home Manager configuration:

imports = [ inputs.listenbrainz-scrobbler.homeManagerModules.default ];
services.listenbrainz-scrobbler.enable = true;

Home Manager replaces the manual installer's LaunchAgent under the same label while preserving the queue and Keychain token. Activate Home Manager, then check lb-scrobbler status to confirm the agent loaded and observations are fresh. The package path changes, so macOS may request Automation or Keychain access again. Use lb-scrobbler auth if no token is stored yet.

The LaunchAgent starts at user login after a reboot, when Music and the login Keychain are available. Home Manager owns its lifecycle after migration, so use it for configuration changes instead of the manual install and uninstall commands. After changing the token, restart the loaded agent with launchctl kickstart -k "gui/$(id -u)/xyz.hakula.listenbrainz-scrobbler". Disable the module and reactivate Home Manager to remove it. The existing Keychain entry keeps credentials outside the Nix store.

See the changelog for release changes. GitHub releases also provide wheels, source archives, and checksums.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

listenbrainz_scrobbler-0.2.0.tar.gz (66.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

listenbrainz_scrobbler-0.2.0-py3-none-any.whl (16.7 kB view details)

Uploaded Python 3

File details

Details for the file listenbrainz_scrobbler-0.2.0.tar.gz.

File metadata

  • Download URL: listenbrainz_scrobbler-0.2.0.tar.gz
  • Upload date:
  • Size: 66.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.13 {"installer":{"name":"uv","version":"0.12.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for listenbrainz_scrobbler-0.2.0.tar.gz
Algorithm Hash digest
SHA256 2d56aa39d1fa3f150e3ba1b95cd2989d3335d882dc1bbd223cc0e85a2fbe9ac3
MD5 11b9b9c4b1f7dd9ddb50c9c3c9120301
BLAKE2b-256 2dcee3ad256131ea6d94ea0d70db71a359bf9f12ad480c6acec23708d8470294

See more details on using hashes here.

File details

Details for the file listenbrainz_scrobbler-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: listenbrainz_scrobbler-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 16.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.13 {"installer":{"name":"uv","version":"0.12.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for listenbrainz_scrobbler-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e504fd157754ca60123ea9b0cff982e0127bf1121264d38617dcfe67211bb373
MD5 1c7dc0b47e01444d9173b9bf1b8360ba
BLAKE2b-256 6402a8695f21624f98dc3883e76d77675661d34008d40d26b67135684da9cdf1

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 files

0.1.1

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page