LibVLC 4.x is there a definitive event raised when completely valid track list information is available?
I am looking at the behaviour of libvlc_media_player_get_tracklist API, my goal is to know when it is "safe" to get the track list and all of the returned data is valid.
I have some very rough code to try and demonstrate this in isolation:
#include <stdio.h>
#include <unistd.h>
#include "vlc/vlc.h"
void dumpTracklist(libvlc_media_tracklist_t *list);
static void callback(const struct libvlc_event_t *p_event, void *p_data ) {
libvlc_track_type_t wantedType = libvlc_track_audio;
switch (p_event->type) {
case libvlc_MediaPlayerPlaying:
printf("Playing\n");
break;
case libvlc_MediaPlayerBuffering:
printf("Buffering %f\n", p_event->u.media_player_buffering.new_cache);
break;
case libvlc_MediaPlayerLengthChanged:
printf("LengthChanged\n");
break;
case libvlc_MediaPlayerESAdded:
if (p_event->u.media_player_es_changed.i_type != wantedType)
return;
printf("ESAdded\n");
break;
case libvlc_MediaPlayerESSelected:
if (p_event->u.media_player_es_selection_changed.i_type != wantedType)
return;
printf("ESSelected\n");
break;
case libvlc_MediaPlayerESUpdated:
if (p_event->u.media_player_es_changed.i_type != wantedType)
return;
printf("ESUpdated\n");
break;
default:
printf("Event: %d\n", p_event->type);
break;
}
// Dump the track list after every registered event
libvlc_media_player_t *p_media_player = p_event->p_obj;
libvlc_media_tracklist_t *p_tracklist = libvlc_media_player_get_tracklist(p_media_player, libvlc_track_audio, false);
dumpTracklist(p_tracklist);
printf("\n");
}
int main(int argc, char **argv) {
const char *FILE = "/home/movies/whatever.mp4";
const char *args[] = { "--quiet" };
libvlc_instance_t *p_instance = libvlc_new(sizeof(args) / sizeof(args[0]), args);
if (p_instance == NULL)
goto error;
libvlc_media_t *p_md = libvlc_media_new_path(FILE);
if (p_md == NULL)
goto error;
libvlc_media_player_t *p_media_player = libvlc_media_player_new_from_media(p_instance, p_md);
if (p_media_player == NULL)
goto error;
libvlc_event_type_t events[] = {
libvlc_MediaPlayerPlaying,
libvlc_MediaPlayerBuffering,
libvlc_MediaPlayerLengthChanged,
libvlc_MediaPlayerESAdded,
libvlc_MediaPlayerESSelected,
libvlc_MediaPlayerESUpdated,
};
for (int i = 0; i < sizeof(events) / sizeof(events[0]); i++) {
libvlc_event_attach(
libvlc_media_player_event_manager(p_media_player),
events[i],
&callback,
NULL
);
}
printf("PLAY!\n\n");
libvlc_media_player_play(p_media_player);
usleep(5000 * 1000);
error:
if (p_md != NULL)
libvlc_media_release(p_md);
if (p_media_player != NULL) {
for (int i = 0; i < sizeof(events) / sizeof(events[0]); i++) {
libvlc_event_detach(
libvlc_media_player_event_manager(p_media_player),
events[i],
&callback,
NULL
);
}
}
if (p_media_player != NULL)
libvlc_media_player_release(p_media_player);
if (p_instance != NULL)
libvlc_release(p_instance);
}
void dumpTracklist(libvlc_media_tracklist_t *list) {
if (list == NULL) {
printf("Track list is NULL\n");
return;
}
libvlc_media_track_t *track = libvlc_media_tracklist_at(list, 0);
printf("Bit Rate is: %d\n", track->i_bitrate);
}
What I see with this code is:
PLAY!
Buffering 0.000000
Track list is NULL
ESAdded
Bit Rate is: 193662
LengthChanged
Bit Rate is: 193662
ESSelected
Bit Rate is: 193662
Playing
Bit Rate is: 193662
Buffering 0.000000
Bit Rate is: 193662
Buffering 23.400000
Bit Rate is: 193662
Buffering 48.400002
Bit Rate is: 193662
Buffering 73.400002
Bit Rate is: 193662
ESUpdated
Bit Rate is: 0
Buffering 98.400002
Bit Rate is: 0
Buffering 100.000000
Bit Rate is: 0
What you can see here is immediately after playing the tracklist is NULL - that's fine.
Soon after we get a valid tracklist returned, and it reports the bit rate value is 193662, and then it stays this way until after an ESUpdated event when the bit rate value changes to 0.
Is this expected?
I did not check what happens after every single media player event, only the ones that looked relevant.