Skip to main content

Topic: Getting a metadb_handle_ptr for the next track (Read 1418 times) previous topic - next topic

0 Members and 1 Guest are viewing this topic.
  • Gamil
  • [*]
Getting a metadb_handle_ptr for the next track
I'm writing a plugin which requires knowing what track will get played next.

The ultimate goal is to be able to have pre-specified tracks always played together in the correct order. Think Queen's "We Will Rock You" and "We Are The Champions". If your album happens to split the songs up, but they are supposed to be played together, it can be a bit annoying that shuffle always separates them.

So far I have the logic and everything in place so that when Foobar selects "We Will Rock You", it adds "We Are the Champions" to the playlist queue. But, say if "Werewolves In London" was supposed to follow "We Will Rock You", I want that to then come after "We Are The Champions", instead of "Dark Chest of Wonders"

That desired behavior happens automatically when I add songs to the queue with

Code: [Select]
pm->queue_add_item(playlist, songHandle);

But when doing it with

Code: [Select]
pm->queue_add_item_playlist(playlist, songIndex);

the playlist continues from wherever "We Are The Champions" would have been according to the play order. I want to use the latter so that it I can see them queue on the playlist, and I can choose to dequeue. In order to do that, I would need to know which track comes next.


From my playing around, it seems the only option would be do something like this:

Code: [Select]
metadb_handle_ptr last_played_handle;

static_api_ptr_t<playlist_manager> pm;
static_api_ptr_t<play_control> pc;

// check if the last song played was one "We Will Rock You" or "We Are The Champions"
if(last_played_handle.is_empty()){
    metadb_handle_ptr temp_handle;
    pc->get_now_playing(temp_handle);

    // if not, check if this song is one of them
    if(mdb->path_compare_metadb_handle(song1, temp_handle) || mdb->path_compare_metadb_handle(song2, temp_handle)){
        last_played_handle = temp_handle;
        pc->start(playback_control::track_command_next, false);
    }
    return;
}

pc->get_now_playing(song3);
        
t_size song1index = 0;
t_size song2index = 0;
t_size song3index = 0;

t_size playlist = pm->get_active_playlist();

//get playlist index for all 3 songs...Is there a more efficient method? I don't like this at O(n)
pm->playlist_find_item(playlist, song1, song1index);
pm->playlist_find_item(playlist, song2, song2index);
pm->playlist_find_item(playlist, song3, song3index);

//enqueue all 3 songs
pm->queue_add_item_playlist(playlist, song1index);
pm->queue_add_item_playlist(playlist, song2index);
pm->queue_add_item_playlist(playlist, song3index);

  • foosion
  • [*][*][*][*][*]
  • Moderator
Getting a metadb_handle_ptr for the next track
Reply #1
There is no API to retrieve the next played song. However, there is another way to get the desired functionality. If I understand you correctly, you want the following behaviour:
  • Playback is shuffled.
  • Certain groups of songs are always played in a fixed order.
The "Shuffle (albums)" playback order does exactly that and it can be customized through the advanced preferences ("Album grouping pattern" and "Album sorting pattern"). The problem is now to define suitable patterns.

Suppose we have a field %chain_group% that allows us to distinguish groups of songs, i.e. it has the same value for all songs in the same group and no two groups have the same value. We can consider songs that are not group as a singleton group. Suppose we also have a field %chain_sort% which specifies the order of the songs in a group, for example it could be the zero-padded, four digit index of the song within the group. It does not matter what its value is for ungrouped songs, but lets say it was 0001. Then we can set the album grouping pattern to "%chain_group% and the album sorting pattern to "%chain_group%|%chain_sort%" (simply %chain_sort% might work as well).

I can think of two ways to define these two fields. The first one is to use tagging, i.e. define a custom tag CHAIN_GROUP for all songs in a group and set it to the value of "%path%|$num(%subsong%,4)" as evaluated for the first song of the group. Define a custom tag CHAIN_SORT to store the index of the song within the group. The set the the album grouping pattern to "$if2(%chain_group%,%path%|$num(%subsong%,4))" and the album sorting pattern to "$if2(%chain_group%,%path%|$num(%subsong%,4))$if2(%chain_sort%,0001)" (or simply "$if2(%chain_sort%,0001)").

The second way is two implement a metadb_display_field_provider which provides the %chain_group% and %chain_sort% fields. Then you could store the group information in whichever way you like and wouldn't need to use tagging.
http://foosion.foobar2000.org/ - my components for foobar2000

  • Gamil
  • [*]
Getting a metadb_handle_ptr for the next track
Reply #2
Hi foosion,

Thanks for the reply. I wasn't aware of that functionality in the album sort.

However, I'm also writing this plugin more for personal academic purposes. I've been working in the coddled realms of C# and Java since college, and I'm trying to refresh my C++ skills.

Thanks also for mentioning the metadb_display_field_provider. I can definitely make use of that.
  • Last Edit: 19 March, 2013, 09:42:06 AM by Gamil