mm5 Fast Rate and skip

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

Moderators: jiri, drakinite, Addon Administrators

ddowdle
Posts: 4
Joined: Tue Jan 19, 2016 8:27 pm

mm5 Fast Rate and skip

Post by ddowdle »

I am having a real problem grasping the mm5 programming structure. Has anyone created or can create a script to rate the currently playing song, skip to next song, and then skip a little forward in new song... or something similar. I would really like to assign to a hotkey for going through and rating a lot of songs somewhat quickly.

Thanks
dd
Lowlander
Posts: 56492
Joined: Sat Sep 06, 2003 5:53 pm
Location: MediaMonkey 5

Re: mm5 Fast Rate and skip

Post by Lowlander »

No, no such Addon exists. However maybe using Hotkeys (Tools > Options > Hotkeys) to Rate and then Skip can do the trick for you in the meanwhile?
ddowdle
Posts: 4
Joined: Tue Jan 19, 2016 8:27 pm

Re: mm5 Fast Rate and skip

Post by ddowdle »

yeah. That is what i did, i thought someone could just help get me pointed in the right direction to write it.
drakinite
Posts: 965
Joined: Tue May 12, 2020 10:06 am
Contact:

Re: mm5 Fast Rate and skip

Post by drakinite »

Hi there,

Firstly, in order to get a grasp of how hotkeys and actions work, I'd recommend going through SampleScripts/hotkeyAction and possibly SampleScripts/refreshSkinShortcut, as well as just generally examining actions.js. Secondly, if you don't yet know how to create and package an addon, the Getting Started guide can be helpful.
Hotkeys and context menus are always associated with an action. The text of a context menu item / name of the hotkey is given the action's title, and when the menu item is clicked / hotkey is pressed, its execute function is called. So all of the business logic for your special hotkey will go into your action's execute parameter.

For rating the currently playing song, you can look in actions.js for actions.ratePlaying1 through actions.ratePlaying5. (If you do a Ctrl+F search, just search for "ratePlaying". They're made with object literals, but you don't have to worry about that detail. Note that the window.uitools.ratePlaying() function is passed a number from 0 to 100, not 0 to 5 (Also note that "unknown" ratings are given -1).

For skipping to the next song, that is simple. Just use app.player.nextAsync(). For more details on the player, see here: https://www.mediamonkey.com/docs/api/cl ... layer.html

To skip forward in the song, you can then use the app.player.seekMSAsync method. Please note the Async keyword in those two methods. I can take you down a long rabbit hole explaining what asynchronous methods are and how they work, how to use Promises and async/await — but the jist is that you need to do a little bit of extra work if you want to make sure the player changes seek position after it's finished changing tracks. (If you do want to go down the rabbit hole, start here: https://developer.mozilla.org/en-US/doc ... ynchronous)

If you do the following, there is no guarantee that the player will do what you asked in the correct order.

Code: Select all

app.player.nextAsync();
app.player.seekMSAsync(5000);
Imagine you have an intern who's making you coffee. You tell him, "Go fill the kettle, turn it on, then pour the water" then let him go do it. He fills the kettle then turns it on, but before waiting for the water to boil, he starts pouring the cold water into the mug.

If you're writing code and you want your water to be boiled before your intern pours the water, you have to tell him to wait before pouring the water. There are many ways to do this in code, but the simplest is by turning your function into an async function, and using the await keyword. (More info here)

Now, after testing this myself, it seems like awaiting app.player.nextAsync() isn't enough to make it work, so I'd recommend putting your seekMSAsync() in a timer. 100 ms seems to do the trick.

All together, here's a working sample for an action's execute function:

Code: Select all

async function() {
    uitools.ratePlaying(80);
    await app.player.nextAsync();
    requestTimeout(async function () {
        if (app.player.trackLengthMS > 10000) {
            await app.player.seekMSAsync(5000);
        }
    }, 100);
}
I put that if block in there just in case you have a song that's super short, in which case you probably wouldn't want it to skip.

If you want to add multiple hotkeys, one for each star, I'd recommend putting that nextAsync() and seekMSAsync() business into a single function (i.e. something like "skipAndSeek()"), and call it from each of your separate actions. That way, you don't have to deal with lots of copy-and-paste.

Good luck!

(P.S. I'd recommend using a debug build, so you can easily open the JS console and run tests/debug stuff from there. Also the pack-mmip addon can be useful: https://github.com/JL102/pack-mmip)
Image
Student electrical-computer engineer, web programmer, part-time MediaMonkey developer, full-time MediaMonkey enthusiast
I uploaded many addons to MM's addon page, but not all of those were created by me. "By drakinite, Submitted by drakinite" means I made it on my own time. "By Ventis Media, Inc., Submitted by drakinite" means it may have been made by me or another MediaMonkey developer, so instead of crediting/thanking me, please thank the team. You can still ask me for support on any of our addons.
ddowdle
Posts: 4
Joined: Tue Jan 19, 2016 8:27 pm

Re: mm5 Fast Rate and skip

Post by ddowdle »

thank you drakinite.

in case anybody else wants it:
i used 1 and 3 as hotkeys because of placement on num-pad.
it rates and then skips halfway through the next song.
copied MediaMonkey\SampleScripts\hotkeyAction to MediaMonkey\SampleScripts\fastRate
replaced the contents of MediaMonkey\SampleScripts\fastRate\actions_add.js with the below
and modified MediaMonkey\SampleScripts\fastRate\info.js to my liking.

Code: Select all

async function myFastRate(myStarValue) {
    myRating = myStarValue * 20;
    /*
     messageDlg('This is fast rate myStarValue ' + myRating, 'information', ['btnOK'], {
        defaultButton: 'btnOK'
    }, undefined);
    return;
    */
    uitools.ratePlaying(myRating);
    awaitNext = app.player.nextAsync();
    awaitNext.then(function () {
        seekDistance = Math.round(app.player.trackLengthMS / 2);
        if (seekDistance > 10000) {
            app.player.seekMSAsync(seekDistance);
        }
    });
    /*
    requestTimeout(async function () {
        seekDistance = Math.round(app.player.trackLengthMS/2);
        if (seekDistance > 10000) {
            await app.player.seekMSAsync(seekDistance);
        }
    }, 500);
    */
};

actions.fastRate1 = {
    title: 'Fast Rate 1',
    hotkeyAble: true,
    execute: function () {
        myFastRate(1);
    }
}
actions.fastRate5 = {
    title: 'Fast Rate 5',
    hotkeyAble: true,
    execute: function () {
        myFastRate(5);
    }
}

hotkeys.addHotkey('Ctrl+Alt+1', 'fastRate1',true);
hotkeys.addHotkey('Ctrl+Alt+3', 'fastRate5',true);
drakinite
Posts: 965
Joined: Tue May 12, 2020 10:06 am
Contact:

Re: mm5 Fast Rate and skip

Post by drakinite »

ddowdle wrote: Mon Oct 11, 2021 2:12 pm thank you drakinite.
No problem! :slight_smile: Why not upload it to the addons site so others can download it easily? First you'll want to zip the files up into a standard .zip file (Make sure info.json is in the "root" of the archive, instead of in a subfolder. Demonstration: https://files.drakinite.net/mmip-export-example.mp4) and then rename the extension to .mmip.
Then you can upload it here: https://www.mediamonkey.com/addon_system/admin/
I would personally place it under either the Behavior Tweaks or Tag fixers category. Click on the category you want, then click Submit New Addon, and follow the instructions.
Image
Student electrical-computer engineer, web programmer, part-time MediaMonkey developer, full-time MediaMonkey enthusiast
I uploaded many addons to MM's addon page, but not all of those were created by me. "By drakinite, Submitted by drakinite" means I made it on my own time. "By Ventis Media, Inc., Submitted by drakinite" means it may have been made by me or another MediaMonkey developer, so instead of crediting/thanking me, please thank the team. You can still ask me for support on any of our addons.
Post Reply