{"id":46445259,"url":"https://github.com/lazykern/mprisence","last_synced_at":"2026-04-02T18:17:40.766Z","repository":{"id":177008619,"uuid":"658077114","full_name":"lazykern/mprisence","owner":"lazykern","description":" Highly customizable Discord Rich Presence for MPRIS media players on Linux","archived":false,"fork":false,"pushed_at":"2026-03-02T14:03:47.000Z","size":12613,"stargazers_count":78,"open_issues_count":3,"forks_count":6,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-04T16:58:01.857Z","etag":null,"topics":["discord","discord-rich-presence","mpris","rich-presence","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lazykern.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-06-24T17:36:10.000Z","updated_at":"2026-03-04T04:36:24.000Z","dependencies_parsed_at":"2024-03-09T05:29:01.629Z","dependency_job_id":"ac4acd33-28b6-414c-a0d0-8f556edfb857","html_url":"https://github.com/lazykern/mprisence","commit_stats":null,"previous_names":["phusitsom/mprisence","frokexec/mprisence","pulllazy/mprisence","lazykern/mprisence"],"tags_count":40,"template":false,"template_full_name":null,"purl":"pkg:github/lazykern/mprisence","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lazykern%2Fmprisence","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lazykern%2Fmprisence/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lazykern%2Fmprisence/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lazykern%2Fmprisence/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lazykern","download_url":"https://codeload.github.com/lazykern/mprisence/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lazykern%2Fmprisence/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30152957,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-05T21:15:50.531Z","status":"ssl_error","status_checked_at":"2026-03-05T21:15:11.173Z","response_time":93,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["discord","discord-rich-presence","mpris","rich-presence","rust"],"created_at":"2026-03-05T22:35:21.253Z","updated_at":"2026-04-02T18:17:40.750Z","avatar_url":"https://github.com/lazykern.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# mprisence\n\n[![AUR version](https://img.shields.io/aur/version/mprisence)](https://aur.archlinux.org/packages/mprisence)\n[![Nixpkgs](https://img.shields.io/badge/NixOS-nixpkgs-blue?logo=nixos)](https://search.nixos.org/packages?query=mprisence)\n\nHighly customizable Discord Rich Presence client for MPRIS media players. Supports VLC, MPV, RhythmBox, and many other Linux music and media players.\n\n\u003cimg src=\"/assets/example.gif\" width=\"548\" height=\"548\"/\u003e\n\n_(Note: Actual appearance depends on your configuration and the specific media player)_\n\n## Preconfigured Players\n\nReady to use with popular media players (configured in [`config.default.toml`](./config/config.default.toml)):\n\n- **Media Players**: VLC, MPV, Audacious, Elisa, Lollypop, Rhythmbox, CMUS, MPD, Musikcube, Clementine, Strawberry, Amberol, SMPlayer, Supersonic, Feishin, kew, Quod Libet, Euphonica\n- **Streaming**: YouTube Music, Spotify (disabled by default)\n- **Browsers** (disabled by default): Firefox, Zen, Chrome, Edge, Brave\n\nNote: MPD frontends (e.g., Euphonica) will also show MPD rich presence in Discord; you can disable the MPD entry in your config (see [Configuration Reference](#configuration-reference)\n\nFeel free to create a new issue if you want your player name+icon to be recognized by mprisence!\n\n## Features\n\n- **Works with any MPRIS player** (VLC, MPV, Rhythmbox, etc.)\n- **Template-driven presence (Handlebars)**: full control over details/state text, with helpers + conditionals\n- **Custom status display**: choose what Discord shows as your status (`name`, `state`, or `details`) — globally or per player\n- **Cover art**: uses metadata, local files, and online providers (with caching)\n- **Hot reload**: most config edits apply instantly (no restart)\n- **Smart activity type**: “Listening” / “Watching” / etc. based on content (configurable)\n- **Per-player overrides**: app IDs, icons, status, and more\n- **Rich metadata**: access detailed fields (including technical audio info) inside templates\n\n## Prerequisites\n\n- **For running:** A desktop environment with an active D-Bus session (standard on most Linux desktops).\n- **For service management:** `systemd` (user instance).\n- **For manual installation/building from source:**\n  - `rustc` and `cargo` (latest stable version recommended)\n  - `git` (to clone the repository)\n\n## Installation and Setup\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eExpand installation and setup steps\u003c/b\u003e\u003c/summary\u003e\n\n### Package Manager\n\n#### Arch Linux\n\n```bash\n# Install the stable version\nyay -S mprisence\n\n# Or, install the latest development version\nyay -S mprisence-git\n\n# Or without building from source\nyay -S mprisence-bin\n```\n\n#### Nix (NixOS, Linux)\n\nAvailable in `nixpkgs`\n\n```bash\n# without flakes:\nnix-env -iA nixpkgs.mprisence\n\n# with flakes:\nnix profile install nixpkgs#mprisence\n```\n\nNixOS configuration:\n\n```nix\nenvironment.systemPackages = [ pkgs.mprisence ];\n```\n\n#### Debian, Ubuntu, and derivatives\n\nDownload the `.deb` package from the [**GitHub Releases page**](https://github.com/lazykern/mprisence/releases) and install it:\n\n```bash\nsudo dpkg -i /path/to/mprisence_*.deb\n```\n\n### Manual Installation\n\nThis method is for other Linux distributions, or if you prefer to install from source or crates.io. It requires a few manual setup steps.\n\n#### Step 1: Install the `mprisence` binary\n\nChoose **one** of the following ways to get the executable:\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eOption A: From Crates.io (requires Rust)\u003c/b\u003e\u003c/summary\u003e\n\n```bash\ncargo install mprisence\n```\n\nThis will install the binary to `~/.cargo/bin/`. Ensure this directory is in your `$PATH`.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eOption B: From GitHub Releases (pre-compiled)\u003c/b\u003e\u003c/summary\u003e\n\nDownload the `...-unknown-linux-gnu.tar.gz` archive from the [**GitHub Releases page**](https://github.com/lazykern/mprisence/releases). Extract it, and place the `mprisence` binary in a directory included in your system's `$PATH` (e.g., `~/.local/bin` or `/usr/local/bin`).\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eOption C: From Source (for development)\u003c/b\u003e\u003c/summary\u003e\n\n```bash\n# Clone the repository\ngit clone https://github.com/lazykern/mprisence.git\ncd mprisence\n\n# Install from local source\ncargo install --path .\n```\n\nThis also installs the binary to `~/.cargo/bin/`.\n\n\u003c/details\u003e\n\n#### Step 2: Set up Configuration\n\n`mprisence` looks for its configuration at `~/.config/mprisence/config.toml`.\n\n1. **Create the configuration directory:**\n\n   ```bash\n   mkdir -p ~/.config/mprisence\n   ```\n\n2. **Download the example configuration:**\n\n   ```bash\n   curl -o ~/.config/mprisence/config.toml https://raw.githubusercontent.com/lazykern/mprisence/main/config/config.example.toml\n   ```\n\n   Now you can edit this file to customize mprisence. See the [Configuration Reference](#configuration-reference) section for more details.\n\n#### Step 3: Set up and Run the Service\n\nTo have `mprisence` start automatically on login, set up the systemd user service.\n\n1. **Create the systemd user directory if it doesn't exist:**\n\n   ```bash\n   mkdir -p ~/.config/systemd/user\n   ```\n\n2. **Download the service file:**\n   The provided service file is configured to find the `mprisence` binary in `~/.cargo/bin/`.\n\n   ```bash\n   curl -o ~/.config/systemd/user/mprisence.service https://raw.githubusercontent.com/lazykern/mprisence/main/mprisence.service\n   ```\n\n   \u003e **Note:** If you placed the binary in a different location (e.g., `/usr/local/bin`), you must edit `~/.config/systemd/user/mprisence.service` and change the `ExecStart` path.\n\n3. **Enable and start the service:**\n\n   ```bash\n   systemctl --user enable --now mprisence\n   ```\n\n   This command enables `mprisence` to start at login and starts it immediately.\n\n### Managing the Service\n\nOnce the service is installed (either manually or via a package), you can manage it using `systemctl --user`:\n\n```bash\n# Check service status\nsystemctl --user status mprisence\n\n# Restart the service after changing the config\nsystemctl --user restart mprisence\n\n# View detailed logs\njournalctl --user -u mprisence -f\n\n# Stop and disable the service\nsystemctl --user disable --now mprisence\n```\n\n\u003c/details\u003e\n\n## Configuration\n\n`mprisence` is highly configurable via `~/.config/mprisence/config.toml` (or `$XDG_CONFIG_HOME/mprisence/config.toml`).\n\nAfter following the installation steps, you can modify `~/.config/mprisence/config.toml` to your liking. The application will hot-reload most configuration changes automatically.\n\n### Local Album Covers\n\nmprisence will first attempt to find cover art from MusicBrainz. If it's not found, it can re-host local cover art through Catbox (no key required) or ImgBB (requires an API key).\n\nUpdate the provider order to include whichever host you prefer (e.g., `[\"musicbrainz\", \"catbox\", \"imgbb\"]`, `[\"catbox\"]`, etc.).\n\n**Catbox (no key required)**\n\n```toml\n[cover.provider]\nprovider = [\"catbox\"]\n\n[cover.provider.catbox]\n# user_hash = \"your_user_hash\" # optional: lets you delete uploads later\nuse_litter = false            # true -\u003e upload to Litterbox instead of permanent Catbox storage\nlitter_hours = 24             # valid values: 1, 12, 24, 72\n```\n\n**ImgBB (API key required)**\n\n```toml\n[cover.provider]\nprovider = [\"imgbb\"]\n\n[cover.provider.imgbb]\napi_key = \"YOUR_API_KEY_HERE\"\n```\n\nNotes:\n\n- Clear cache: `rm -rf ~/.cache/mprisence/cover_art`.\n- Authenticated/self-hosted art URLs from players like Feishin (Subsonic/OpenSubsonic/Navidrome/Jellyfin API image routes) are treated as source input and re-hosted via your configured providers instead of being cached as direct Discord URLs.\n\n### Custom Status Display\n\nUse `status_display_type` to control which text Discord shows in your status.\n\n| `status_display_type`                                                                 | Preview                                                     |\n| ------------------------------------------------------------------------------------- | ----------------------------------------------------------- |\n| `name`: shows the player/app name in your status                                      | ![Status display type name](./assets/status_name.png)       |\n| `state`: shows the rendered `template.state` value (default template shows artist(s)) | ![Status display type state](./assets/status_state.png)     |\n| `details`: shows the rendered `template.details` value (default template shows title) | ![Status display type details](./assets/status_details.png) |\n\nSet a global default in `[player.default]`, then override per player only when needed.\n\n```toml\n# Global default for all players\n[player.default]\nstatus_display_type = \"name\" # name | state | details\n\n# Optional per-player override (this one only affects VLC)\n[player.vlc_media_player]\nstatus_display_type = \"details\"\n```\n\n### Configuration Reference\n\n- [`config.example.toml`](./config/config.example.toml): Detailed options and explanations.\n- [`config.default.toml`](./config/config.default.toml): Default configurations for popular players.\n- [`src/metadata.rs`](./src/metadata.rs): Definitive source for all available template variables.\n\n---\n\n\u003cdetails\u003e\n\u003csummary\u003eBasic Configuration Example\u003c/summary\u003e\n\n```toml\n# Basic settings\n# Whether to clear Discord activity when media is paused\nclear_on_pause = true\n\n# How often to update Discord presence (in milliseconds)\ninterval = 2000\n\n# Restrict discovery to specific players (identities, wildcards, or regex).\n# Matches against player identity or the bus-name \"player\" part (e.g., \"vlc\"),\n# not the full D-Bus name. Leave empty to allow all players.\nallowed_players = []\n\n# Note: Triple braces `{{{variable}}}` are used to prevent HTML escaping,\n# which is generally desired for Discord presence fields.\n# See: https://handlebarsjs.com/guide/#html-escaping\n# Extra helpers: `eq`, `contains`, `icontains`, `regex_is_match`, and `regex_captures`\n\n# Display template\n[template]\n# First line in Discord presence\ndetails = \"{{{title}}}\"\n\n# Second line in Discord presence - using Handlebars array iteration\nstate = \"{{#each artists}}{{this}}{{#unless @last}} \u0026 {{/unless}}{{/each}}\"\n# or just use\n# state = \"{{{artist_display}}}\"\n\n# Text shown when hovering over the large image - using conditional helpers\nlarge_text = \"{{#if album}}{{{album}}}{{#if year}} ({{{year}}}){{/if}}{{/if}}\"\n\n# Text shown when hovering over the small image (player icon)\n# Only visible when show_icon = true in player settings\nsmall_text = \"{{#if player}}{{{player}}}{{else}}MPRIS{{/if}}\"\n\n# Match substrings or regex patterns in helpers\n# details = \"{{#if (contains player \\\"Spotify\\\")}}{{{title}}}{{else}}{{{player}}}{{/if}}\"\n# details = \"{{#if (icontains player \\\"spotify\\\")}}{{{title}}}{{else}}{{{player}}}{{/if}}\"\n# small_text = \"{{#if (regex_is_match pattern=\\\"^(mpv|vlc)$\\\" on=player_bus_name)}}Video{{else}}Audio{{/if}}\"\n\n# Activity type settings\n[activity_type]\n# Auto-detect type (audio -\u003e \"listening\", video -\u003e \"watching\")\nuse_content_type = true\n# Default type: \"listening\", \"watching\", \"playing\", or \"competing\"\ndefault = \"listening\"\n\n# Time display settings\n[time]\n# Show progress bar/time in Discord\nshow = true\n# true = show elapsed time, false = show remaining time\nas_elapsed = true\n```\n\n\u003c/details\u003e\n\n---\n\n\u003cdetails\u003e\n\u003csummary\u003eCover Art Setup\u003c/summary\u003e\n\n```toml\n[cover]\n# File names (without extension) to search for local art (e.g., cover.jpg, folder.png)\nfile_names = [\"cover\", \"folder\", \"front\", \"album\", \"art\"]\n# How many parent directories to search upwards for local art (0 = same dir only)\nlocal_search_depth = 2\n\n[cover.provider]\n# Cover art providers in order of preference\n# (catbox will be used as a fallback if musicbrainz fails or local art isn't found)\nprovider = [\"musicbrainz\", \"catbox\"] # Also checks local files first based on above\n\n[cover.provider.musicbrainz]\n# Minimum score (0-100) for MusicBrainz matches. Higher = stricter.\nmin_score = 100\n\n[cover.provider.catbox]\n# user_hash = \"your_user_hash\" # optional: lets you delete uploads later\nuse_litter = false            # true -\u003e upload to Litterbox instead of permanent Catbox storage\nlitter_hours = 24             # valid values: 1, 12, 24, 72\n\n[cover.provider.imgbb]\n# Your ImgBB API key (get one at: https://api.imgbb.com/)\napi_key = \"YOUR_API_KEY_HERE\"\n# How long to keep uploaded images (in seconds, default: 1 day)\nexpiration = 86400\n```\n\n\u003c/details\u003e\n\n---\n\n\u003cdetails\u003e\n\u003csummary\u003ePlayer-Specific Configuration\u003c/summary\u003e\n\n```toml\n# Use 'mprisence players list' to get the correct player identity (e.g., vlc_media_player)\n\n# Default settings applied to ALL players unless overridden below\n[player.default]\nignore = false # Set to true to disable presence for all players by default\napp_id = \"1121632048155742288\" # Default Discord Application ID\nicon = \"https://raw.githubusercontent.com/lazykern/mprisence/main/assets/icon.png\" # Default icon URL\nshow_icon = false # Show player icon as small image by default?\nallow_streaming = false # Allow HTTP/HTTPS streaming content? False clears Discord activity for those players.\nstatus_display_type = \"name\" # Controls which text Discord shows in your status.\n                              # For example:\n                              # \"name\"    -\u003e Player/app name\n                              # \"state\"   -\u003e Rendered template.state value (default: \"{{{artists}}}\")\n                              # \"details\" -\u003e Rendered template.details value (default: \"{{{title}}}\")\n\n# Override settings for a specific player (VLC in this example)\n[player.vlc_media_player]\n# You can override any key from [player.default] here\napp_id = \"YOUR_VLC_APP_ID_HERE\" # Use a VLC-specific Discord App ID\nicon = \"https://example.com/vlc-icon.png\" # Use a VLC-specific icon\nshow_icon = true # Show the VLC icon\nallow_streaming = true # Allow streaming content for VLC\n# You could also add 'override_activity_type = \"watching\"' here if desired\nstatus_display_type = \"details\"\n\n# Example: Ignore Spotify\n# [player.spotify]\n# ignore = true\n\n# Example: Wildcard matches\n[player.\"*youtube_music*\"]\nshow_icon = true\nallow_streaming = true\n```\n\nWhen `allow_streaming` is `false`, mprisence will skip HTTP/HTTPS sources for that player and clear any previously published Discord activity so browsers stay hidden unless explicitly enabled.\n\n\u003c/details\u003e\n\nPlayer config priority: user entries always override bundled ones. The resolver tries user exact \u003e user regex \u003e user wildcard \u003e bundled exact \u003e bundled regex \u003e bundled wildcard; any field left unset on a higher-priority match is filled from the next match down, falling back to `[player.default]` (user, then bundled) and finally built-in defaults. When identity and bus-name differ (for example with proxies like `playerctld`), an exact user bus-name entry wins over identity-derived matches.\n\n## CLI Commands\n\n```bash\n# Get help\nmprisence --help\n\n# Run without system service\nmprisence\n\n# List available MPRIS players\nmprisence players list\n\n# Show detailed player information including metadata and config\nmprisence players list --detailed\n\n# Show current configuration\nmprisence config\n\n# Show version\nmprisence version\n\n# Enable more verbose logging\nRUST_LOG=debug mprisence # or RUST_LOG=trace mprisence\n```\n\n## Troubleshooting\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eExpand troubleshooting tips\u003c/b\u003e\u003c/summary\u003e\n\n### Common Issues\n\n1. **Discord Presence Not Showing / Updating**\n   - **Is your player running and MPRIS-compatible?** Run `mprisence players list` to see detectable players.\n   - **Is the service running?** `systemctl --user status mprisence`\n   - **Discord Settings:** Check `Discord Settings -\u003e Registered Games / Activity Privacy`. Ensure `Display current activity as a status message.` is ON. Sometimes toggling this off and on helps. Add `mprisence` if it's not listed.\n   - **Correct App ID?** Verify the `app_id` in your config matches a valid Discord application ID.\n   - **Using Vesktop Flatpak?** Set up the Discord IPC symlink as described in the Vesktop Flatpak guide: [Native applications](https://github.com/flathub/dev.vencord.Vesktop?tab=readme-ov-file#native-applications).\n   - **Logs:** Check `journalctl --user -u mprisence -f` or run `RUST_LOG=debug mprisence` for errors.\n\n2. **Cover Art Not Displaying**\n   - **Check the logs:** Run with `RUST_LOG=debug mprisence` to see the cover art process.\n   - **Provider Order:** Cover art is checked in this order: Cache -\u003e Direct URL (from metadata) -\u003e Local Files -\u003e Configured Providers (e.g., MusicBrainz, ImgBB).\n   - **MusicBrainz:** Does the track metadata (title, artist, album) accurately match the MusicBrainz database? Check the `min_score` in your config.\n   - **ImgBB:**\n     - Is a local file available (embedded or matching `file_names` in the folder/parent folders)? ImgBB is primarily used to _upload_ local art.\n     - Is your `api_key` in `[cover.provider.imgbb]` correct and valid?\n     - Is the image file format supported and readable?\n   - **Cache:** Try clearing the cache (`rm -rf ~/.cache/mprisence/cover_art`) if you suspect stale entries.\n\n3. **Service Issues**\n   - Use the commands mentioned in the [Autostarting / Service Management](#autostarting--service-management) section to check status (`status`), view logs (`journalctl`), and manage the service (`start`, `stop`, `restart`).\n\n4. **Configuration Issues**\n   _**Syntax Errors:** Validate your `config.toml` using an online TOML validator or `toml-lint`.\n   _ **Defaults:** If unsure, temporarily remove your `~/.config/mprisence/config.toml` to test with the built-in defaults.\n\n\u003c/details\u003e\n\n## Contributing\n\nContributions are welcome! Please feel free to open an issue to report bugs, suggest features, or discuss changes. If you'd like to contribute code, please open a pull request.\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flazykern%2Fmprisence","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flazykern%2Fmprisence","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flazykern%2Fmprisence/lists"}