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 129 forks source link

Error after adding autocue.cue_file.liq #4057

Open iSerganov opened 2 months ago

iSerganov commented 2 months ago

Description

Tried to add loudness normalization to my .liq script.

Versions: Liquidsoap v2.2.5 autocue.cue_file.liq and cue_file v4.1.0

.liq file:

%include "autocue.cue_file.liq"
settings.autocue.cue_file.noclip := true  # clipping prevention
settings.autocue.cue_file.nice := true  # Linux/MacOS only!
enable_autocue_metadata()
ignore(check_autocue_setup(shutdown=true, print=true))
# Log dir
log.file.path.set("/tmp/basic-radio.log")

# Music
myplaylist = playlist("/playlist.pls",reload_mode="watch",mode="normal")
myplaylist.on_track(print)
# If something goes wrong, we'll play this
noiseS = noise()

radio = myplaylist

# apply loudness normalization
radio = amplify(1., override="liq_amplify", radio)

# And finally the security
radio = fallback(track_sensitive = false, [radio, noiseS])

# Stream it out
output.icecast(%mp3,
  host = environment.get("ICECAST_HOST"), port = int_of_string(environment.get("ICECAST_PORT")),
  password = environment.get("ICECAST_PASS"), mount = environment.get("MOUNT_ENDPOINT"),
  radio)

Autocue check passes fine.

When a track playback starts an error occurs in runtime:

liquidsoap  | Thread 3 killed on uncaught exception Unix.Unix_error(_, "", "")
liquidsoap  | Raised at Errno_unix.with_unix_exn in file "unix/errno_unix.ml", line 451, characters 43-64
liquidsoap  | Called from Posix_time2.clock_nanosleep in file "posix-time2/src/posix_time2.ml" (inlined), line 272, characters 2-427
liquidsoap  | Called from Liq_posix_time.Sys_time.sleep_until in file "src/core/tools/liq_posix_time.ml", line 51, characters 8-124
liquidsoap  | Called from Clock.MkClock.clock#run.loop in file "src/core/clock.ml", line 256, characters 40-63
liquidsoap  | Called from Clock.MkClock.clock#run in file "src/core/clock.ml", line 280, characters 8-15
liquidsoap  | Called from Tutils.create.(fun).process in file "src/core/tools/tutils.ml", line 186, characters 12-15
liquidsoap  | Re-raised at Tutils.create.(fun).process in file "src/core/tools/tutils.ml", line 230, characters 14-52
liquidsoap  | Called from Thread.create.(fun) in file "thread.ml", line 49, characters 8-14
liquidsoap  | Fatal error: exception Unix.Unix_error(Unix.EUNKNOWNERR 0, "", "")
liquidsoap  | Raised at Errno_unix.with_unix_exn in file "unix/errno_unix.ml", line 451, characters 43-64
liquidsoap  | Called from Posix_time2.clock_nanosleep in file "posix-time2/src/posix_time2.ml" (inlined), line 272, characters 2-427
liquidsoap  | Called from Liq_posix_time.Sys_time.sleep_until in file "src/core/tools/liq_posix_time.ml", line 51, characters 8-124
liquidsoap  | Called from Clock.MkClock.clock#run.loop in file "src/core/clock.ml", line 256, characters 40-63
liquidsoap  | Called from Clock.MkClock.clock#run in file "src/core/clock.ml", line 280, characters 8-15
liquidsoap  | Called from Tutils.create.(fun).process in file "src/core/tools/tutils.ml", line 186, characters 12-15
liquidsoap  | Re-raised at Tutils.exit in file "src/core/tools/tutils.ml", line 68, characters 34-70
liquidsoap  | Called from Stdlib__List.iter in file "list.ml", line 110, characters 12-15
liquidsoap  | Called from Stdlib__List.iter in file "list.ml", line 110, characters 12-15
liquidsoap  | Called from Stdlib__List.iter in file "list.ml", line 110, characters 12-15
liquidsoap  | Called from Stdlib__List.iter in file "list.ml", line 110, characters 12-15
liquidsoap  | Called from Stdlib__List.iter in file "list.ml", line 110, characters 12-15
liquidsoap  | Called from Stdlib__List.iter in file "list.ml", line 110, characters 12-15
liquidsoap  | Called from Stdlib__List.iter in file "list.ml", line 110, characters 12-15
liquidsoap  | Called from Dune__exe__Liquidsoap in file "src/bin/liquidsoap.ml", line 1, characters 9-41
liquidsoap exited with code 2

And liquidsoap crashes.

Track data from the console:

liquidsoap  | [("liq_amplify_adjustment", "0.00 dB"), ("liq_cue_out", "303."), ("liq_cue_duration", "303.00"), ("compatible_brands", "iso6mp41"), ("on_air_timestamp", "1721859494.00"), ("kind", "{audio=pcm(stereo)}"), ("liq_blank_skipped", "false"), ("decoder", "ffmpeg"), ("liq_cross_duration", "2.5"), ("liq_cue_in", "0."), ("filename", "/tmp/liq-process059d7b.mp3"), ("liq_sustained_ending", "true"), ("encoding", "Lavf57.56.101"), ("temporary", "true"), ("source", "playlist_pls"), ("initial_uri", "http://some.awesome.mp3"), ("liq_cross_start_next", "300.5"), ("liq_fade_out", "2.5"), ("liq_true_peak", "0.233"), ("major_brand", "dash"), ("liq_fade_out_delay", "0."), ("liq_reference_loudness", "-18.00 LUFS"), ("status", "playing"), ("encoder", "Lavf57.56.101"), ("liq_longtail", "false"), ("replaygain_reference_loudness", "-18.00 LUFS"), ("replaygain_track_gain", "6.87 dB"), ("minor_version", "0"), ("liq_loudness_range", "9.36 LU"), ("on_air", "2024/07/24 22:18:14"), ("liq_autocue", "cue_file"), ("liq_fade_in", "0.1"), ("rid", "2"), ("liq_loudness", "-24.87 LUFS"), ("duration", "303.490612"), ("liq_amplify", "6.87 dB"), ("liq_blankskip", "0."), ("liq_true_peak_db", "-12.65 dBFS")]

Issue starts only after adding the latest %include "autocue.cue_file.liq".

Steps to reproduce

Include the latest https://github.com/Moonbase59/autocue/blob/master/autocue.cue_file.liq file into your .liq config file and load your playlist with MP3 files.

Expected behavior

No runtime exception and Liquidsoap crash.

Liquidsoap version

Liquidsoap 2.2.5
Copyright (c) 2003-2024 Savonet team
Liquidsoap is open-source software, released under GNU General Public License.
See <http://liquidsoap.info> for more information.

Liquidsoap build config

* Liquidsoap version  : 2.2.5

 * Compilation options
   - Release build       : true
   - Git SHA             : (none)
   - OCaml version       : 4.14.1
   - OS type             : Unix
   - Libs versions       : alsa=0.3.0 angstrom=0.15.0 ao=0.2.4 asetmap=0.8.1 asn1-combinators=0.2.6 astring=0.8.5 base64=3.5.1 bigarray=[distributed with Ocaml] bigarray-compat=1.1.0 bigstringaf=0.9.1 bjack=0.1.6 bos=0.2.1 bytes=[distributed with OCaml 4.02 or above] ca-certs=v0.2.3 camlimages.all_formats=4.2.6 camlimages.core=5.0.4 camlimages.exif=5.0.4 camlimages.gif=5.0.4 camlimages.jpeg=5.0.4 camlimages.png=5.0.4 camlimages.tiff=5.0.4 camlimages.xpm=5.0.4 camlp-streams camomile.lib=2.0 cohttp=5.3.0 cohttp-lwt=5.3.0 cohttp-lwt-unix=5.3.0 conduit=6.2.0 conduit-lwt=6.2.0 conduit-lwt-unix=6.2.0 cry=1.0.3 cstruct=6.2.0 ctypes=0.21.1 ctypes-foreign=0.21.1 ctypes.stubs=0.21.1 curl=0.9.2 domain-name=0.4.0 domain_shims dssi=0.1.5 dtools=0.4.5 dune-build-info=3.11.1 dune-private-libs.dune-section=3.11.1 dune-site=3.11.1 dune-site.private=3.11.1 duppy=0.9.4 eqaf=0.9 eqaf.bigstring=0.9 eqaf.cstruct=0.9 faad=0.5.2 fdkaac=0.3.3 ffmpeg-av=1.1.10 ffmpeg-avcodec=1.1.10 ffmpeg-avdevice=1.1.10 ffmpeg-avfilter=1.1.10 ffmpeg-avutil=1.1.10 ffmpeg-swresample=1.1.10 ffmpeg-swscale=1.1.10 fileutils=0.6.4 flac=0.5.1 flac.decoder=0.5.1 flac.ogg=0.5.1 fmt=0.9.0 fpath=0.7.3 frei0r=0.1.2 gd=1.0a5 gen=1.1 gmap=0.3.0 hkdf=1.0.4 inotify=2.4.1 integers ipaddr=5.5.0 ipaddr-sexp=5.5.0 ipaddr.unix=5.5.0 irc-client irc-client-unix jemalloc ladspa=0.2.2 lame=0.3.7 lastfm=0.3.4 lilv=0.1.0 liquidsoap-lang=2.2.5 liquidsoap-lang.console=2.2.5 liquidsoap_alsa=f0fdb0e-dirty liquidsoap_ao=f0fdb0e-dirty liquidsoap_bjack=f0fdb0e-dirty liquidsoap_builtins=f0fdb0e-dirty liquidsoap_camlimages=f0fdb0e-dirty liquidsoap_core=f0fdb0e-dirty liquidsoap_dssi=f0fdb0e-dirty liquidsoap_faad=f0fdb0e-dirty liquidsoap_fdkaac=f0fdb0e-dirty liquidsoap_ffmpeg=f0fdb0e-dirty liquidsoap_flac=f0fdb0e-dirty liquidsoap_frei0r=f0fdb0e-dirty liquidsoap_gd=f0fdb0e-dirty liquidsoap_irc=f0fdb0e-dirty liquidsoap_jemalloc=f0fdb0e-dirty liquidsoap_ladspa=f0fdb0e-dirty liquidsoap_lame=f0fdb0e-dirty liquidsoap_lastfm=f0fdb0e-dirty liquidsoap_lilv=f0fdb0e-dirty liquidsoap_lo=f0fdb0e-dirty liquidsoap_mad=f0fdb0e-dirty liquidsoap_mem_usage=f0fdb0e-dirty liquidsoap_memtrace=f0fdb0e-dirty liquidsoap_ogg=f0fdb0e-dirty liquidsoap_ogg_flac=f0fdb0e-dirty liquidsoap_optionals=f0fdb0e-dirty liquidsoap_opus=f0fdb0e-dirty liquidsoap_osc=f0fdb0e-dirty liquidsoap_oss=f0fdb0e-dirty liquidsoap_portaudio=f0fdb0e-dirty liquidsoap_posix_time=f0fdb0e-dirty liquidsoap_prometheus=f0fdb0e-dirty liquidsoap_pulseaudio=f0fdb0e-dirty liquidsoap_runtime=f0fdb0e-dirty liquidsoap_samplerate=f0fdb0e-dirty liquidsoap_sdl=f0fdb0e-dirty liquidsoap_shine=f0fdb0e-dirty liquidsoap_soundtouch=f0fdb0e-dirty liquidsoap_speex=f0fdb0e-dirty liquidsoap_srt=f0fdb0e-dirty liquidsoap_ssl=f0fdb0e-dirty liquidsoap_stereotool=f0fdb0e-dirty liquidsoap_taglib=f0fdb0e-dirty liquidsoap_theora=f0fdb0e-dirty liquidsoap_tls=f0fdb0e-dirty liquidsoap_vorbis=f0fdb0e-dirty liquidsoap_xmlplaylist=f0fdb0e-dirty liquidsoap_yaml=f0fdb0e-dirty lo=0.2.0 logs=0.7.0 logs.fmt=0.7.0 logs.lwt=0.7.0 lwt=5.7.0 lwt.unix=5.7.0 macaddr=5.5.0 mad=0.5.3 magic-mime=1.3.1 mem_usage=0.1.1 memtrace=0.2.3 menhirLib=20230608 metadata=0.3.0 mirage-crypto=0.11.2 mirage-crypto-ec=0.11.2 mirage-crypto-pk=0.11.2 mirage-crypto-rng=0.11.2 mirage-crypto-rng.unix=0.11.2 mm=0.8.5 mm.audio=0.8.5 mm.base=0.8.5 mm.image=0.8.5 mm.midi=0.8.5 mm.video=0.8.5 ocplib-endian ocplib-endian.bigstring ogg=0.7.4 ogg.decoder=0.7.4 opus=0.2.3 opus.decoder=0.2.3 osc osc-unix parsexp=v0.16.0 pbkdf pcre=7.5.0 portaudio=0.2.3 posix-base=5a7f328 posix-socket=5a7f328 posix-socket.constants=5a7f328 posix-socket.stubs=5a7f328 posix-socket.types=5a7f328 posix-time2=5a7f328 posix-time2.constants=5a7f328 posix-time2.stubs=5a7f328 posix-time2.types=5a7f328 posix-types=5a7f328 posix-types.constants=5a7f328 ppx_sexp_conv.runtime-lib=v0.16.0 prometheus=1.2 prometheus-app=1.2 ptime=1.1.0 ptime.clock.os=1.1.0 pulseaudio=0.1.6 re=1.11.0 result=1.5 rresult=0.7.0 samplerate=0.1.7 saturn_lockfree=0.4.1 sedlex=ccd3dea seq=[distributed with OCaml 4.07 or above] sexplib=v0.16.0 sexplib0=v0.16.0 shine=0.2.3 soundtouch=0.1.9 speex=0.4.2 speex.decoder=0.4.2 srt=0.3.1 srt.constants=0.3.1 srt.stubs=0.3.1 srt.stubs.locked=0.3.1 srt.types=0.3.1 ssl=0.7.0 stdlib-shims=0.3.0 stereotool=f0fdb0e-dirty str=[distributed with Ocaml] stringext=1.6.0 taglib=0.3.10 theora=0.4.1 theora.decoder=0.4.1 threads=[distributed with Ocaml] threads.posix=[internal] tls=0.17.1 tsdl=v1.0.0 tsdl-image=0.5 tsdl-ttf=0.6 unix=[distributed with Ocaml] unix-errno=52c6ecb unix-errno.errno_bindings=52c6ecb unix-errno.errno_types=52c6ecb unix-errno.errno_types_detected=52c6ecb unix-errno.unix=52c6ecb uri=4.4.0 uri-sexp=4.4.0 uri.services=4.4.0 vorbis=0.8.1 vorbis.decoder=0.8.1 x509=0.16.5 xmlm=1.4.0 xmlplaylist=0.1.5 yaml=3.1.0 yaml.bindings=3.1.0 yaml.bindings.types=3.1.0 yaml.c=3.1.0 yaml.ffi=3.1.0 yaml.types=3.1.0 zarith=1.13
   - architecture        : amd64
   - host                : x86_64-pc-linux-gnu
   - target              : x86_64-pc-linux-gnu
   - system              : linux
   - ocamlopt_cflags     : -O2 -fno-strict-aliasing -fwrapv -pthread -fPIC
   - native_c_compiler   : gcc -O2 -fno-strict-aliasing -fwrapv -pthread -fPIC -D_FILE_OFFSET_BITS=64
   - native_c_libraries  : -lm

 * Configured paths
   - mode              : posix
   - standard library  : /usr/share/liquidsoap/libs
   - scripted binaries : /usr/share/liquidsoap/bin
   - rundir            : /var/run/liquidsoap
   - logdir            : /var/log/liquidsoap
   - camomile files    : /usr/share/liquidsoap/camomile

 * Supported input formats
   - MP3               : yes
   - AAC               : yes
   - Ffmpeg            : yes
   - Flac (native)     : yes
   - Flac (ogg)        : yes
   - Opus              : yes
   - Speex             : yes
   - Theora            : yes
   - Vorbis            : yes

 * Supported output formats
   - FDK-AAC           : yes
   - Ffmpeg            : yes
   - MP3               : yes
   - MP3 (fixed-point) : yes
   - Flac (native)     : yes
   - Flac (ogg)        : yes
   - Opus              : yes
   - Speex             : yes
   - Theora            : yes
   - Vorbis            : yes

 * Tags
   - Taglib (ID3 tags) : yes
   - Vorbis            : yes

 * Input / output
   - ALSA              : yes
   - AO                : yes
   - FFmpeg            : yes
   - GStreamer         : no (requires gstreamer)
   - JACK              : yes
   - OSS               : yes
   - Portaudio         : yes
   - Pulseaudio        : yes
   - SRT               : yes

 * Audio manipulation
   - FFmpeg            : yes
   - LADSPA            : yes
   - Lilv              : yes
   - Samplerate        : yes
   - SoundTouch        : yes
   - StereoTool        : yes

 * Video manipulation
   - camlimages        : yes
   - FFmpeg            : yes
   - frei0r            : yes
   - ImageLib          : no (requires imagelib)
   - SDL               : yes

 * MIDI manipulation
   - DSSI              : yes

 * Visualization
   - GD                : yes
   - Graphics          : no (requires graphics)
   - SDL               : yes

 * Additional libraries
   - FFmpeg filters    : yes
   - FFmpeg devices    : yes
   - inotify           : yes
   - irc               : yes
   - jemalloc          : yes
   - lastfm            : yes
   - lo                : yes
   - memtrace          : yes
   - mem_usage         : yes
   - osc               : yes
   - ssl               : yes
   - tls               : yes
   - posix-time2       : yes
   - windows service   : no (requires winsvc)
   - YAML support      : yes
   - XML playlists     : yes

 * Monitoring
   - Prometheus        : yes

Installation method

From official container image

Additional Info

No response

iSerganov commented 2 months ago

Important update: the issue occurs when I run Liquidsoap docker container on my MacOS laptop (arm64). The very same Liquidsoap image works fine when running on linux based docker host. 🤷‍♂️

Moonbase59 commented 2 months ago

Hi @iSerganov, I’m away but took a quick look at the autocue.cue_file part. Your build config and script look good to me, can’t really see where the Unix error and clock issue could come from.

Unfortunately, I don’t have a MacOS arm64-based system to test, and don’t really know what’s in the Docker you use. autocue.cue_file wants Python3 (3.7+ I believe), ffmpeg and ̀ffprobe somewhere in the path, and (ideally, but optional) Python3 Mutagen be installed. Plus of course the cue_file executable (a Python script).

Please let me know should it turn out that there is an issue with autocue.cue_file—thanks!

iSerganov commented 2 months ago

@Moonbase59 , thanks for looking into this!

I am not familiar with OCaml and it's very difficult for me to say where the exact issue is, but I am hesitating to say that it is in autocue.cue_file (maybe it just triggers something that contains bug).

What I do clearly see is that it happens randomly regardless of the input track and it happens only when enable_autocue_metadata (https://github.com/savonet/liquidsoap/blob/27dda43947cdb39fca16a9fb435dc9f45bee1e4b/src/libs/autocue.liq#L932) is called after including autocue.cue_file into a .liq script.

So issue OCCURS:

%include "autocue.cue_file.liq"
enable_autocue_metadata()

Issue DOES NOT occur:

enable_autocue_metadata()

The exact exception happens in the posix_time2 module in a place that was added there in the latest release - v2.0.2.

I am not really sure what exactly makes it fail specifically when running official Liquidsoap image on my M1 MacBook while still working fine on Linux...

However I will be glad to help you to debug and troubleshoot it. Just let me know if any kind of additional information (debug logs, system info, etc.) may be helpful for the investigation - I will do my best to get it asap.