Getting Started/Discord RPC Plugin

To discuss development of addons / skins / customization of MediaMonkey.

Moderator: jiri

malkierian
Posts: 141
Joined: Wed May 10, 2017 1:38 pm

Getting Started/Discord RPC Plugin

Post by malkierian » Mon Jul 23, 2018 12:57 pm

OK, so I tried. I really did. I want to make a Discord rich presence plugin for MM5. It should technically be possible, they have 3rd-party JS extensions to interface. However, I just can't figure out how a MM5 script interfaces with MM5. There's no documentation on how to get a script started, and there's no common denominator that I can see looking at the examples in the Scripts folder. How does a script get started here?

TIV73
Posts: 96
Joined: Sat Nov 12, 2011 1:31 pm

Re: Getting Started/Discord RPC Plugin

Post by TIV73 » Wed Jul 25, 2018 5:11 pm

MM5 uses the chromium engine as frontend, so what you basically want to do is establish a remote session with chromium and use that to send javascript commands to MM. The best way I to do that (that I found so far) is via the chrome devtools protocol.

To get started, try the following:
- Start MM5
- Open http://localhost:9222/json in a browser
- In the results look for the entry with url 'file:///mainwindow.html' and copy the webSocketDebuggerUrl

That's the url you need to to interface with chromium. With that you can send js commands to MM.

Code: Select all

var ws = new WebSocket("ws://localhost:9222/devtools/page/[your-id-here]")

var request = {id:1,method:'Runtime.evaluate',params:{expression:'app.currentSkin()'}}

ws.addEventListener('open', function (event) {
    ws.send(JSON.stringify(request));
});

ws.addEventListener('message', function (event) {
    console.log("Result",event.data);
});

>> Result {"id":1,"result":{"result":{"type":"string","value":"Monkey Groove"}}}
There already are a ton of packages and wrappers on github that simplify the communication with chromium, but the example above should give you a rough idea over the steps involved. To get an idea of what commands are avaible for MM, you can either check out the API reference, or just open the developer console in MM (Ctrl+Shift+Alt) and and try out a couple of commands to see what they do.

I'm also currently in the process of rewriting MediaMonkeyNet, feel free to PM me if you need a working example (in C#) on how to communicate with MM.

malkierian
Posts: 141
Joined: Wed May 10, 2017 1:38 pm

Re: Getting Started/Discord RPC Plugin

Post by malkierian » Thu Jul 26, 2018 2:18 pm

Wait, so you're advocating not even using MM's built-in Script system, but using a third-party executable? Hmm. In some ways, that would make it easier, but I was hoping to do it internally. Well, at the very least, I could probably write that while waiting for someone else to tell me how to get started with scripts.

TIV73
Posts: 96
Joined: Sat Nov 12, 2011 1:31 pm

Re: Getting Started/Discord RPC Plugin

Post by TIV73 » Thu Jul 26, 2018 2:41 pm

I'm not sure I follow, there is no external application involved in my example. You use the API that's exposed by chromium (which is the frontend for mediamonkey) to issue javascript commands which is as native as it gets with MediaMonkey 5. You could run the same commands from within mediamonkey.

Addon (and script) development works pretty much exactly like it does for chrome because both chrome and MM run on the same engine.

malkierian
Posts: 141
Joined: Wed May 10, 2017 1:38 pm

Re: Getting Started/Discord RPC Plugin

Post by malkierian » Thu Jul 26, 2018 3:19 pm

Yeah, but you have to run what you're making separately from MM, right? That's external. Internal would be something you drop in MM's Scripts folder to run with MM, which is what all the documentation is about (and the "examples" they mention already in the Scripts folder).

TIV73
Posts: 96
Joined: Sat Nov 12, 2011 1:31 pm

Re: Getting Started/Discord RPC Plugin

Post by TIV73 » Thu Jul 26, 2018 4:05 pm

As long as it's a valid js command, MM shouldn't really care what process sent the request, it all goes through chromium one way or another - including requests made by chromium itself, e.g. when pressing a button in the MM gui. Anyway, I hacked together a quick example which illustrates how to pack a simple addon.

Simply extract the zip and drop the sampleFunction folder into your mm5 scripts directory. The next time you start mm there should be a new icon in the top right corner next to the search button. If you click the button while you have one or more songs selected, the addon will alert the titles of all selected tracks. You can also run actions.sampleFunction.execute() to start it.

malkierian
Posts: 141
Joined: Wed May 10, 2017 1:38 pm

Re: Getting Started/Discord RPC Plugin

Post by malkierian » Thu Jul 26, 2018 8:27 pm

I appreciate the effort you went to to show me how to use the Scripts folder. I will try both, to see which way is more applicable/efficient.

PetrCBR
Posts: 1640
Joined: Tue Mar 07, 2006 5:31 pm
Location: Czech
Contact:

Re: Getting Started/Discord RPC Plugin

Post by PetrCBR » Fri Jul 27, 2018 3:30 am

Basically ... every folder (or zip file) in Scripts folder is single script. Script can just override/extend any of ours files/classes and can run his code at MM startup. When you need to extend any of our files (typically actions.js where all basic actions are located), just add file with "_add" name addition (e.g. actions_add.js) and this file will be automatically included at the end of our file. Script can contain init.js which is called at MM startup so can be used to register toolbar button(s) etc. If you need to add your item in track popup menu (right-click on track in any tracklist), check controls/trackListView.js file for window.menus.createTracklistMenu method (and window.menus.tracklistMenuItems array) which is called everytime user raise right-click on track. Easiest way how to add your action(s) to that menu is add "controls/trackListView_add.js" file into your script and add your action(s) to window.menus.tracklistMenuItems array.

Code: Select all

window.menus.tracklistMenuItems.push(
    {
        action: actions.myAction,
        order: 10,
        grouporder: 10
    });
Using order and grouporder you can define where in the list your action will be added.

malkierian
Posts: 141
Joined: Wed May 10, 2017 1:38 pm

Re: Getting Started/Discord RPC Plugin

Post by malkierian » Sat Jul 28, 2018 8:00 pm

Thanks for that info, PetrCBR. Hopefully I can utilize it in a little while.

Just wanted to give an update, thanks to TIV73's MediaMonkeyNet, I was able to put together a C# utility that plugs into MM and feeds info to Discord:

https://i.imgur.com/sLU88VL.png

Unfortunately, they made the assumption that only games developers are going to want to use RPC, so this is as good as it will get until they decide to give us more extensibility/Spotify-like abilities through the API. I'm hoping I can figure out how to do this in JS so I can drop it in the scripts folder and have a setting for it in user preferences, but I have what I wanted for now, so that may be a while.

PetrCBR
Posts: 1640
Joined: Tue Mar 07, 2006 5:31 pm
Location: Czech
Contact:

Re: Getting Started/Discord RPC Plugin

Post by PetrCBR » Sun Jul 29, 2018 3:57 pm

Feel free to ask anything about MM5 script development.

malkierian
Posts: 141
Joined: Wed May 10, 2017 1:38 pm

Re: Getting Started/Discord RPC Plugin

Post by malkierian » Sun Jul 29, 2018 9:43 pm

Is there an event system? How would I tie into the play/pause/next/prev/etc functions? I would need to know when a track is paused, and when it plays (from whatever source, whether unpausing, going back or forward, or starting a new track through the media browser).

PetrCBR
Posts: 1640
Joined: Tue Mar 07, 2006 5:31 pm
Location: Czech
Contact:

Re: Getting Started/Discord RPC Plugin

Post by PetrCBR » Mon Jul 30, 2018 3:11 am

Check controls/player.js.
Our app.player object have event you need. For example:

Code: Select all

function _onPlaybackState(state) {
  switch (state) {
    case 'unpause': ...
    case 'play': ...
    case 'stop': ...
    case 'pause': ...
    case 'trackChanged': ...
  }
};
app.listen(app.player, 'playbackState', _onPlaybackState);

malkierian
Posts: 141
Joined: Wed May 10, 2017 1:38 pm

Re: Getting Started/Discord RPC Plugin

Post by malkierian » Mon Jul 30, 2018 1:08 pm

Awesome, thanks.

Next question. Is it possible to load third-party libraries in the scripts system? Right now, I have a couple nested requirements I'm trying to load, but they use "require" instead of "requirejs" or "localRequirejs", and I get the error "require is not defined" at startup. Am I going to have to go through each of the source files on there to change those things, or is there some other way I should be doing it?

PetrCBR
Posts: 1640
Joined: Tue Mar 07, 2006 5:31 pm
Location: Czech
Contact:

Re: Getting Started/Discord RPC Plugin

Post by PetrCBR » Mon Jul 30, 2018 2:18 pm

We're not using 3rd party modules. If you can, send me some of them and will try how to include (petr at mediamonkey dot com).

malkierian
Posts: 141
Joined: Wed May 10, 2017 1:38 pm

Re: Getting Started/Discord RPC Plugin

Post by malkierian » Mon Jul 30, 2018 2:56 pm

These are very specific to the Discord Rich Presence API. Only my addon would benefit from you including them in source. Which is why I asked about including them in the scripts folder.

Post Reply