xMusic - some extra music stuff

Xlobby plugin development

xMusic - some extra music stuff

Postby S Pittaway on Fri Mar 02, 2007 2:13 pm

xMusic


This provides a collection of music related functions -

1) track rating
2) automatically detect track changes and update played times/counts/run user command.
3) a smart playlist shuffle (reorder the playlist, based on rating\last played time).
4) add extra tags to help go from tracks to albums (and vice versa).
6) import extra tags form a tab separated text file.
5) extra milkdrop functionality.
6) cd player style playback controls (play-pause, previous-restart buttons).

Some of the milkdrop/cd player controls require you that you are using Winamp, Someone could extend it to use foobar if needed.

This plug-in needs a dummy screen (xMusic.dummy.xml) which is included with the download, you need add this to you skin for the plug-in to work (it simply defines a few categories used when auto updating)

As usual, the source code is included, its written in C# and you can use the free edition of C# to edit/compile it.

Download link (including source code) -
xMusic.zip
(111.89 KiB) Downloaded 808 times


Updates
20 Mar 2007 - Added album.added\sort and track.added\sort tags.
20 Mar 2007 - Fixed a bug while loading invalid tag files.
20 Mar 2007 - Improved tag importing instructions.
20 Mar 2007 - Very basic multizone support (works on the active zone).
?????????????? - Play status is now correctly picked up from WinAmp.
2 Apr 2008 - Updated to "my" version.
3 Apr 2008 - Added more data to xmusic.dummy.xml.
2 Apr 2008 - tags renamed to match xDatabase
2 Apr 2008 - Settings moved to an ini file
2 Apr 2008 - removed current.track.on track change command and current.track.auto update play times.
3 Apr 2008 - added ini file option to use the the file creation date - Get Date Added From File = true/false.
3 Apr 2008 - added ini file option to add item specific xdb.date.added - Add Date Added For "type" = true/false
4 Apr 2008 - fixed bug which reset play counter
4 Apr 2008 - fixed bug in use file creation date
4 Apr 2008 - sort info correctly added to albums/tracks and movies
6 Apr 2008 - added "find.audio.player.now"
6 Apr 2008 - added "find.audio.player.next"


Please note...


I only use this plugin to control milkdrop and automatiaclly add play times... for everything else i use xDatabase.
I have left the duplicated routines in, so hopefully it wont break anyone's install, but i am less likely to update this because I dont use it...
I would suggest moving over to xDatabase for most of the PLAYLIST/DATABASE routines.


I now use a ini file to store plugin settings, there is a new section about it in this post.

Some of the tag names have changed (i made them more neutral, and share them with xDatabase), here are the new tag names
"played" = "xdb.played"
"last.played" = "xdb.last.played.sort"
"last.played.str" = "xdb.last.played"
"played.count" = "xdb.played.count"
"album.added" = "xdb.date.added"
"track.added" = "xdb.date.added"
"album.added.sort" = "xdb.date.added.sort"
"track.added.sort" = "xdb.date.added.sort"
"shuffle.pos" = "xdb.random"
"stars" = "xdb.rating"


Functions are -


*** PLUGIN **********************************

xmusic.plugin.stop
This will stop the plugin from looking for track changes and play state changes.

xmusic.plugin.start
This will make the plugin look for track changes and play state changes. This can be called automatically by setting AutoStart = true in the ini file.


*** CURRENT TRACK **********************************

current.track.set track rating:dec/inc/toggle/*/**/***/****/*****
This writes/updates a tag called "stars" in the current track.
"dec" decrements the rating
"inc" increments the rating
"toggle" increments the rating, if it equals ***** it wraps round to *
"*" to "*****" sets stars to that value.

current.track.set track played time:value
This will update the current songs "played", "played.count", "last.played" and "last.played.str".
"" use the current time
"blank" reset the played times
"date/time" set the played times to be this value.
if the value is blank, the tags will be removed, if not they are set to
"played" to true
"played.count" is incremented
"last.played" to be the number of mins since my birthday :) (good for sorting)
"last.played.str" to be "last played at %datetime>f"

current.track.set album rating:blank/dec/inc/*/**/***/****/*****
This does the same thing as "current.track.set track rating", but it is applied to every track on the current songs album.

current.track.set album played time:value
This does the same thing as "track.set track played time", but it is applied to every track on the current songs album.


*** PLAYLIST/DATABASE ******************************

find.audio.player.now:category name>category field>audio.player.field>is sorted (true/false)
This will find the current song in a category.

find.audio.player.next:category name>category field>audio.player.field>is sorted (true/false)
This will find the next song in a category.

database.m3uplaylists.load.current
Jump to the current playlist in the m3uplaylists category - useful to ensure that you are deleing/renaming the current playlist.

database.m3uplaylists.find:playlistname
Jump to the playlist "playlistname" in the m3uplaylists category.

database.set rating:category>dec/inc/*****
This does the same thing as "set track rating", but it updates the selected entry in "category".

database.set played time:category>value
This does the same thing as "track.set track played time", but it updates the selected entry in "category".

database.playlist shuffle:MaxSongsToResuffle
This will add a field ("shuffle.pos") to every item in the current playlist, the playlist can then be sorted on the new field to randomize it. This means you can see what order the tracks will be played in (unlike when using the shuffle command).
If MaxSongsToResuffle is set it will only update that number of the entries in the playlist (useful if you playlist is very large).

database.add shuffle
Updates the "shuffle.pos" of every song in the music database.

database.add extra fields
This add the following fields to each album -
"artist.sort" (i.e. artist=the beatles, artist.sort=beatles, the)
"albumname.sort" (i.e. albumname=the big album, albumname.sort=big album, the)
It will also add the following fields to each track -
"artist.sort" (i.e. artist=the beatles, artist.sort=beatles, the)
"album.artist"\"album.artist.sort" a copy of the alum artist name (allows for simple mapping of various artist tracks)
If the following are NOT present they are added and set to
"played" = "false"
"played.count" = "0"
"last.played" = "0000000000"
"stars" = "***"
"track.search" = "TrackName (TrackArtist, AlbumName)"
"shuffle.pos" = random position based on the rating/played time.

database.import tags:tab_separated_file_path
This parses a tab separated list and adds/updates any music entries found in the text file.


*** PLAYBACK CONTROLS ******************************

playback.set pause string:str
When the music player is paused, %variable>xmusic.play.pause.button% will contain this string.

playback.set play string:str
When the music player is playing, %variable>xmusic.play.pause.button% will contain this string.

playback.toggle playback
Toggle the music player, combine with %variable>xmusic.play.pause.button% and you have a simple play/pause combo button.

playback.stop
Stop the music player (and updates %variable>xmusic.play.pause.button%).

playback.restart and previous track
Call this once and it will restart the current track, call it twice and it will jump to the previous track (this is how all of my cd players have worked). In use this feels like double clicking the button...

playback.auto.hide.controls:TRUE/FALSE/BLANK
If this is set to true it will automatically hide the progress bar and any controls with an id of "id.music.controls".
I use this to hide a music now plying display on my main menu.


*** MILKDROP ***************************************

milkdrop.auto.reposition:TRUE/FALSE
If enabled, this does the same kind of thing as xmovewindow - whenever a screen is entered or milkdrop is started it will strip the border/title from milkdrop and automatically position miilkdrop at the control with an id of "xmusic.milkdrop.screen_name", where screen_name is the name of the screen the control is on.
If you want it to look for milkdrop starting and position the control as needed you need a textbox with a value of "plugin>xmusic>milkdrop.auto.position".

milkdrop.position
This does the same kind of thing as xmovewindow - it will strip the border/title from milkdrop and automatically position miilkdrop at the control with an id of "xmusic.milkdrop.screen_name", where screen_name is the name of the screen the control is on.

milkdrop.stop
Stop milkdrop.

milkdrop.start
Start milkdrop.

milkdrop.toggle
Stop/start milkdrop.

milkdrop.fullscreen stop
Not yet implemented.

milkdrop.fullscreen start
Not yet implemented.

milkdrop.fullscreen toggle
Not yet implemented.

milkdrop.rating -
Decrement the rating for the current visualization currently running.

milkdrop.rating +
Increment the rating for the current visualization currently running.

milkdrop.vis +
Move to the next visualization.

milkdrop.vis -
Move to the previous visualization.

milkdrop.vis random
Pick a random visualization.

milkdrop.show title
Show the current songs title in milkdrop.

milkdrop.show fps
Show the current songs title (animated) in milkdrop.


*** INI FILE SETTINGS *********************************

Format Rating Char = char
Whenever a user rating is changed this charecter is used.

AutoStart = true/false
On start-up, kick off the plugin

Auto Update Last Played Time = true/false
Automatically update the last played time whenever the current track changes.

Add Date Added For "type" = true/false
If this is set, i will create a xdb.date.added."type" and xdb.date.added.sort"type" entries, where "type" is track or album.

Get Date Added From File = true/false
If this is set, i will try and get the date added from the file creation time, if the value stored in the database is older i will still use that...

Auto Position Milkdrop window = true/false
Automatically remove the frame from mildrop and position it to the control "xmusic.milkdrop.***current screen name***.

Auto Hide Music Controls = true/false
If a track is playing show progressbar and any controls with an id of id.music.controls, if no track is playing hide them.

Pause Button Text = string
If a track IS playing the value of "xmusic.play.pause.button" will be this string.

Play Button Text = string
If a track is NOT playing the value of "xmusic.play.pause.button" will be this string.

Check For Track Changes every (ms) = int
Every XXX ms i will see if the current track has changed.

Milkdrop Class Name = string
This is the class name of the milkdrop window, it is Milkdrop for version 1 and Milkdrop2 for the new milkdrop.

Check Playback State Via Winamp = true/false
IF you are using WinAmp, i can tell if a track is playing or paused and update the state acordingly.

Check For Play State Changes every (ms) = int
If Check Playback State Via Winamp is set, Every XXX ms i will see if the you have pressed the play/pause/stop buttons.

[On Track Change]
Whenever the current track changes, i will run the commands in the [On Track Change]. It will run all of the commands in the order 1, 2, 3 etc.
Example -
[On Track Change]
1 = command¦xlobby¦goto screen¦menu
2 = command¦plugin¦command¦xMusic¦milkdrop.stop


[On Track Change]
Whenever the play status changes, i will run the commands in the [On Play State Change]. It will run all of the commands in the order 1, 2, 3 etc.
Example -
[On Track Change]
1 = command¦xlobby¦goto screen¦menu
2 = command¦plugin¦command¦xMusic¦milkdrop.stop



Notes:

xml file backups
Anything that directly modifies a database.xml file will save the old file as xxx.bup, if anything goes wrong you can restore the last copy.

CD Playback controls
The value of %variable>xmusic.play.pause.button% is automatically updated to reflect the play status of Winamp.

Smart Playlist/shuffle.pos
shuffle.pos is "smart", it will factor in the rating of the track and its last played time - it tries to place ***** songs near the start of the playlist and * songs at the end. it will also try and place unplayed songs at the start of they playlist. Personally, i tent to listen to all of my tracks in a random playlist (i load up 14000 tracks when Xlobby starts) calling database.playlist shuffle takes ages to run on such a large playlist, instead i call "database.add shuffle" every time i exit Xlobby, this means i can simply sort my initial playlist on "shuffle.pos".

Mp3 Tag Importing

I use a simple export file, the output file name should be *.txt and i use the following mte file -

Code: Select all
parameter   length   length.seconds   genre   year   bitrate   codec
$loop(%album%)$loop(%album%)%_folderpath%%_filename_ext%   %_length%   %_length_seconds%   %genre%   %year%   %_bitrate%   %_codec%
$loopend()$loopend()


PLEASE NOTE THAT THE ABOVE IS USING TABS NOT SPACES

%_folderpath%%_filename_ext% HAS to be the FISRT entry!
%_length%, %_length_seconds% can be replaced with any of the tags supported in Mp3Tag.

This will generate a file that looks like this

C:\tag.txt
-----------------------------------------------
C:\oasis\stop the clocks [disc 1 of 2]\06-wonderwall.flac 04:17 257 Rock 2006 1040 Free Lossless Audio Codec
C:\oasis\stop the clocks [disc 1 of 2]\01-rock 'n' roll star.flac 05:19 319 Rock 2006 1061 Free Lossless Audio Codec
-----------------------------------------------

You then need to add an header to the the file so the importer knows what field names to use -

-----------------------------------------------
parameter length length.seconds genre year bitrate codec
C:\Documents and Settings\sean.pittaway\My Data\Music\New\oasis\stop the clocks [disc 1 of 2]\06-wonderwall.flac 04:17 257 Rock 2006 1040 Free Lossless Audio Codec
C:\Documents and Settings\sean.pittaway\My Data\Music\New\oasis\stop the clocks [disc 1 of 2]\01-rock 'n' roll star.flac 05:19 319 Rock 2006 1061 Free Lossless Audio Codec
-----------------------------------------------


Again parameter MUST BE THE FIRST ENTRY.

PLEASE NOTE THAT THE ABOVE IS USING TABS NOT SPACES

You can now import these tags using this plugin.






Sean.
Last edited by S Pittaway on Mon Apr 07, 2008 9:58 am, edited 16 times in total.
S Pittaway
 
Posts: 651
Joined: Wed Jan 25, 2006 11:08 am
Location: Manchester, England

Postby scottw on Fri Mar 02, 2007 3:48 pm

Wow this looks awesome. I just had time to skim thru it but will jump into it later on.


Thanks alot!!!!!!!!!!
scottw
 
Posts: 774
Joined: Mon Feb 06, 2006 4:21 pm
Location: Glen Burnie, Maryland

Postby scottw on Fri Mar 02, 2007 4:31 pm

I wonder if there would be a way to use this to have a date added tag for music. That way you can sort your music by the most recently added.

Just a thought.
scottw
 
Posts: 774
Joined: Mon Feb 06, 2006 4:21 pm
Location: Glen Burnie, Maryland

Postby P3rv3rt B3ar on Fri Mar 02, 2007 5:39 pm

Great to see this one out... i think u have been promising this as long as ive been ZPd. Which actually does pretty same stuff but for videos. Ive been waiting this one anxiously. ill get back to u when i have tested it.
P3rv3rt B3ar
 
Posts: 1364
Joined: Fri Apr 07, 2006 9:52 pm
Location: West Coast Funland

Postby scalt on Fri Mar 02, 2007 7:14 pm

Could you point me to the MP3 tagger (website..) you're using to add the FLAC song duration to your database?
scalt
 
Posts: 75
Joined: Tue Dec 06, 2005 10:53 pm

Postby scottw on Fri Mar 02, 2007 8:01 pm

Maybe I am doing something wrong but I cannot get the "current.track.auto update play times:TRUE/FALSE" to work. I assume you set the "Variables" to either TRUE or FALSE, right?

I ran the "database.add extra fields" and it added all the fields in my music and I also ran "current.track.set track played time" with "" in the Variables field and that seemed to update what it was supposed to but the auto update does not seem to work, for me :lol:

I assume that after you set this and run it then it will auto update the said tags after the current song is changed, right?


Thanks,
scottw
 
Posts: 774
Joined: Mon Feb 06, 2006 4:21 pm
Location: Glen Burnie, Maryland

Postby S Pittaway on Sat Mar 03, 2007 7:58 am

scalt, Mp3 Tag can be downloaded from http://www.mp3tag.de/en/index.htmlMp3 its actually petty good, i tried a few other taggers and this seems like the best one.


scottw, i can easily add a "date.added" tag whenever you run "database.add extra fields" to any songs/albums that dont contain it,i will stick it in the next issue.

You did add xmusic.dummy.xml to your skin folder dident you?

You are right about the boolean variables, they accept TRUE/true/YES ect.

You are also correct about "current.track.auto update play times" when its enabled it updates the tags whenever a track changes.

i had a quick play and it seamed to work fine here (as long as the dummy screen is present).

I am using the latest xlobby build, not sure if that makes any differance?

I know that a while ago trackparamter was not returned correctly.... it stopd this plugin from working

"current.track.auto update play times" is actually on by default, so just dont call it for now and it should work fine (its what i use).

Out of interest could you try setting "current.track.on track change command" to be something like "command:xlobby:goto screen:menu" and see if the screen changes when the track changes?
S Pittaway
 
Posts: 651
Joined: Wed Jan 25, 2006 11:08 am
Location: Manchester, England

Postby scottw on Sun Mar 04, 2007 2:45 am

Thanks for the reply and adding the Date Added would be outstanding!!!

I tried the "current.track.on track change command" using "command:xlobby:goto screen:menu" in the Variables field, without the quotes :D but it did nothing.
Without really knowing how the plugin works I can't help much, but this is what I know.
I don't know if this has anything to do with it but I do not have my music setup the "standard" way of Artist>Album>Tracks. I have mine setup like Artist>track1.mp3 track2.mp3
On my hard drive I have c:\music with:
Artist1
....Track1.mp3
....Track2/mp3
Artist2
....Track1.mp3
....Track2.mp3
and I imported into XL with the Import type set to "id3" and ID3 options/Views set to Album.
Don't know if this matters but I did not want you getting into a whole bunch of troubleshooting with me if it was something as simple as the way my music was imported :D

I am running the Nov 24th copy of XL and I do have the dummy file in my skin.
If I goto the dummy file and view that screen in XL I see XMusicDummy and XMusicDummyDetails. XmusicDummy shows the Artist/Albumname of the first artist shown in my database and XMusicDummyDetails show the track from that first artist. Is this supposed to change to show the currently playing song, because it does not.

This sounds like an awesome plugin but I think I just need a little more info on it, if you have time :D

EDIT: Oh and I am using Winamp 5.31
scottw
 
Posts: 774
Joined: Mon Feb 06, 2006 4:21 pm
Location: Glen Burnie, Maryland

Postby scottw on Sun Mar 04, 2007 3:03 am

Ok I have a little update. On the dummy screen if I am playing one song I do see that Artist/Album on the XmusicDummy category (the first section on that screen). If I have a bunch of songs queued up I see the last Artist/Album that is in the queue and it does not change depending on what is currently playing. The XmusicDummyDetails category always just shows the list of songs of the first artist listed in the database, the same as I said above and this is so no matter what.

Hope that helps a little.
scottw
 
Posts: 774
Joined: Mon Feb 06, 2006 4:21 pm
Location: Glen Burnie, Maryland

Postby S Pittaway on Sun Mar 04, 2007 9:09 am

It doesent do anythin complex any more, all it does is every xxx see if the current "audioplayer>now>%parameter%" has changed...

when a track change is detected it calls

"command:music:select playing:xMusicDummy"

This is supposed to load the current songs album details into a category (xMusicDummy in this case), steve added this while ago...

After the details have been loaded it walks thro the dummy cat until it finds the current track (it looks for an entry whos parameter ="audioplayer>now>%parameter%").

When the track is found it adds/updates the fields.

It also runs the track changed command whenever the parameter changes...


xmusicdummy is not really used, all it is for is to populate XMusicDummyDetails. it does this so if you are lookng at a music detail screen when the track changes that wont change.

I could understand it not working if you dont have any albums defined and just have artists/tracks (i guess its a bug in "select playing", chances of it being fixed???).

But i dont see any reason for "command:xlobby:goto screen:menu" NOT working, i take it you have a skin screen called menu? :)



If you want you could email me (seanDOTpittawayATdaiDOTcoDOTuk) a copy of you music.xml file and i could see why it does not work?



It might take me a while tho, we had a baby last year, so i only get to play with xlobby now and again :)


Sean.
S Pittaway
 
Posts: 651
Joined: Wed Jan 25, 2006 11:08 am
Location: Manchester, England

Postby scalt on Sun Mar 04, 2007 10:25 pm

Could you give me step-by-step instructions on how to add flac song length to my music DB?

I tried simply using the database import command but it didn't work...it basicly erased by DB (i had made a backup first..so no biggy).

Do I have to add the fields to the database first?

Also, I used the same program as you to create a tag.txt file with the proper header. It looked the same as the one you gave as an example.
scalt
 
Posts: 75
Joined: Tue Dec 06, 2005 10:53 pm

Postby scottw on Mon Mar 05, 2007 12:07 am

I think you may need to add the database fields first but I am just getting started with this GREAT plugin, but do not have any FLAC files.

Have you tried any of the other functions of this plugin??
scottw
 
Posts: 774
Joined: Mon Feb 06, 2006 4:21 pm
Location: Glen Burnie, Maryland

Postby S Pittaway on Mon Mar 05, 2007 9:20 am

Importing Tags From Mp3Tag (i.e. FLAC file play times) -


Backup you xml file

This works for me but it could be full of bugs so make a copy jsut in case...



Configure Mp3Tag


1) install Mp3Tag :)

2) start Mp3Tag

3) select Mp3Tag - Tools - Option

4) select export from the option tree.

5) click the new configuration button

6) eneter a name (xlobby?)


Notepad opens up....


7) delete the text from notepad

8) paste the following code into notepad
Code: Select all
$loop(%album%)$loop(%album%)%_folderpath%%_filename_ext%   %_length%   %_length_seconds%
$loopend()$loopend()


9) exit notepad and save the changes

10) press ok on the mp3tag option window



Export Tags

1) open Mp3Tag and point it at the root of you music filess

2) wait for a while (quite a while for my 14000 tracks :))

3) select all of you files (Mp3Tag - Edit - select all)

4) right click on the file list (in Mp3Tag ) and select export

5) select the export file type you created above

6) enter a export file name (say, c:\tags.txt)

7) press ok

8) wait till its finished

9) exit Mp3Tag



Add header line to tag file

1) open up the exported file you created above (say c:\tags.txt)

2) it should look something like -
Code: Select all
C:\oasis\stop the clocks [disc 1 of 2]\06-wonderwall.flac 04:17 257
C:\oasis\stop the clocks [disc 1 of 2]\01-rock 'n' roll star.flac 05:19 319


3) Add the header line, this is file path, any tags you added for the export file created abvove (length & length_in_secs) add "parameter length length.seconds" so the file should now look like -

Code: Select all
parameter length length.seconds
C:\oasis\stop the clocks [disc 1 of 2]\06-wonderwall.flac 04:17 257
C:\oasis\stop the clocks [disc 1 of 2]\01-rock 'n' roll star.flac 05:19 319


4) save the file



Import to xlobby

1) load up/refreash your songs as usual

2) create an event to load the data, for the file above it would be
"plugin>xmusic>database.import tags>c:\tags.txt"

3) run the event.


When its finished look at the music.xml file and it should now contain the added tags (length.seconds is not an xlobby tag so is easy to find).

Done.
S Pittaway
 
Posts: 651
Joined: Wed Jan 25, 2006 11:08 am
Location: Manchester, England

Postby scottw on Mon Mar 05, 2007 5:30 pm

Sean,

Thanks for the help and I completely understand about the baby thing. I have a 5 year old and still cannot get much done at home :D

I am trying to do as much troubleshooting myself as I can. I even downloaded the C# program from microsoft but am lost at programming.

The problem seems to be with updating the "dummy" page. For my skin and probably most others there are 2 was to play a music file:
1) executing a "track play" from the music commands
2) clicking on a song directly and it automatically starts playing (this is that way it is in my playlist screen) and having the next song start playing after the first one is finished.

Option 1 for me will always update the "xMusicDummy" category with the current playing artist/album but the xMusicDummyDetails always shows the song list from first artist in the music database, not from the artist that is currently playing.

Option 2 will always show the first artist/album in the music database in the xMusicDummy category and the song list from first artist in the music database in xMusicDummyDetails. So this pretty much does nothing.

I tried adding a button to the xmusic.dummy page that runs a "Select Playing" on category "xMusicDummy" and what this will do is update the xMusicDummyDetails category with the currently playing artists song list but does nothing to the xMusicDummy category :?


I know by now you are probably sorry you even released this plugin :lol: :lol: so I understand if you do not have time to mess with it but if you get a chance I would appreciate it.

This plugin (I think) has a lot of potential and can go very far.
scottw
 
Posts: 774
Joined: Mon Feb 06, 2006 4:21 pm
Location: Glen Burnie, Maryland

Postby scalt on Mon Mar 05, 2007 7:06 pm

Pittaway

So I tried the method you described, but it doesn't work for me. All I get is an empty music.xml file. It does however create the music.xml.dup file so I know that the event is being launched.

Could I send you my music.xml file and tag.txt files so you can take a look?

Maybe it's because my music db is formatted differently then yours?

My sort order is
Code: Select all
  <sortorder>artist:albumname:tracknumber:trackfilename</sortorder>
scalt
 
Posts: 75
Joined: Tue Dec 06, 2005 10:53 pm

Next