Page 2 of 4

Re: [REQ] Addon to save Playcounter, LastPlayed, SkipCounter, LastSkipped to tag

Posted: Mon May 17, 2021 10:25 pm
by Andre_H
Hi Guys,

I'm trying to set up at least a little script for the thing above but it doesn't work. I took the supplied "swapArtistTitle" script as a basis and adapted it:

Code: Select all

/* Save Track-Statistics from Database to CustomFields.*/
// Fields:
// Custom5=Rating
// Custom6=Playcount
// Custom7=LastPlayed

actions.saveStatistics = {
    title: _('Speichere Statistik-Daten in CustomFields ...'),
    hotkeyAble: false,
    disabled: uitools.notMediaListSelected,
    visible: window.uitools.getCanEdit,
    execute: async function () {
        var list = await uitools.getSelectedTracklist().whenLoaded();
        if (list.count === 0) {
            return;
        }
        list.forEach(function(itm) {
           itm.beginUpdate();
               if(itm.Rating > 0 && itm.Rating != Number(itm.Custom5)) {
                  itm.Custom5 = itm.Rating;
               };		
               if(itm.PlayCounter > 0 && itm.PlayCounter != Number(itm.Custom6)) {
                  itm.Custom6 = itm.PlayCounter;
               };
               if(itm.LastTimePlayed > 0 && itm.LastTimePlayed != Number(itm.Custom7)) {
                  itm.Custom7 = itm.LastTimePlayed;
               };
           itm.endUpdate();
        });
        list.commitAsync();                        
    }
}

window._menuItems.editTags.action.submenu.push({
        action: actions.saveStatistics,
        order: 90,
        grouporder: 10
});
I don't get an error message, but MediaMonkey / my script doesn't write any changes to the MP3 tags.

Can someone help me?

Re: [REQ] Addon to save Playcounter, LastPlayed, SkipCounter, LastSkipped to tag

Posted: Wed May 19, 2021 4:11 pm
by Ludek
I think it is capitalization issue.

Use camelCase instead of CamelCase
i.e.
itm.custom6 = itm.playCounter.toString();

BTW: You can easily debug this in DevTools , right-click an element in the Debug build > Open DevTools in Chrome
and then put breakpoint into your code to see/debug the properties/values like this:
https://www.dropbox.com/s/523y4v5kwo6ix ... 4.png?dl=0

Re: [REQ] Addon to save Playcounter, LastPlayed, SkipCounter, LastSkipped to tag

Posted: Sat May 22, 2021 12:10 am
by Andre_H
Don't get it to work. No one of the tried variants of upper/lower/mixed case works. Not even when I want to write values unconditional ​​...

Code: Select all

itm.beginUpdate();
   itm.custom5 = itm.rating;
   itm.custom6 = itm.playCounter;
   itm.custom7 = itm.lastTimePlayed;
itm.endUpdate();
The MP3 file gets a new time stamp, something is saved, but not the IDTag updates I wanted.

Code: Select all

itm.custom5 = itm.rating.toString();
raises an error.

I'm not familiar enough with Chrome development, so I can't debug it either. Guess I'll give up at that point.

Anyway, thank you for your time.

Re: [REQ] Addon to save Playcounter, LastPlayed, SkipCounter, LastSkipped to tag

Posted: Tue May 25, 2021 12:48 pm
by Ludek
Strange, for me this works fine:

Code: Select all

itm.custom6 = itm.playCounter.toString();
itm.custom7 = itm.rating.toString();
i.e. opening track properties after this script run on the selected track shows the play count and rating values in the Custom6 and Cutsom7 fields on the [Custom] tab in Properties (tested with 5.0.1.2407)
Just note that 5 stars rating is converted to integer value 100 (like in the database), i.e. 20 = 1 star

For the lastTimePlayed I would recommend something like this (to be human readable):

Code: Select all

itm.custom8 = app.utils.dateTime2Timestamp( itm.lastTimePlayed_UTC);
and for backward conversion:

Code: Select all

itm.lastTimePlayed_UTC = app.utils.timestamp2DateTime( itm.custom8);

Re: [REQ] Addon to save Playcounter, LastPlayed, SkipCounter, LastSkipped to tag

Posted: Tue May 25, 2021 3:50 pm
by Andre_H
edit my original answer: it works, finally. Thank you, man!

The whole thing, in case anybody can do something useful with it ...

Code: Select all

actions.saveStatistics = {
    title: _('Speichere Statistik-Daten in CustomFields ...'),
    hotkeyAble: false,
    disabled: uitools.notMediaListSelected,
    visible: window.uitools.getCanEdit,
    execute: async function () {
        var list = await uitools.getSelectedTracklist().whenLoaded();
        if (list.count === 0) {
            return;
        }
        list.forEach(function(itm) {

           itm.beginUpdate();

               if(itm.custom5 != itm.rating.toString()) {
                  itm.custom5 = itm.rating.toString();
		  itm.commitAsync();
               };	
	
               if(itm.custom6 != itm.playCounter.toString()) {
                  itm.custom6 = itm.playCounter.toString();
		  itm.commitAsync();
               };

               if(itm.custom7 != app.utils.dateTime2Timestamp(itm.lastTimePlayed_UTC)) {
                  itm.custom7 = app.utils.dateTime2Timestamp(itm.lastTimePlayed_UTC);
		  itm.commitAsync();
               };

           itm.endUpdate();

        });
        // list.commitAsync();                        
    }
}

window._menuItems.editTags.action.submenu.push({
        action: actions.saveStatistics,
        order: 90,
        grouporder: 10
});
It checks if anything has changed, and only then, the values were saved again.

Last question: How can i trigger that on playing, and on after/on syncing back metadata from MMA (as both change at least the playcounter/timestamp)?

Re: [REQ] Addon to save Playcounter, LastPlayed, SkipCounter, LastSkipped to tag

Posted: Wed May 26, 2021 12:30 am
by drakinite
Great to hear it's working now.

For triggering it on playing, I know you can add a listener for playbackState on the player.
Here's an example:

Code: Select all

//listen for playback state to change
app.listen(player, 'playbackState', onPlaybackStateChange);

function onPlaybackStateChange(newState) {
	console.log(newState);
	switch(newState) {
		case 'pause':
			// do thing
			break;
		case 'stop':
			// do thing
			break;
		case 'trackChanged':
			// do thing
			break;
		case 'play':
			// do thing
		case 'unpause':
			// do thing
			break;
	}
}
As for running after syncing from MMA: I'm not sure, as I haven't dealt with any of the media sync stuff before, but maybe you can get somewhere with something along these lines.

Code: Select all

mediaSyncHandlers['usb'].override({finishSyncing: function($super, sync, mode) {
    $super(sync, mode);
    // do custom stuff
}});
This would override the finishSyncing method for the USB media sync handler. I'm not sure if that would actually do what you're looking for; Ludek would probably be able to help better with that.

Re: [REQ] Addon to save Playcounter, LastPlayed, SkipCounter, LastSkipped to tag

Posted: Wed May 26, 2021 1:17 am
by Andre_H
Sorry to ask that stupid question, but i'm totally new to that and just modified an existing script: Your code has to be a new script, along with the info.json-file and all that, or can i simply add that to the existing script? (that didn't work in the first try).

Re: [REQ] Addon to save Playcounter, LastPlayed, SkipCounter, LastSkipped to tag

Posted: Wed May 26, 2021 11:34 am
by drakinite
You can certainly add it to your existing addon, though I don't think you should put it in actions_add.js.

I'd recommend creating a mediaSync_add.js, within a subfolder named helpers. That's because the mediaSyncHandlers object is defined in that script.

Re: [REQ] Addon to save Playcounter, LastPlayed, SkipCounter, LastSkipped to tag

Posted: Wed May 26, 2021 12:50 pm
by Andre_H
so, (for the first part, update after beeing played in MMW) i added a "app.listen_add.js"-file with these code ...

Code: Select all

app.listen(app, 'trackmodified', function (track) {

	if(track.custom6 != track.playCounter.toString()) {
           track.custom6 = track.playCounter.toString();
	};

	if(track.custom7 != app.utils.dateTime2Timestamp(track.lastTimePlayed_UTC)) {
           track.custom7 = app.utils.dateTime2Timestamp(track.lastTimePlayed_UTC);
	};
	
	track.commitAsync();
    }                    
});
... but that seems to do nothing. i picked the code snipped from ludek, because i see (and understand) the track-reference, i didn't know, where i refer to the track or itm in drakinite's snippet.

edit: i searched, but found not, any addon / script with a similar functionality, where i can get an idea about the framework i need. if you can recommend someting, i dig into it.

Re: [REQ] Addon to save Playcounter, LastPlayed, SkipCounter, LastSkipped to tag

Posted: Wed May 26, 2021 4:51 pm
by drakinite
The way you're naming your JS file isn't correct. Take a look at the "Code" and "init.js" sections of the wiki page: https://www.mediamonkey.com/wiki/Gettin ... dons)#Code

If you name a script "app.listen_add.js", MM won't recognize it and it won't load/run that script.

I actually made an addon for a friend recently which utilizes the trackmodified event. It mimics the behavior of SMG, outputting the currently-playing track to a file (because SMG hasn't yet been updated to add support for MM5). It runs its main code in init.js. Hopefully this can be helpful to you: https://1drv.ms/u/s!AqHzUrf30uprqIxNKQC ... g?e=xDmMmt

Re: [REQ] Addon to save Playcounter, LastPlayed, SkipCounter, LastSkipped to tag

Posted: Thu May 27, 2021 1:16 am
by Andre_H
Thank you, got the file, i will look into it. :wink:

Re: [REQ] Addon to save Playcounter, LastPlayed, SkipCounter, LastSkipped to tag

Posted: Thu May 27, 2021 3:30 am
by Andre_H
one step further: "init.js" with

Code: Select all

requirejs('actions');
// Execute when the window is ready
window.whenReady(() => {
	app.listen(app, 'trackmodified', function (track) {

		if(track.custom6 != track.playCounter.toString()) {
        	   track.custom6 = track.playCounter.toString();
		};

		if(track.playCounter > 0 && track.custom7 != app.utils.dateTime2Timestamp(track.lastTimePlayed_UTC)) {
        	   track.custom7 = app.utils.dateTime2Timestamp(track.lastTimePlayed_UTC);
		};

		track.commitAsync();                   
	});
});
seems to do the job; after playing a song, the custom fields were updated and all values are correct. but: that seems to trigger an endless loop (status info: 1 track to tag, counting up as more tracks are played); i guess it's the logic behind "do when modified => modify ===> do when modified".

"trackmodified" sounds good, as i expected this to trigger also after syncing back (=modify) playcounts from MMA. (not tested so far).

if not, i would go for a "do after song is played" trigger also. is there anything like this? or any other way to break the loop?

Re: [REQ] Addon to save Playcounter, LastPlayed, SkipCounter, LastSkipped to tag

Posted: Thu May 27, 2021 6:36 am
by Ludek
Yes, 'trackmodified' should work fine for all your purposes as it is fired everytime the track is somehow modified (despite the way how it was modified, be it sync, playback or anything else).

I would just adjust it like this (otherwise you commit tracks that don't have any modification)

Code: Select all

requirejs('actions');
// Execute when the window is ready
window.whenReady(() => {
	app.listen(app, 'trackmodified', function (track) {

		var modified = false;
		if(track.custom6 != track.playCounter.toString()) {
        		track.custom6 = track.playCounter.toString();
        		modified = true;
		};

		if(track.playCounter > 0 && track.custom7 != app.utils.dateTime2Timestamp(track.lastTimePlayed_UTC)) {
        		track.custom7 = app.utils.dateTime2Timestamp(track.lastTimePlayed_UTC);
        		modified = true;
		};

		if (modified)
			track.commitAsync();                   
	});
});

Re: [REQ] Addon to save Playcounter, LastPlayed, SkipCounter, LastSkipped to tag

Posted: Thu May 27, 2021 6:59 am
by Andre_H
I'm going to test it tonight.

Thank you both for the support!

Re: [REQ] Addon to save Playcounter, LastPlayed, SkipCounter, LastSkipped to tag

Posted: Thu May 27, 2021 9:34 am
by drakinite
😊

Somewhat off topic, but that infinite loop reminded me of this: https://youtu.be/N6lYcXjd4pg