Skip to main content

Notice

Please note that most of the software linked on this forum is likely to be safe to use. If you are unsure, feel free to ask in the relevant topics, or send a private message to an administrator or moderator. To help curb the problems of false positives, or in the event that you do find actual malware, you can contribute through the article linked here.
Topic: Iterating over all tags in current track ? (Read 4339 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

Iterating over all tags in current track ?

I've been wanting to make a plugin that will dump now playing info to XML, which can then be used in various uses (you can see which one im leaning too from the other threads i made).

I've looked around the SDK and i think i saw most of what i needed (any short code samples are appriciated, but not strictly needed), including the track change events.

i have two questions, one concerning the sdk mostly, and another general.

1) Is it possible to go over the list of tags in a playing file ? for example, i dont want to access only fields i know that are usualy on files, like 'artist' and 'title', but just go over every tag and dump it to XML. some people use %DISC%, some people use %STYLE% and so on.. Is that possible in the SDK ?

2) Generally regarding XML.. havent seen any xml parser\writer in the sdk (not needed i suppose, or maybe i wasnt looking hard enough) and im not sure i wanna add in some pre-made bulky library to the build. Any special rules i should follow writing those (aside from a quick look in W3C's site for rules like opening <XML version='1.0'> tags and so on) ?

Any help, comments, etc, appriciated.

Iterating over all tags in current track ?

Reply #1
1) First the basic code to retrieve and release a handle for the playing track.
Code: [Select]
// get handle for playing track
metadb_handle * handle = play_control::get()->get_now_playing();
// check if we got a handle
if (handle != NULL) {
   // do something
   do_something(handle);
   // release the handle
   handle->handle_release();
}

If you use a playback callback you will get a metadb_handle as parameter which you must not release. Now for the do_something part. You will have to query the metadb_handle for some file_info. You can either get a copy of this or the file_info in the metadb, in which case you must lock (and unlock!) the handle. An item in the metadb may not have an associated file_info, so you must check for this case. Once you have a file_info object, you can iterate over the meta key-value pairs.

2) There is no XML processing support in the SDK. Use an external library, if you need to. Reading at least some introductory material couldn't hurt. If you don't use some premade helper functions, you will at least have to make sure you replace some special characters in exported text with the corresponding entities. From the top of my head this is
  • " -> &quot;
  • & -> &amp;
  • < -> &lt;
  • > -> &gt;
This list may be incomplete, especially I'm not sure about ' (apostrophe).

Iterating over all tags in current track ?

Reply #2
would this method of obtaining info fail incase the user doesnt have the database enabled in foobar?

Iterating over all tags in current track ?

Reply #3
No. Enabling the database only means that the contents of the metadb are saved across sessions. Retrieving cached info for loaded/playing tracks works independent of that.

Iterating over all tags in current track ?

Reply #4
Thats nice to know. The only detail im trying to take care of now is locking the file so the application reading the XML wont jump in while im dumping the now-playing info to the file (trying to do this safe on both ends).

Thanks for the help, foosion.

Iterating over all tags in current track ?

Reply #5
Code: [Select]
  // Checking if file is available for writing.
 if (xmlFile != NULL)
 {
     // Trying to get file_info object.
     fprintf(xmlFile,"Trying To Get file_info object ..");
     file_info* trackInfo;
     track->handle_query(trackInfo);
     fprintf(xmlFile,"Got file_info object .");

     // Checking if such an object exists.
     if (trackInfo != NULL)
     {
   // Iterating over meta data in this file.
   for (int index = 0; index < trackInfo->meta_get_count(); index++)
   {
       fprintf(xmlFile,"%s :: %s",
       trackInfo->meta_enum_name(index),
       trackInfo->meta_enum_value(index));
   }
     }
 }


Here's what im trying to do now. Im have some crashs (obviously, due to the fact trackInfo is null.. but how can i instanciate it if file_info is an abstract interface ?) and would appriciate any tips, though im still debugging it at the moment. The general loading and event catching works just fine.

EDIT: i surprise myself, sometimes >.<
Cant believe i missed the file_info_i class that implements that interface. Works fine now.

Iterating over all tags in current track ?

Reply #6
Code: [Select]
file_info_i_full trackInfo;
if (track->handle_query(&trackInfo)) {
   ...
}

You might want to check that against the actual SDK.

Iterating over all tags in current track ?

Reply #7
Used your method, i prefer working with straight variables and not pointers anyway. Release build cranks down to 12kb instead of 148kb (debug build).
I think im mostly done for now, gonna post it and let people test it around.

Thanks again, foosion.

Iterating over all tags in current track ?

Reply #8
Sorry for the double post, wanted anyone notice this but a new thread seems too much.

I was trying to provide dynamic info as well, such as elapsed time, but i couldnt make the on_playback_time event fire off. I did override the default implementation but it never raised that event. Anything wrong ?