savonet / liquidsoap

Liquidsoap is a statically typed scripting general-purpose language with dedicated operators and backend for all thing media, streaming, file generation, automation, HTTP backend and more.
http://liquidsoap.info
GNU General Public License v2.0
1.41k stars 130 forks source link

`on_track` propagation with `smooth_add` #1829

Open vitoyucepi opened 3 years ago

vitoyucepi commented 3 years ago

Describe the bug smooth_add triggers on_track event only once - at startup. So I can't monitor metadata changes without this event. Also it seems this operator has no information about track duration.

I'll see in log something like this

liquidsoap_1  | 2021/08/18 05:34:48 [playlist_1:3] Prepared "/media/music/music_8.mp3" (RID 1).
liquidsoap_1  | Radio metadata updated /var/liquidsoap/security.ogg
liquidsoap_1  | MainStream metadata updated /var/liquidsoap/security.ogg

liquidsoap_1  | Radio metadata updated /media/music/music1_8.mp3

So no more MainStream metadata updates.

To Reproduce

Liquidsoap config In this setup `addInput` harbor is just for sample. I don't connect to it. ``` security = single("security.ogg") music = playlist(mode = "randomize", reload = 1, reload_mode = "rounds", "/media/music") radio = fallback(track_sensitive = false, [schedule, security]) addInput = input.harbor(port = 8000, user = "source", password = "hackme", "add") mainStream = smooth_add(p = 0.15, normal = radio, special = addInput) def addSourceMonitor(~name = null(), src) def onNewTrack(newMetadata) print("#{name ?? src.id()} metadata updated #{newMetadata['filename']}") end src.on_track(onNewTrack) end addSourceMonitor(name = "Radio", radio) addSourceMonitor(name = "MainStream", mainStream) ```

Expected behavior I think that add_smooth should propagate on_track events to all further sources. Also I think that it should be aware of source.duration and source.remaining of previous source, if it has this info.

Version details

Install method Deb package from liquidsoap releases at github

Common issues N/A

toots commented 3 years ago

I can confirm the issue. This is a consequence of the current implementation of the add operator. This operator should eventually be rewritten to take advantage of some new facilities internally such as Producer_consumer and Child_support. This would introduce a buffer between the child sources and the final, added source.

The current implementation is synchronous, i.e. we pull data from both sources at each streaming round so, if s1 and s2 have data like this:

   |                   |
s1: ---------*
s2: -------------------

Then, we cannot add the track mark at s1 or else we would loose some data from s2 that has already been added to the frame.

With a buffer, both sources would write to an intermediary buffer so we can then pull from it and keep the extra data from s2 to use in the next get_frame call.

The same goes for remaining/duration/elapsed values.

Unfortunately, this is too much work to do at the moment as we are nearing the rc cycles for 2.0.0. This will be done with 2.0.1 and is captured in this ticket: https://github.com/savonet/liquidsoap/issues/1831

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.