A lightweight macOS menu bar application that scrobbles your music to Last.fm and ListenBrainz.
- 🎵 Automatic Scrobbling - Scrobbles to Last.fm and/or ListenBrainz
- 🎯 macOS Native - Uses macOS Media Remote for universal media player support
- 🧹 Text Cleanup - Configurable regex patterns to clean track/album names (removes
[Explicit],[Clean], etc.) - 🔄 Multiple Services - Support for multiple ListenBrainz instances
- 📊 Menu Bar Integration - Lightweight menu bar icon showing current track
- ⚡ Efficient - Low resource usage, runs silently in background
- macOS 10.15 or later
- Rust toolchain (install from rustup.rs)
The easiest way to install OSX Scrobbler:
# Install the binary
cargo install osx-scrobbler
# Create a macOS app bundle in /Applications/
osx-scrobbler --install-appThat's it! The app will:
- ✅ Show only in menu bar (no dock icon)
- ✅ Run silently in the background
- ✅ Log to
~/Library/Logs/osx-scrobbler.log
To start at login: Add "OSX Scrobbler" to System Settings → General → Login Items
Note: If you get a permission error during installation, run with sudo:
sudo osx-scrobbler --install-appThe configuration file is located at:
~/Library/Application Support/osx_scrobbler.conf
A default configuration will be created automatically on first run.
# Polling interval in seconds
refresh_interval = 5
# Scrobble after playing this % of the track (or 4 minutes, whichever comes first)
scrobble_threshold = 50Remove unwanted tags from track/album/artist names before scrobbling:
[cleanup]
enabled = true
patterns = [
# Remove explicit/clean tags
"\\s*\\[Explicit\\]",
"\\s*\\[Clean\\]",
"\\s*\\(Explicit\\)",
"\\s*\\(Clean\\)",
"\\s*- Explicit",
"\\s*- Clean",
]Add custom patterns:
patterns = [
# ... default patterns ...
# Remove featuring artists
"\\s*\\(feat\\..*?\\)",
"\\s*\\(ft\\..*?\\)",
# Remove remastered tags
"\\s*-\\s*Remastered.*",
"\\s*\\(Remastered.*?\\)",
# Remove year tags
"\\s*\\(\\d{4}\\)",
]Patterns are standard regex and are applied in order. Remember to escape special characters with \\ in TOML.
Control which apps OSX Scrobbler listens to for scrobbling. When a new app starts playing music, you'll be prompted to allow or ignore it.
[app_filtering]
# Whether to prompt when encountering a new app
prompt_for_new_apps = true
# Whether to scrobble from apps that don't provide bundle_id
scrobble_unknown = true
# Apps to scrobble from (bundle IDs)
allowed_apps = [
"com.spotify.client",
"com.apple.Music"
]
# Apps to ignore (bundle IDs)
ignored_apps = [
"com.apple.Safari" # Don't scrobble YouTube in browser
]How it works:
- When music plays from a new app, a dialog will ask whether to allow or ignore scrobbling from that app
- Your choice is automatically saved to the config file
- You can manually edit
allowed_appsandignored_appslists - Apps without a bundle ID (rare) are controlled by the
scrobble_unknownsetting - Disable prompts by setting
prompt_for_new_apps = false
Common bundle IDs:
- Spotify:
com.spotify.client - Apple Music:
com.apple.Music - VLC:
org.videolan.vlc - Safari (for web players):
com.apple.Safari - Google Chrome:
com.google.Chrome
- Create a Last.fm API account: https://www.last.fm/api/account/create
- Note your API Key and API Secret
[lastfm]
enabled = true
api_key = "your_api_key_here"
api_secret = "your_api_secret_here"
session_key = "" # Leave empty initiallyRun the authentication helper:
osx-scrobbler --auth-lastfmThis will:
- Generate an authorization token
- Open a URL in your browser for you to authorize the app
- Automatically fetch and save the session key to your config
After authentication, your config will have the session_key filled in and enabled = true.
- Go to https://listenbrainz.org/profile/
- Log in or create an account
- Navigate to "User Settings" → "Music Services"
- Copy your User Token
[[listenbrainz]]
enabled = true
name = "Primary"
token = "your_listenbrainz_token"
api_url = "https://api.listenbrainz.org"You can scrobble to multiple ListenBrainz instances (e.g., self-hosted):
[[listenbrainz]]
enabled = true
name = "Primary"
token = "token_for_listenbrainz_org"
api_url = "https://api.listenbrainz.org"
[[listenbrainz]]
enabled = true
name = "Self-hosted"
token = "token_for_your_instance"
api_url = "https://your.instance.com"Simply run:
osx-scrobblerThe app will:
- Show a musical note icon in your menu bar
- Monitor your media players automatically
- Scrobble tracks when you've played 50% or 4 minutes (whichever comes first)
Click the menu bar icon to see:
- Now Playing - Currently playing track
- Last Scrobbled - Most recently scrobbled track
- Quit - Exit the application
# Show help
osx-scrobbler --help
# Show version
osx-scrobbler --version
# Install as macOS app bundle in /Applications/
osx-scrobbler --install-app
# Uninstall the app bundle from /Applications/
osx-scrobbler --uninstall-app
# Authenticate with Last.fm
osx-scrobbler --auth-lastfm
# Force console output (show logs in terminal even when not running from one)
osx-scrobbler --consoleThe app automatically detects how it's being run:
- From Terminal: Logs are shown in the terminal (stdout)
- From Spotlight/Finder: Logs are written to
~/Library/Logs/osx-scrobbler.log - Force Console Mode: Use
--consoleflag to always show logs in terminal
To view logs when running in background:
tail -f ~/Library/Logs/osx-scrobbler.logThe app follows Last.fm's scrobbling rules:
- Track must be at least 30 seconds long
- Scrobble submitted after:
- Playing 50% of the track duration, OR
- Playing for 4 minutes
- (whichever comes first)
- Each track is scrobbled only once per play session
- Pausing doesn't reset the scrobble timer
OSX Scrobbler works with any media player that integrates with macOS Media Remote, including:
- Apple Music / iTunes
- Spotify
- YouTube (in Safari/Chrome/Firefox)
- VLC
- IINA
- Swinsian
- And many more!
If it shows up in your macOS Control Center or Lock Screen, it will work with OSX Scrobbler.
- Check your config - Ensure
enabled = truefor at least one service - Verify credentials:
- Last.fm: Run
osx-scrobbler --auth-lastfmto re-authenticate - ListenBrainz: Verify your token at https://listenbrainz.org/profile/
- Last.fm: Run
- Check logs:
- From terminal:
RUST_LOG=debug osx-scrobbler --console - In background:
tail -f ~/Library/Logs/osx-scrobbler.log
- From terminal:
- Track length - Tracks under 30 seconds are not scrobbled
- Restart the app - Quit and relaunch the application
- Check permissions - macOS may require accessibility permissions
- Menu bar space - Ensure your menu bar isn't too crowded (try hiding other icons)
- Check config - Ensure
cleanup.enabled = true - Test patterns - Your regex patterns may have syntax errors (check logs for warnings)
- Pattern order - Patterns are applied in order; make sure they don't conflict
| Setting | Type | Default | Description |
|---|---|---|---|
refresh_interval |
integer | 5 |
How often (in seconds) to poll for now playing info |
scrobble_threshold |
integer | 50 |
Percentage of track to play before scrobbling (1-100) |
| Setting | Type | Default | Description |
|---|---|---|---|
cleanup.enabled |
boolean | true |
Enable text cleanup |
cleanup.patterns |
array of strings | See config | Regex patterns to remove from track names |
| Setting | Type | Required | Description |
|---|---|---|---|
lastfm.enabled |
boolean | Yes | Enable Last.fm scrobbling |
lastfm.api_key |
string | Yes | Your Last.fm API key |
lastfm.api_secret |
string | Yes | Your Last.fm API secret |
lastfm.session_key |
string | No* | Session key (obtained via --auth-lastfm) |
*Required for scrobbling, but obtained automatically via authentication
| Setting | Type | Required | Description |
|---|---|---|---|
listenbrainz.enabled |
boolean | Yes | Enable this ListenBrainz instance |
listenbrainz.name |
string | Yes | Friendly name for this instance |
listenbrainz.token |
string | Yes | Your ListenBrainz user token |
listenbrainz.api_url |
string | Yes | API URL (usually https://api.listenbrainz.org) |
git clone https://github.com/yourusername/osx-scrobbler.git
cd osx-scrobbler
cargo buildcargo runcargo testRUST_LOG=debug cargo runcargo clippyInspired by rescrobbled but built specifically for macOS using the media_remote crate.
Licensed under the Apache License, Version 2.0. See LICENSE for details.
Copyright 2026 OSX Scrobbler Contributors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Contributions are welcome! Please feel free to submit a Pull Request.
By contributing to this project, you agree that your contributions will be licensed under the Apache License, Version 2.0.