Get track+media position when playing m3u

This forum is about all development around libVLC.
pichelo
New Cone
New Cone
Posts: 9
Joined: 03 Oct 2019 20:09

Get track+media position when playing m3u

Postby pichelo » 03 Oct 2019 20:24

Hi VideoLAN Forum, I hope this is the right place for my topic.
I wrote some code using libvlc that plays m3u files.
Everything worked like a charm, until I decided to introduce feature to save state when the media is stopped.
I got familiar with functions like

Code: Select all

libvlc_media_player_get_position
which correctly returns the position along the track from the m3u currently being played. This is part of the information I need to "save state on stop".
The other part is the current track being played. Is that possible at all when playing m3u?
Functions I tried:

Code: Select all

libvlc_media_list_index_of_item
always returns -1

Code: Select all

libvlc_media_list_count
always returns 1

It looks like the m3u is a single thing in the media list, still functions like

Code: Select all

libvlc_media_list_player_previous
and

Code: Select all

libvlc_media_list_player_next
work as expected.

I'm not sure whether I call the api wrong or playing m3u has some sort of limitation.
Thus writing this post to exclude the latter and maybe get some advice.

sherington
Cone that earned his stripes
Cone that earned his stripes
Posts: 491
Joined: 10 Sep 2008 11:57
VLC version: master
Operating System: Linux

Re: Get track+media position when playing m3u

Postby sherington » 12 Oct 2019 08:31

Probably you need to look at subitems.

So given your current libvlc_media_t (for the m3u with one item), use libvlc_media_subitems to get the subitems (each entry in the m3u will be a subitem).

pichelo
New Cone
New Cone
Posts: 9
Joined: 03 Oct 2019 20:09

Re: Get track+media position when playing m3u

Postby pichelo » 13 Oct 2019 20:32

At first it didn't work, so I checked better on initialization.
My code used to create a new media list from scratch (libvlc_media_list_new), then adding the m3u media as sole item. This is why the list resulted in a single item. The strange fact is that libvlc_media_list_player_next or libvlc_media_list_player_next, worked as one would have expected. Is such behaviour expected?

The existing functionality worked the same after using libvlc_media_subitems to get the media list. This time items count returned the correct number of items, instead of 1.

Then getting the index of currently played media became a sequence of:

Code: Select all

libvlc_media_player_t *mp = libvlc_media_list_player_get_media_player libvlc_media_t *media = libvlc_media_player_get_media(mp); int curr_i = libvlc_media_list_index_of_item(media_list_from_subitems, media);[code] Thanks!

pichelo
New Cone
New Cone
Posts: 9
Joined: 03 Oct 2019 20:09

Re: Get track+media position when playing m3u

Postby pichelo » 04 Dec 2019 16:07

I have a new problem now. While playlist handling works like a charm, setting the position does not work anymore.
This is roughly how is done in my code (simplified C code):

Code: Select all

media = libvlc_media_new_path(_vlc, /* m3u path */); libvlc_media_parse_with_options(media, libvlc_media_parse_local | libvlc_media_parse_network, 10000); media_list = libvlc_media_subitems(media); media_list_player = libvlc_media_list_player_new(_vlc); media_player = libvlc_media_player_new(_vlc); libvlc_media_list_player_set_media_player(_media_list_player, media_player); libvlc_media_list_player_set_media_list(_media_list_player, media_list); libvlc_media_list_player_play_item_at_index(media_list_player, /* previously saved playlist item id */); libvlc_media_player_set_position(media_player, /* previously saved position (0 to 1.0) */);
Position is saved on some stop event by using libvlc_media_player_get_position, which indeed returns a proper value.
libvlc_media_list_player_play_item_at_index works as expected, but when it comes to libvlc_media_player_set_position, the call has no effect.

I tried few things, including:
- enclosing

Code: Select all

libvlc_media_player_set_position
within

Code: Select all

if (libvlc_media_player_is_seekable(media_player)) { /* set position here */ }
- loop on

Code: Select all

libvlc_media_player_is_playing
, until it returns true, then set position

Code: Select all

libvlc_media_player_set_position
used to work in the buggy code I mentioned when opening the thread.

Strange things happen is some cases, eg:
- if I put a sleep of 2 seconds before setting positions, then position is set and track is playing from there, but immediately after it moves to next track

I wonder how the semantics of

Code: Select all

libvlc_media_player_set_position
in context of media list player.

Thanks and Kind Regards

mangokm40
Cone that earned his stripes
Cone that earned his stripes
Posts: 130
Joined: 20 May 2010 20:00

Re: Get track+media position when playing m3u

Postby mangokm40 » 10 Dec 2019 18:39

"libvlc_media_list_player_play_item_at_index(media_list_player, /* previously saved playlist item id */);
libvlc_media_player_set_position(media_player, /* previously saved position (0 to 1.0) */);"

Might you be setiing position b4 media is playing?
Are you listening for playing event?

pichelo
New Cone
New Cone
Posts: 9
Joined: 03 Oct 2019 20:09

Re: Get track+media position when playing m3u

Postby pichelo » 13 Dec 2019 23:55

Hi, before I already tried something simpler like: while (!media is playing) {}, which did not work either.

Nonetheless I tried by attaching to the media playing event and this is the result:

Code: Select all

typedef struct { libvlc_event_manager_t *evt_manager; float position; } tn_set_position_user_data_t; static void _tn_media_set_position(const struct libvlc_event_t *event, void *user_data) { tn_set_position_user_data_t *position_user_data = (tn_set_position_user_data_t *) user_data; libvlc_event_detach(position_user_data->evt_manager, event->type, _tn_media_set_position, user_data); libvlc_media_player_t *media_player = (libvlc_media_player_t *) (event->p_obj); if (libvlc_media_player_is_seekable(media_player)) { syslog(LOG_INFO, "Recovering (%f)", position_user_data->position); libvlc_media_player_set_position(media_player, position_user_data->position); free(user_data); } else { syslog(LOG_WARNING, "Media is not seekable, starting from the beginning"); } libvlc_media_player_release(media_player); }
The callback is attached to to media player used by media list player by mean of:

Code: Select all

libvlc_event_manager_t *evt_manager = libvlc_media_player_event_manager(media_player); tn_set_position_user_data_t *user_data = malloc(sizeof (tn_set_position_user_data_t)); user_data->position = remember_item->media_pos;// some structure kept in memory, number is proper float between 0.0 and 1.0 retrieved by get position) user_data->evt_manager = evt_manager; libvlc_media_player_retain(media_player); // released by callback. libvlc_event_attach(evt_manager, libvlc_MediaPlayerPlaying, _tn_media_set_position, user_data);
The event gets triggered, callback is called and the log trace:

Code: Select all

syslog(LOG_INFO, "Recovering (%f)", position_user_data->position);
appears. But the media position does not change.
I tried with different media types (only using audio for this project), mp3 and ogg, but still nothing.
libvlc version is 3.0.8

pichelo
New Cone
New Cone
Posts: 9
Joined: 03 Oct 2019 20:09

Re: Get track+media position when playing m3u

Postby pichelo » 14 Dec 2019 00:19

After playing a bit with the callback, something unexpected happened
If I do not detach immediately the event it is called twice.
The set position call does not work the first time, but if I ignore the first event trigger (decrement a counter in user data, initialized to 1), then set position works as intended the second time!

Now I wonder why the event is triggered twice. How is that, is there a reason?
Currently I got the thing working but I feel like working around some behaviour which I did not really understand.

pichelo
New Cone
New Cone
Posts: 9
Joined: 03 Oct 2019 20:09

Re: Get track+media position when playing m3u

Postby pichelo » 14 Dec 2019 21:50

While investigating, something even stranger is noticed.
The media list plays even without calling either libvlc_media_list_player_play_item_at_index or libvlc_media_list_player_play.

This somehow explains the double playing event. But does not explain the unexpected behavior itself.

Is that known behavior? Can I somehow prevent auto playing of media lists?

pichelo
New Cone
New Cone
Posts: 9
Joined: 03 Oct 2019 20:09

Re: Get track+media position when playing m3u

Postby pichelo » 15 Dec 2019 20:42

All solved. My mistake at wiring a push button had the effect of calling libvlc_media_list_player_next, which somehow unnoticed started the track (1st event), then the expected flow arrived to "play item at index" which generated the second (proper) event.

Thanks a lot for the two answers, they were key hints to move forward.


Return to “Development around libVLC”

Who is online

Users browsing this forum: No registered users and 6 guests