Author Topic: MusicBee API  (Read 288430 times)

Steven

  • Administrator
  • Sr. Member
  • *****
  • Posts: 34364
Library_QueryFiles("field=XXXX")
for multiple "and" conditions, separate each one by a null character '\0'
Library_QueryFiles("artist=XXXX" + '\0' + "album=YYYY")
there is no "or" syntax currently supported

That! But i need something like the quicksearch that is in the main window, it uses "all fields" as default, is there a metafield for "all fields"?
must i escape the query text anyway?

The Playlist_QueryFiles(filename) is not usefull because I must generate the xml on runtime so it will not be (and must not be) cached nor shown in the ui

Thanks a lot for your responses and your hard work!
Library_QueryFiles(query) has been enhanced so the query parameter can now be an xml string using the same syntax as the xml for auto-playlist files (suggest you create an auto-playlist to get the xml you want to generate) - however you only really need the Conditions and Condition elements. I forgot that auto-playlists can already search all fields for text by setting the field to "Any field" (=None in the xml) and the comparison type to "Is" or "Is any of"
Its in the next 2.1 update

kogash

  • Guest
i didnt think anyone was using it, so i changed it to return a url as the picture can be very big for an encoded string.
If the API revision in the plugin interface file mbApiInterface.ApiRevision is <= 25 then its using the old way


I was using it, it was very usefull but strange way to pass an image. I prefer the url way...  but I suggest you that in future api updates don't break functionality based on magic version numbers, IMHO it's much better to have:

library_getArtwork(string fileurl) <- returns base64
library_getArtworkUrl(string fileurl) <- new function returns url.

This way you I make a plugin that supports both musicbee 2 and musicbee 2.1

Steven

  • Administrator
  • Sr. Member
  • *****
  • Posts: 34364
i have added this API method to move files in the now playing list. Its in the next 2.1 update

public bool NowPlayingList_MoveFiles(int[] fromIndices, int toIndex)

where fromIndices is the 0 based position of the file(s) to be moved, and toIndex is the index to move after. That means to insert as the first item, you need to set toIndex to -1

When i make the update available, the included example file has a suggested approach for accomodating users still using MB v2.0 who you might want to offer reduced functionality with the older api methods. The issue with using the latest API version is it will crash MBv2.0 with a memory violation error when initialising using this code:
Code
                mbApiInterface = (MusicBeeApiInterface)Marshal.PtrToStructure(apiInterfacePtr, typeof(MusicBeeApiInterface));
the suggested approach is:
to follow
Last Edit: January 01, 2013, 09:41:54 PM by Steven

Steven

  • Administrator
  • Sr. Member
  • *****
  • Posts: 34364
api interface file and example updated in the first post

as well as the new NowPlayingList_MoveFiles() API method described above, the example files have been updated to support MusicBee version 2.0 and 2.1. If the host is MusicBee 2.0, any of the API methods after revision 25 will be null. The initialisation sequence is now:
            mbApiInterface = new MusicBeeApiInterface();
            mbApiInterface.Initialise(apiInterfacePtr);

e-motiv

  • Full Member
  • ***
  • Posts: 188
the reason the rating is not the old value is because the notifications are asynchronous, so by the time you receive it, any call backs to retrieve the current rating will have in likelyhood already changed. Can you let me know what you are trying to achieve

I thought you actually introduced NotificationType.RatingChanging (edit-correction) just for my retrieving old values?

So, I am still  trying to achieve the same thing as my initial request
   http://getmusicbee.com/forum/index.php?topic=1972.msg35234#msg35234
After which you introduced PluginNotifyType.RatingChanging
    http://getmusicbee.com/forum/index.php?topic=1972.msg41272#msg41272
  Developing @ e-motiv.net       --       Musicbee plugins: Speak Back - Ghost Tracks - Radio Dig

e-motiv

  • Full Member
  • ***
  • Posts: 188
Steven, any insight on the above?  This at first sight simple topic has meanwhile been a while and is spread along this thread. If you want, I can assemble previous specific posts in a separate thread so you can have a better view of all the things said/done before?
  Developing @ e-motiv.net       --       Musicbee plugins: Speak Back - Ghost Tracks - Radio Dig

slimmeke

  • Jr. Member
  • **
  • Posts: 51
What is the newest version of the API (C#) and where can I find it? I use now revision 27 and I can't get any notification to work (only the startup notification works.

And I don't use startpOnly in the ReceiveNotifications. I use:
about.ReceiveNotifications = (ReceiveNotificationFlags.PlayerEvents | ReceiveNotificationFlags.TagEvents);

The notification method looks like this:

 public void ReceiveNotification(string sourceFileUrl, NotificationType type)
        {
            // perform some action depending on the notification type
            switch (type)
            {
                case NotificationType.PluginStartup:

                    if (logitech == null)
                    {
                        logitech = new Logitech();
                        logitech.connect();

                        if (!logitech.connected)
                        {
                            Close(PluginCloseReason.StopNoUnload);
                        }
                    }
                    break;

                case NotificationType.PlayStateChanged:

                    if (logitech != null)
                    {
                        switch (mbApiInterface.Player_GetPlayState())
                        {
                            case PlayState.Playing:

                                logitech.changeState(PlayState.Playing);

                                if (!logitech.getFirstTime())
                                {
                                    logitech.setPosition(mbApiInterface.Player_GetPosition());
                                    logitech.setDuration(mbApiInterface.NowPlaying_GetDuration());
                                }
                                break;
                            case PlayState.Paused:
                                if (!logitech.getFirstTime())
                                {
                                    logitech.changeState(PlayState.Paused);
                                }
                                break;
                            case PlayState.Stopped:
                                if (!logitech.getFirstTime())
                                {
                                    logitech.changeState(PlayState.Stopped);
                                }
                                break;
                            case PlayState.Loading:
                                if (!logitech.getFirstTime())
                                {
                                    logitech.changeState(PlayState.Loading);
                                }
                                break;
                            case PlayState.Undefined:
                                if (!logitech.getFirstTime())
                                {
                                    logitech.changeState(PlayState.Undefined);
                                }
                                break;
                        }
                    }
                    break;

                case NotificationType.TrackChanged:
                    string artist = mbApiInterface.NowPlaying_GetFileTag(MetaDataType.Artist);
                    string album = mbApiInterface.NowPlaying_GetFileTag(MetaDataType.Album);
                    string title = mbApiInterface.NowPlaying_GetFileTag(MetaDataType.TrackTitle);
                    string artwork = mbApiInterface.NowPlaying_GetArtwork();

                   
                    logitech.changeArtistTitle(artist, album, title, artwork, mbApiInterface.NowPlaying_GetDuration(), mbApiInterface.Player_GetPosition());
                    break;
            }
        }



It this a bug or is it my source??
Last Edit: February 06, 2013, 02:08:08 PM by slimmeke

Steven

  • Administrator
  • Sr. Member
  • *****
  • Posts: 34364
the most recent API interface is in the first post, but any updates to it is backwards compatible.
Most of the available existing plugins make use of either the tag or player events and no problems have been reported.
Looking at the code, it appears correct  - in fact i thought you had this working a few weeks ago.
Maybe your plugin is crashing?

slimmeke

  • Jr. Member
  • **
  • Posts: 51
Yes it works in my previous version of the plugin. But now I'm rewriting the plugin in C# because of the problems using the Logitech SDK in a C++ dll.

Steven

  • Administrator
  • Sr. Member
  • *****
  • Posts: 34364
check out boroda74's "Advanced Tagging Tools" plugin which has c# source code posted in the first post of that plugin topic

boroda

  • Sr. Member
  • ****
  • Posts: 4636
Source code above looks good.

check out boroda74's "Advanced Tagging Tools" plugin which has c# source code posted in the first post of that plugin topic
My plugin uses only NotificationType.PluginStartup, NotificationType.PlayCountersChanged, NotificationType.TagsChanged and NotificationType.RatingChanged events.

boroda

  • Sr. Member
  • ****
  • Posts: 4636
Well, I've slightly modified my plugin to display message box in case of NotificationType.PlayStateChanged event. No problem. But sometimes plugin received NotificationType.PlayStateChanged event twice when I pressed pause/next/prev. buttons.

slimmeke

  • Jr. Member
  • **
  • Posts: 51
Tnx guys the problem has been solved.

jorgejiro

  • Guest
Hi all,

I'm trying to create a plugin that I used in winamp, when I had not discovered yet the best music player: MusicBee!! :)

The plugin is very simple: it captures a global hotkey (Win+W for example), and send the current song to the recycle bin and plays the next song in the current playlist.

I've downloaded the API c# project, and I've tried to build it, but it doesn't work the way I want.

I've tested my plugin, but only works if I had disabled/enabled it via MusicBee Preferences menu, so I need some kind of advice because it's annoying having to disable and enable the plugin in every session in order to use it  ;)



My question is: There is a way to register a global hotkey via MusicBee API, so I can capture this hotkey and do my stuff?



You can see my source code in BitBucket:
https://bitbucket.org/jorgejiro/musicbee-sendtorecyclebinplugin

The "KeyboardHook.cs" class assigns/detects global hotkeys.

The event function moves to the next song, and send the file to the recycle bin.

        void hook_KeyPressed(object sender, MusicBeePlugin.KeyboardHook.KeyPressedEventArgs e)
        {

            string fileUrl = mbApiInterface.NowPlaying_GetFileProperty(FilePropertyType.Url);

            if (mbApiInterface.NowPlayingList_IsAnyFollowingTracks())
            {
                mbApiInterface.Player_PlayNextTrack();
            }
            else
            {
                mbApiInterface.Player_Stop();
            }
            FileOperationAPIWrapper.MoveToRecycleBin(fileUrl);
        }



Steven

  • Administrator
  • Sr. Member
  • *****
  • Posts: 34364
i had a quick look:
- remove from the Initialise() function - you already have it in the PluginStartup event which is where it should be
Code
            // register the event that is fired after the key press.
            hook.KeyPressed += new EventHandler<MusicBeePlugin.KeyboardHook.KeyPressedEventArgs>(hook_KeyPressed);
            // register the control + alt + F12 combination as hot key.
            hook.RegisterHotKey(MusicBeePlugin.KeyboardHook.ModifierKeys.Win, Keys.W);
- in the Initialise() function set
Code
about.ReceiveNotifications = ReceiveNotificationFlags.StartupOnly
- i dont know if this matters to your function or not, but the PluginStartup notification (and any other notifications) are called on a separate thread to the main MusicBee GUI thread. It doesnt matter for calling MB functions from the plugin but it might matter to your keyboard handler
- you can register a command from which the user can assign a hotkey in the Hotkey preferences (or assign a command button) - its more flexible if you did it this way rather than registering your own hotkeys
Code
mbApiInterface.MB_RegisterCommand("Playback: Delete Current Track and Play Next", AddressOf functionToDoThis)