Help - Search - Members - Calendar
Full Version: Iterating over all tags in current track ?
Hydrogenaudio Forums > Hosted Forums > foobar2000 > Development - (fb2k)
chaosblade
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.
foosion
1) First the basic code to retrieve and release a handle for the playing track.
CODE
// 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).
chaosblade
would this method of obtaining info fail incase the user doesnt have the database enabled in foobar?
foosion
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.
chaosblade
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.
chaosblade
CODE

 // 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.
foosion
CODE
file_info_i_full trackInfo;
if (track->handle_query(&trackInfo)) {
   ...
}

You might want to check that against the actual SDK.
chaosblade
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.
chaosblade
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 ?
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Invision Power Board © 2001-2008 Invision Power Services, Inc.