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: Getting a metadb_handle_ptr for the next track (Read 2282 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

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);

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.

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.