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.4k stars 130 forks source link

Transitions - Syntax Error #1990

Closed FlorianReiterer closed 2 years ago

FlorianReiterer commented 3 years ago

Trying to transition between different sources, getting the error

At test.liq, line 15, char 72-81:
Error 5: this value has type
  [(_, _.{id : _}, ...) -> _]
but it should be a subtype of the type of the value at /home/pi/.opam/4.12.0/lib/liquidsoap/share/liquidsoap/git/6a6e0c9e/libs/switches.liq, line 10, char 58-69
  [(_, source(audio=pcm('A), video=?internal('B), midi=?internal('C)), ...) ->

when using this script

settings.frame.audio.channels.set(2)
settings.frame.audio.samplerate.set(96000)

music = playlist(reload_mode="watch","/Musik")

live = input.harbor("live", port=18888, password="hackme")

def to_show(a, b) 
  add(normalize=false, [
    fade.out(a),
    sequence([blank(duration=2.), (b.source)]),
  ])
end
radio=fallback(track_sensitive=false, transition_length=5., transitions=[to_show],[live, music])

output.icecast(%mp3(bitrate=256,samplerate=44100), fallible=true, mount="source.mp3", radio)

try to switch to live with a fade out, insert silence and switch to live source.

running raspbian buster on rpi4, installed via opam and pinned github liquidsoap 2.1.0 (fresh OS install done from scratch)

2021/09/30 08:55:39 >>> LOG START
2021/09/30 08:55:31 [main:3] Liquidsoap 2.1.0+git@6a6e0c9e
2021/09/30 08:55:31 [main:3] Using: bytes=[distributed with OCaml 4.02 or above] pcre=7.5.0 sedlex=2.4 menhirLib=20210419 curl=0.9.1 dtools=0.4.4 duppy=0.9.2 cry=0.6.5 mm=0.7.1 ogg=0.7.0 ogg.decoder=0.7.0 mad=0.5.0 flac=0.3.0 flac.ogg=0.3.0 flac.decoder=0.3.0 dynlink=[distributed with Ocaml] lame=0.3.4 ffmpeg-avutil=1.0.0 ffmpeg-avcodec=1.0.0 ffmpeg-avdevice=1.0.0 ffmpeg-av=1.0.0 ffmpeg-avfilter=1.0.0 ffmpeg-swresample=1.0.0 ffmpeg-swscale=1.0.0 samplerate=0.1.6 taglib=0.3.6 ssl=0.5.9 camomile=1.0.2
smimram commented 3 years ago

You should change b.source to (b:source) to make it work.

Longer version (mostly for myself): we have implemented a mechanism to increase types, but this is a case where we should decrease them...

FlorianReiterer commented 3 years ago

thx, it starts with no error, but does not fade out source a. If i name fade.out(a:source) it accepts but skips the whole transition thing, although it's saying [switch_0:3] Switch to input.harbor_0 with transition.

gammaw commented 3 years ago

Same here. My code is something like this (after the hint above upon which I got it running by changing b into b:source). It runs, but there is no fading. I'm running the latest tagged 2.0.0 version. Any idea?

def fade_out_transition(a,b)
    sequence(merge=true, [fade.out(duration=5., a),playlist_jingle_station_id,(b:source)])
end

radio = switch(track_sensitive=false, 
    transitions=[fade_out_transition,fade_out_transition],
    [({3w and 15h43m-15h44m or 15h45m-15h46m}, delay(60., playlist_my_show)),
    ({true}, off_air) ])

For the syntax error part: is it a bug in the parser (wrongly inferred expected type) or is it the expected syntax? I haven't seen the b:source style syntax before and I didn't find it in the new book neither (e.g., where it talks about fade.out). Does b:source mean to declare that b is of t type source?

toots commented 3 years ago

Hi!

The (b:source) is a limitation of the typing system that we are working on.

The reason you may not hearing any fade out is because live shows do not buffer data so, when they are done, there is no more data to use to fade out..

Could you try adding a buffer , for instance this:

def fade_out_transition(a,b)
    sequence(merge=true, [fade.out(duration=5., a),playlist_jingle_station_id,(b:source)])
end

radio = switch(track_sensitive=false, 
    transitions=[fade_out_transition,fade_out_transition],
    [({3w and 15h43m-15h44m or 15h45m-15h46m}, delay(60., playlist_my_show)),
    ({true}, buffer(off_air)) ])

I think this could help.

gammaw commented 3 years ago

Thanks! I don't use a live source in this example, all sources are MP3 playlists which contain files on the disk. I added the buffer operator but now I get a That source is fallible error on the last two lines.

FlorianReiterer commented 3 years ago

I have a buffer in there:

output.icecast(%ogg(%flac(samplerate=96000, channels=2, compression=5, bits_per_sample=24)), fallible = true,icy_metadata = "false", mount="source", password="hackme", port=18800,
 buffer(buffer=5.,(radio)))
output.icecast(%mp3(bitrate=256,samplerate=44100), format="audio/mpeg", fallible=true, icy_metadata = "true", mount="source.mp3", password="hackme", port=18800, 
clock(buffer(buffer=5.,(radio))))

the switch from playlist to live is affected. Where there is enough data left in the playlist source, right?

FlorianReiterer commented 3 years ago

Sorry Toots, i got it wrong, here is what you suggested: radio = fallback(track_sensitive=false,[live, buffer(radio)]) no fading though

FlorianReiterer commented 3 years ago

added longer buffer size, still a hard cut instead of fading out: radio = fallback(track_sensitive=false,[live, buffer(buffer=5.,(radio))])

toots commented 2 years ago

Hi.

Do you have logs of the transitions to share? Thks!

FlorianReiterer commented 2 years ago
2021/11/08 07:33:30 [source.mp3:3] Connection setup was successful.
2021/11/08 07:33:47 [input.harbor_0:3] Decoding...
2021/11/08 07:33:49 [switch_4:3] Switch to input.harbor_0 with transition.
gammaw commented 2 years ago

Similar logs on my side too. After I managed to eliminate the fallible parse error by adding fallible=true in the output operator (and still having buffer(off_air) in the switch, as suggested), I still hear no fading. In this example, the transition with fading is supposed to happen at 16:13 (see exact code above). The transition happens on time but there is no fading out of the leaving track.

2021/11/13 16:11:37 [radio.mp3:3] Connecting mount radio.mp3 for source@127.0.0.1...
2021/11/13 16:11:37 [radio.mp3:3] Connection setup was successful.
2021/11/13 16:11:37 [switch_1:3] Switch to buffer.producer_0.
[mp3 @ 0x7fc9e439edc0] Estimating duration from bitrate, this may be inaccurate
[mp3 @ 0x7fc9e63e13c0] Estimating duration from bitrate, this may be inaccurate
2021/11/13 16:13:00 [playlist_my_show:3] Prepared "/var/myradio/media/my_show_test_17_seconds.mp3" (RID 4).
2021/11/13 16:13:00 [switch_1:3] Switch to delay_0 with transition.
[mp3 @ 0x7fc9f0104b00] Estimating duration from bitrate, this may be inaccurate
[mp3 @ 0x7fc9f007f5c0] Estimating duration from bitrate, this may be inaccurate
2021/11/13 16:13:21 [decoder:2] Decoding "/var/myradio/media/my_show_test_17_seconds.mp3" ended: Ffmpeg_decoder.End_of_file.

PS: I was going to write down the exact version I'm using but I didn't know how. liquidsoap --version says 2.0.0 but I guess the commit ID would be more useful. The image I'm using is approx. 3 weeks old (which I built back then based on the latest Liquidsoap image in Docker Hub).

gammaw commented 2 years ago

@toots is the new 2.0.1 a potential fix for this too (although I didn't find this issue listed in the release notes), or are we using fade.out wrongly?

toots commented 2 years ago

Unfortunately, I don't think so. But I'm planning on looking at is soon.

gammaw commented 2 years ago

@toots any update on this? In the meanwhile, do you have a reference script where fade.out works as expected with Liquidsoap 2.0, so that we can compare our script with the reference script and iteratively change the one into the other to spot where the problem lies?

Background: we're willing to switch from 1.4 to 2.0 because of the new delay operator and other things but we cannot do it with fade.out not working.

gammaw commented 2 years ago

Same here. My code is something like this (after the hint above upon which I got it running by changing b into b:source).

@smimram thanks, now it works with writing simply b. Just tested with the 2.0.1 image.

Unfortunately, it's only the syntax, fading still does not work for me. @FlorianReiterer did you manage to get it working?

gammaw commented 2 years ago

Same here. My code is something like this (after the hint above upon which I got it running by changing b into b:source).

@smimram thanks, now it works with writing simply b. Just tested with the 2.0.1 image.

I was wrong about that. When inside a transitions function in a switch, the sequence(merge=true, [fade.out(duration=5., a),(b:source)]) syntax works but sequence(merge=true, [fade.out(duration=5., a),b]) does not.

FlorianReiterer commented 2 years ago

Unfortunately, it's only the syntax, fading still does not work for me. @FlorianReiterer did you manage to get it working?

unsolved but on dev's list; Mr. Toots sort of confirmed an issue with this and said he was going to look at it sometime. Hang in there, help is coming :)

toots commented 2 years ago

I would suggest to look at: https://github.com/savonet/liquidsoap/discussions/2123#discussioncomment-1870488. It contains an implementation of a clean fade out/fade in with a skip when switching back and forth to a live show using cross. This is the right way to do it I believe.

Gonna close it since the original issue was a syntax one. Please re-open/open new issues or follow-up with conversations as appropriate. Thanks!