You are browsing as a guest. Sign up (or log in) to start making projects!

Vencord ListenBrainz RPC

  • 1 Devlogs
  • 5 Total hours

šŸŽ§ adding ListenBrainz "Now Listening" Rich Presence to Vencord~ pull request here: https://github.com/Vendicated/Vencord/pull/4077

Ship #1 Changes requested

This is (somewhat) done—there’s still an unresolved code smell, check the PR for details. I’m going to ship this now for the Free Stickerā„¢, but stay tuned for the merge :)

Alternatively, reviewers, don’t approve this until it gets merged. That’s fine with me too!

To install this, clone the repository at the source code link below ā¬‡ļø, then pnpm build. Follow the Vencord docs @ installing your custom build to install! Then, go to Settings -> Plugins -> AudioScrobblerRichPresence, open the plugin settings, and configure as needed :)

  • 1 devlog
  • 5h
Try project → See source code →
Open comments for this post

5h 29m 45s logged

for more info check out the pull request thread

ListenBrainz Rich Presence in Vencord!

I’ve always been a fan of tools that track your listening activity. Last.FM is a website that does exactly that! Vencord—a client mod for Discord—included a plugin that showed your Last.FM ā€œNow Playingā€ as a Rich Presence activity, and I used that for a while. However, I grew increasingly dissatisfied with how Last.FM handled metadata, which is to say, it didn’t. There would be like, five different entries for one song, six for one artist, and so on and so forth. Also, oftentimes Last.FM wouldn’t associate albums with tracks—that meant the track would have no album art, and it was really annoying to see a placeholder image show up on your Discord profile. The solution…?

ListenBrainz! A scrobbler application made by the same organization responsible for MusicBrainz, the database on everything song metadata. However, using ListenBrainz instead of Last.FM meant that I wouldn’t have my currently playing song show up on my Discord profile. Which obviously meant I gave up.

Just kidding, I wrote my own plugin: ListenBrainz Rich Presence for Vencord. That isn’t part of my Stardance time though, I wrote that janky mess all the way back in March. I submitted this plugin as a pull request to the Vencord repository, only to get this response:

Vendicated: Please merge this into the lastfm rpc plugin to avoid duplicating code

And I said, sure, I can do that—then proceeded to forget all about this project for a whole month. This week, Vendicated bumped the thread, asking whether I was gonna actually do it, and that’s where our story actually starts.

The idea: a unified scrobbler plugin (obviously) that accepts a variety of different backends for its status. Last.FM and ListenBrainz would be separate backends that the user could choose from. I would also make the whole fetching metadata feature a separate thing that the user could access from either backend, using MusicBrainz instead of the ListenBrainz lookup API (which requires a token now because of AI abuse.)

Here’s the thing, though—I thought I would make the backend selection an enum. However, a backend tends to be more of an object than just a string—it’s got an ID, a name, a website, and tons of other properties that all have to be expressed. My initial implementation was janky as shit:

interface ScrobblerBackend {
    name: string,
    id: string,
    url: string,
    userProfilePath: string;
}

const ScrobblerBackends: Map<string, ScrobblerBackend> = new Map([
    [
        "lastfm",
        {
            name: "Last.FM",
            id: "lastfm",
            url: "https://www.last.fm/",
            userProfilePath: "/user"
        }
    ],
    [
        "listenbrainz",
        {
            name: "ListenBrainz",
            id: "listenbrainz",
            url: "https://listenbrainz.org/",
            userProfilePath: "/user"
        }
    ]
]);

what the hell dawg 😭

This is partially attributed to my fairly weak understanding of TypeScript as it relates to object-oriented programming—I didn’t know how classes and inheritance actually worked. I learned OOP in Java and C#, okay 😭 this was all still kinda new to me!

Obviously Vendicated caught and corrected me real quick there, and I learned that yes, inheritance is a thing. Classes can inherit interfaces. Isn’t that crazy.

We construct this interface…

export interface ScrobblerBackend {
    name: string,
    id: string,
    url: string,

    fetchTrackData(username: string, apiKey?: string): Promise<TrackData | null>;
    getUserURL(username: string): string;
}

…and then we do export class ListenBrainzScrobbler implements ScrobblerBackend. Woohoo. Yippee.

0
0
3

Delete project?

Are you sure you want to permanently delete this project? This action cannot be undone.

All devlogs, followers, and associated data will be removed.

Followers

Loading…