Search code examples
vlclibvlc

Recalculating duration on EOF in libvlc


I have a really specific use-case where in prod I have to play back a continously appended wav file in my java application (I have no way of modify this scenario).

My problem is that when I open this wav file for playback libvlc handles the duration calculation, and after a while it detects EOF, despite the file actual length is much larger since we opened it (my guess is because of buffered playback). This causes the player to stop (raise the finished event). As of today I restart the playback and set the time to the end position from this finished event. This causes little pauses and unacceptable in the final product.

I try to implement a logic in libvlc (vlc 3.0.6 version) that will handle this problem, but I can't really find out the proper way of doing it.

My approach would be to recalculate the duration of the wav file in case it's detecting EOF. If the new duration equals the old one than it is really EOF else it can continue playback.

I have tied to modify the VLC_DEMUXER_EOF handling in input.c, follow the file end trace, modify the demux-run.c and wav.c process, and to play around with the event handling (finished/stopped), but cannot get much closer to a valid solution.

I would really appreciate some help with this one, because I loosing my hair rapidly in the last couple of days. (I'm open for alternatives too, if you have some idea.)


Solution

  • I'm not sure which binding you are using, but I'm assuming vlcj since you mentioned Java.

    Anyway, one solution could be to use libvlc_media_new_callbacks. Doc: https://www.videolan.org/developers/vlc/doc/doxygen/html/group__libvlc__media.html#ga591c3cbe56444f1949165b2b9b75d8e2

    Implementing these custom callbacks will allow you to tell libvlc explicitly to wait. You can do this in the libvlc_media_read_cb callback, where the documentation states:

    If no data is immediately available, then the callback should sleep.

    You should find how this API is exposed through whichever binding you use and then use it from Java code.