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.45k stars 131 forks source link

Stereotool not working with 2.3.0+git@d32d50956 #4102

Closed RM-FM closed 3 months ago

RM-FM commented 3 months ago

Description

Stereotool (10.30) doesn't seem to work with Azuracast (branch dev-ls2.3.x). Based on the error messages, it appears the issue is related to LS 2.3.0 rather than Azuracast.

Azuracast discussion thread: https://github.com/AzuraCast/AzuraCast/discussions/7354

2024/08/20 14:33:26 >>> LOG START
2024/08/20 14:33:14 [ffmpeg.filter.bitstream:3] No valid mode found for filter pgs_frame_merge!
2024/08/20 14:33:14 [main:3] Liquidsoap 2.3.0+git@d32d50956
2024/08/20 14:33:14 [main:3] Using: alsa=0.3.0 angstrom=0.16.0 ao=0.2.4 asetmap=0.8.1 asn1-combinators=0.2.6 astring=0.8.5 base=v0.16.3 base.base_internalhash_types=v0.16.3 base.caml=v0.16.3 base.shadow_stdlib=v0.16.3 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 camlp-streams camomile.lib=2.0 cohttp=5.3.1 cohttp-lwt=5.3.0 cohttp-lwt-unix=5.3.0 conduit=6.2.3 conduit-lwt=6.2.3 conduit-lwt-unix=6.2.3 cry=1.0.3 cstruct=6.2.0 ctypes=0.22.0 ctypes-foreign=0.22.0 ctypes.stubs=0.22.0 curl=0.9.2 domain-name=0.4.0 domain_shims dssi=0.1.5 dtools=0.4.5 dune-build-info=3.16.0 dune-private-libs.dune-section=3.16.0 dune-site=3.16.0 dune-site.private=3.16.0 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.2.0 ffmpeg-avcodec=1.2.0 ffmpeg-avdevice=1.2.0 ffmpeg-avfilter=1.2.0 ffmpeg-avutil=1.2.0 ffmpeg-swresample=1.2.0 ffmpeg-swscale=1.2.0 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.1 gen=1.1 gmap=0.3.0 hkdf=1.0.4 inotify=2.0-62-g5e58536 integers ipaddr=5.6.0 ipaddr-sexp=5.6.0 ipaddr.unix=5.6.0 irc-client irc-client-unix ladspa=0.2.2 lame=0.3.7 lastfm=0.3.4 lilv=0.2.0 liquidsoap-lang=2.3.0 liquidsoap-lang.console=2.3.0 liquidsoap_alsa=rolling-release-v2.3.x-5-gd32d509 liquidsoap_ao=rolling-release-v2.3.x-5-gd32d509 liquidsoap_bjack=rolling-release-v2.3.x-5-gd32d509 liquidsoap_builtins=rolling-release-v2.3.x-5-gd32d509 liquidsoap_core=rolling-release-v2.3.x-5-gd32d509 liquidsoap_dssi=rolling-release-v2.3.x-5-gd32d509 liquidsoap_faad=rolling-release-v2.3.x-5-gd32d509 liquidsoap_fdkaac=rolling-release-v2.3.x-5-gd32d509 liquidsoap_ffmpeg=rolling-release-v2.3.x-5-gd32d509 liquidsoap_flac=rolling-release-v2.3.x-5-gd32d509 liquidsoap_frei0r=rolling-release-v2.3.x-5-gd32d509 liquidsoap_gd=rolling-release-v2.3.x-5-gd32d509 liquidsoap_irc=rolling-release-v2.3.x-5-gd32d509 liquidsoap_ladspa=rolling-release-v2.3.x-5-gd32d509 liquidsoap_lame=rolling-release-v2.3.x-5-gd32d509 liquidsoap_lastfm=rolling-release-v2.3.x-5-gd32d509 liquidsoap_lilv=rolling-release-v2.3.x-5-gd32d509 liquidsoap_lo=rolling-release-v2.3.x-5-gd32d509 liquidsoap_mad=rolling-release-v2.3.x-5-gd32d509 liquidsoap_ogg=rolling-release-v2.3.x-5-gd32d509 liquidsoap_ogg_flac=rolling-release-v2.3.x-5-gd32d509 liquidsoap_optionals=rolling-release-v2.3.x-5-gd32d509 liquidsoap_opus=rolling-release-v2.3.x-5-gd32d509 liquidsoap_osc=rolling-release-v2.3.x-5-gd32d509 liquidsoap_oss=rolling-release-v2.3.x-5-gd32d509 liquidsoap_portaudio=rolling-release-v2.3.x-5-gd32d509 liquidsoap_posix_time=rolling-release-v2.3.x-5-gd32d509 liquidsoap_prometheus=rolling-release-v2.3.x-5-gd32d509 liquidsoap_pulseaudio=rolling-release-v2.3.x-5-gd32d509 liquidsoap_runtime=rolling-release-v2.3.x-5-gd32d509 liquidsoap_samplerate=rolling-release-v2.3.x-5-gd32d509 liquidsoap_sdl=rolling-release-v2.3.x-5-gd32d509 liquidsoap_sdl_log_level=rolling-release-v2.3.x-5-gd32d509 liquidsoap_shine=rolling-release-v2.3.x-5-gd32d509 liquidsoap_soundtouch=rolling-release-v2.3.x-5-gd32d509 liquidsoap_speex=rolling-release-v2.3.x-5-gd32d509 liquidsoap_sqlite=rolling-release-v2.3.x-5-gd32d509 liquidsoap_srt=rolling-release-v2.3.x-5-gd32d509 liquidsoap_ssl=rolling-release-v2.3.x-5-gd32d509 liquidsoap_stdlib=rolling-release-v2.3.x-5-gd32d509 liquidsoap_stereotool=rolling-release-v2.3.x-5-gd32d509 liquidsoap_theora=rolling-release-v2.3.x-5-gd32d509 liquidsoap_tls=rolling-release-v2.3.x-5-gd32d509 liquidsoap_vorbis=rolling-release-v2.3.x-5-gd32d509 liquidsoap_xmlplaylist=rolling-release-v2.3.x-5-gd32d509 liquidsoap_yaml=rolling-release-v2.3.x-5-gd32d509 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.6.0 mad=0.5.3 magic-mime=1.3.1 mem_usage=0.1.1 memtrace=0.2.3 menhirLib=20231231 metadata=0.3.0 mirage-crypto=0.11.3 mirage-crypto-ec=0.11.3 mirage-crypto-pk=0.11.3 mirage-crypto-rng=0.11.3 mirage-crypto-rng.unix=0.11.3 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 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_compare.runtime-lib=v0.16.0 ppx_hash.runtime-lib=v0.16.0 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=3.2 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 sqlite3=5.1.0 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=rolling-release-v2.3.x-5-gd32d509 str=[distributed with Ocaml] stringext=1.6.0 theora=0.4.1 theora.decoder=0.4.1 threads=[distributed with Ocaml] threads.posix=[internal] tls=0.17.4 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.2.0 yaml.bindings=3.2.0 yaml.bindings.types=3.2.0 yaml.c=3.2.0 yaml.ffi=3.2.0 yaml.types=3.2.0 zarith=1.13
2024/08/20 14:33:14 [main:3] 
2024/08/20 14:33:14 [main:3] DISCLAIMER: This version of Liquidsoap has been compiled from a snapshot of the
2024/08/20 14:33:14 [main:3] development code. As such, it should not be used in production unless you know
2024/08/20 14:33:14 [main:3] what you are doing!
2024/08/20 14:33:14 [main:3] 
2024/08/20 14:33:14 [main:3] We are, however, very interested in any feedback about our development code and
2024/08/20 14:33:14 [main:3] committed to fix issues as soon as possible.
2024/08/20 14:33:14 [main:3] 
2024/08/20 14:33:14 [main:3] If you are interested in collaborating to the development of Liquidsoap, feel
2024/08/20 14:33:14 [main:3] free to drop us a mail at <savonet-devl@lists.sf.net> or to join the slack chat
2024/08/20 14:33:14 [main:3] at <http://slack.liquidsoap.info>.
2024/08/20 14:33:14 [main:3] 
2024/08/20 14:33:14 [main:3] Please send any bug report or feature request at
2024/08/20 14:33:14 [main:3] <https://github.com/savonet/liquidsoap/issues>.
2024/08/20 14:33:14 [main:3] 
2024/08/20 14:33:14 [main:3] We hope you enjoy this snapshot build of Liquidsoap!
2024/08/20 14:33:14 [main:3] 
2024/08/20 14:33:14 [clock:3] Using native (high-precision) implementation for latency control
2024/08/20 14:33:26 [frame:3] Using 44100Hz audio, 25Hz video, 44100Hz main.
2024/08/20 14:33:26 [frame:3] Video frame size set to: 1280x720
2024/08/20 14:33:26 [frame:3] Targeting 'frame.duration': 0.02s = 882 ticks.
2024/08/20 14:33:26 [main:3] User script loaded in 10.27 seconds.
2024/08/20 14:33:26 [sandbox:3] Sandboxing disabled
2024/08/20 14:33:26 [startup:3] DSSI plugins registration: 0.00s
2024/08/20 14:33:26 [startup:3] FFmpeg filters registration: 0.08s
2024/08/20 14:33:26 [startup:3] FFmpeg bitstream filters registration: 0.01s
2024/08/20 14:33:26 [startup:3] Error while saving cache: Sys_error("/var/cache/liquidsoap/tmp79dc09.liq-cache: Permission denied")
2024/08/20 14:33:26 [startup:3] Lilv plugins registration: 0.02s
2024/08/20 14:33:26 [startup:3] Frei0r plugin registration: 0.00s
2024/08/20 14:33:26 [startup:3] Error while saving cache: Sys_error("/var/cache/liquidsoap/tmp8b0e1a.liq-cache: Permission denied")
2024/08/20 14:33:26 [startup:3] LADSPA plugins registration: 0.10s
2024/08/20 14:33:26 [startup:3] main script hash computation: 0.08s
2024/08/20 14:33:26 [startup:3] main script cache retrieval: 0.08s
2024/08/20 14:33:26 [startup:3] stdlib hash computation: 0.06s
2024/08/20 14:33:26 [startup:3] stdlib cache retrieval: 0.06s
2024/08/20 14:33:26 [startup:3] Typechecking stdlib: 8.57s
2024/08/20 14:33:26 [startup:3] Error while saving cache: Sys_error("/var/cache/liquidsoap/tmp99a76a.liq-cache: Permission denied")
2024/08/20 14:33:26 [startup:3] Typechecking main script: 0.37s
2024/08/20 14:33:26 [startup:3] Error while saving cache: Sys_error("/root/.cache: Permission denied")
2024/08/20 14:33:26 [startup:3] Evaluating main script: 0.12s
2024/08/20 14:33:26 [clock:3] Starting clock generic with 11 source(s) and sync: auto
2024/08/20 14:33:26 [clock:3] Starting clock generic.child.child with 20 source(s) and sync: passive
2024/08/20 14:33:26 [video.converter:3] Using preferred video converter: ffmpeg.
2024/08/20 14:33:26 [audio.converter:3] Using samplerate converter: libsamplerate.
2024/08/20 14:33:26 [error_jingle:3] Content type is {audio=pcm(stereo)}.
2024/08/20 14:33:26 [error_jingle:3] /usr/local/share/icecast/web/error.mp3 is static, resolving once for all...
2024/08/20 14:33:26 [video.text:3] Using sdl implementation
2024/08/20 14:33:26 [decoder.ffmpeg:3] Requested content-type for "/usr/local/share/icecast/web/error.mp3": {audio=pcm(stereo)}
2024/08/20 14:33:26 [decoder.ffmpeg:3] FFmpeg recognizes "/usr/local/share/icecast/web/error.mp3" as audio: {codec: mp3, 44100Hz, 2 channel(s)}
2024/08/20 14:33:26 [decoder.ffmpeg:3] Decoded content-type for "/usr/local/share/icecast/web/error.mp3": {audio=pcm(stereo)}
2024/08/20 14:33:26 [request.dynamic.6:3] Content type is {audio=pcm(stereo)}.
2024/08/20 14:33:26 [request.dynamic.6:3] Prepared "/usr/local/share/icecast/web/error.mp3" (RID 2).
2024/08/20 14:33:26 [metadata_map:3] Content type is {}.
2024/08/20 14:33:26 [metadata_map.2:3] Content type is {audio=pcm(stereo)}.
2024/08/20 14:33:26 [cross:3] Content type is {audio=pcm(stereo)}.
2024/08/20 14:33:26 [amplify:3] Content type is {audio=pcm(stereo)}.
2024/08/20 14:33:26 [interrupting_fallback:3] Content type is {audio=pcm(stereo)}.
2024/08/20 14:33:26 [interrupting_requests:3] Content type is {audio=pcm(stereo)}.
2024/08/20 14:33:26 [requests_fallback:3] Content type is {audio=pcm(stereo)}.
2024/08/20 14:33:26 [requests:3] Content type is {audio=pcm(stereo)}.
2024/08/20 14:33:26 [autodj_fallback:3] Content type is {audio=pcm(stereo)}.
2024/08/20 14:33:26 [dynamic_startup:3] Content type is {audio=pcm(stereo)}.
2024/08/20 14:33:26 [next_song:3] Content type is {audio=pcm(stereo)}.
2024/08/20 14:33:26 [source.available:3] Content type is {audio=pcm(stereo)}.
2024/08/20 14:33:26 [autodj_startup_blank:3] Content type is {audio=pcm(stereo)}.
2024/08/20 14:33:26 [switch.4:3] Content type is {audio=pcm(stereo)}.
2024/08/20 14:33:26 [on_track.2:3] Content type is {audio=pcm(stereo)}.
2024/08/20 14:33:26 [switch.3:3] Content type is {audio=pcm(stereo)}.
2024/08/20 14:33:26 [source:3] Content type is {audio=pcm(stereo)}.
2024/08/20 14:33:26 [playlist_jingles:3] Content type is {audio=pcm(stereo)}.
2024/08/20 14:33:26 [standard_playlists:3] Content type is {audio=pcm(stereo)}.
2024/08/20 14:33:26 [on_track:3] Content type is {audio=pcm(stereo)}.
2024/08/20 14:33:26 [switch:3] Content type is {audio=pcm(stereo)}.
2024/08/20 14:33:26 [playlist_default:3] Content type is {audio=pcm(stereo)}.
2024/08/20 14:33:26 [track_amplify:3] Content type is {audio=pcm(stereo)}.
2024/08/20 14:33:26 [track_metadata_deduplicate:3] Content type is {}.
2024/08/20 14:33:26 [metadata_deduplicate:3] Content type is {audio=pcm(stereo)}.
2024/08/20 14:33:26 [custom_metadata:3] Content type is {audio=pcm(stereo)}.
2024/08/20 14:33:26 [safe_fallback:3] Content type is {audio=pcm(stereo)}.
2024/08/20 14:33:26 [metadata_map.3:3] Content type is {}.
2024/08/20 14:33:26 [metadata_map.4:3] Content type is {audio=pcm(stereo)}.
2024/08/20 14:33:26 [local_1:3] Content type is {audio=pcm(stereo)}.
2024/08/20 14:33:26 [local_1:3] Content type is {audio=pcm(stereo)}.
2024/08/20 14:33:26 [lang:3] API nextsong - Sending POST request to 'http://127.0.0.1:6010/api/internal/2/liquidsoap/nextsong' with body: 
2024/08/20 14:33:26 [safe_fallback:3] Switch to metadata_map.2.
[mp3float @ 0x7fdd2c00a600] Could not update timestamps for skipped samples.
2024/08/20 14:33:26 [local_1:3] Connecting mount /radio.mp3 for source@127.0.0.1...
2024/08/20 14:33:26 [autocue.cue_file:3] Now autocueing: "/var/azuracast/stations/test230/media/radiomonster.fm_-_dropin_03.mp3"
2024/08/20 14:33:26 [autocue.cue_file:3] Blank (silence) skipping active: false, set to 0.0 s
2024/08/20 14:33:26 [autocue.cue_file:3] Clipping prevention active: false
2024/08/20 14:33:26 [autocue.cue_file:3] Writing tags: false, including ReplayGain: false
2024/08/20 14:33:26 [autocue.cue_file:3] Writing metadata to /tmp/cue_file9746bc.json
2024/08/20 14:33:26 [local_1:3] Connection setup was successful.
2024/08/20 14:33:26 [lang:3] API nextsong - Response (200): autocue:annotate:title="Chills (Feel My Love)",artist="Oliver Heldens, David Guetta, Fast Boy",duration="163.42",song_id="35132b33cd2691e7d29d07d89d94e9da",media_id="48",liq_amplify="-9.26 dB",liq_amplify_adjustment="0.00 dB",liq_autocue="cue_file",liq_blank_skipped="false",liq_blankskip="0.00",liq_cross_end_duration="2.00",liq_cross_max_start_duration="160.60",liq_cross_start_duration="0.10",liq_cue_duration="162.60",liq_cue_in="0.00",liq_cue_out="162.60",liq_fade_in="0.10",liq_fade_out="2.00",liq_fade_out_delay="0.00",liq_fade_out_start_next="0.00",liq_longtail="false",liq_loudness="-6.74 LUFS",liq_loudness_range="4.87 LU",liq_reference_loudness="-16.00 LUFS",liq_sustained_ending="false",liq_true_peak="1.16",liq_true_peak_db="1.31 dBFS",replaygain_reference_loudness="-16.00 LUFS",replaygain_track_gain="-9.26 dB",playlist_id="3":media:oliver_heldens,_david_guetta,_fast_boy_-_chills_(feel_my_love).mp3
2024/08/20 14:33:26 [autocue.cue_file:3] Now autocueing: "/var/azuracast/stations/test230/media/oliver_heldens,_david_guetta,_fast_boy_-_chills_(feel_my_love).mp3"
2024/08/20 14:33:26 [autocue.cue_file:3] Blank (silence) skipping active: false, set to 0.0 s
2024/08/20 14:33:26 [autocue.cue_file:3] Clipping prevention active: false
2024/08/20 14:33:26 [autocue.cue_file:3] Writing tags: false, including ReplayGain: false
2024/08/20 14:33:26 [autocue.cue_file:3] Writing metadata to /tmp/cue_filef02148.json
2024/08/20 14:33:27 [autocue.cue_file:3] cue_file result for "/var/azuracast/stations/test230/media/radiomonster.fm_-_dropin_03.mp3": {"duration": 16.613878, "liq_cue_duration": 5.2, "liq_cue_in": 0.0, "liq_cue_out": 5.2, "liq_cross_start_next": 5.1, "liq_longtail": false, "liq_sustained_ending": true, "liq_loudness": "-6.02 LUFS", "liq_loudness_range": "14.44 LU", "liq_amplify": "-9.98 dB", "liq_amplify_adjustment": "0.00 dB", "liq_reference_loudness": "-16.00 LUFS", "liq_blankskip": 0.0, "liq_blank_skipped": false, "liq_true_peak": 1.1, "liq_true_peak_db": "0.85 dBFS"}
2024/08/20 14:33:27 [autocue.cue_file:3] Replaced liq_amplify=-9.98 dB with -9.98 dB from adjusted replaygain_track_gain
2024/08/20 14:33:27 [autocue.cue_file:3] Given fade-out (0.1 s) < overlay duration (0.1 s), moving cue-out point from 5.2 s to 5.2 s.
2024/08/20 14:33:27 [autocue.cue_file:3] Metadata added/corrected for "/var/azuracast/stations/test230/media/radiomonster.fm_-_dropin_03.mp3":
2024/08/20 14:33:27 [autocue.cue_file:3] ("duration", "16.613878")
2024/08/20 14:33:27 [autocue.cue_file:3] ("liq_amplify", "-9.98 dB")
2024/08/20 14:33:27 [autocue.cue_file:3] ("liq_amplify_adjustment", "0.00 dB")
2024/08/20 14:33:27 [autocue.cue_file:3] ("liq_autocue", "cue_file")
2024/08/20 14:33:27 [autocue.cue_file:3] ("liq_blank_skipped", "false")
2024/08/20 14:33:27 [autocue.cue_file:3] ("liq_blankskip", "0.00")
2024/08/20 14:33:27 [autocue.cue_file:3] ("liq_cross_end_duration", "0.10")
2024/08/20 14:33:27 [autocue.cue_file:3] ("liq_cross_max_start_duration", "5.10")
2024/08/20 14:33:27 [autocue.cue_file:3] ("liq_cross_start_duration", "0.10")
2024/08/20 14:33:27 [autocue.cue_file:3] ("liq_cross_start_next", "5.1")
2024/08/20 14:33:27 [autocue.cue_file:3] ("liq_cue_duration", "5.20")
2024/08/20 14:33:27 [autocue.cue_file:3] ("liq_cue_in", "0.00")
2024/08/20 14:33:27 [autocue.cue_file:3] ("liq_cue_out", "5.2")
2024/08/20 14:33:27 [autocue.cue_file:3] ("liq_fade_in", "0.1")
2024/08/20 14:33:27 [autocue.cue_file:3] ("liq_fade_out", "0.1")
2024/08/20 14:33:27 [autocue.cue_file:3] ("liq_fade_out_delay", "0.00")
2024/08/20 14:33:27 [autocue.cue_file:3] ("liq_fade_out_start_next", "0.00")
2024/08/20 14:33:27 [autocue.cue_file:3] ("liq_longtail", "false")
2024/08/20 14:33:27 [autocue.cue_file:3] ("liq_loudness", "-6.02 LUFS")
2024/08/20 14:33:27 [autocue.cue_file:3] ("liq_loudness_range", "14.44 LU")
2024/08/20 14:33:27 [autocue.cue_file:3] ("liq_reference_loudness", "-16.00 LUFS")
2024/08/20 14:33:27 [autocue.cue_file:3] ("liq_sustained_ending", "true")
2024/08/20 14:33:27 [autocue.cue_file:3] ("liq_true_peak", "1.10")
2024/08/20 14:33:27 [autocue.cue_file:3] ("liq_true_peak_db", "0.85 dBFS")
2024/08/20 14:33:27 [autocue.cue_file:3] ("replaygain_reference_loudness", "-16.00 LUFS")
2024/08/20 14:33:27 [autocue.cue_file:3] ("replaygain_track_gain", "-9.98 dB")
2024/08/20 14:33:27 [decoder.ffmpeg:3] Requested content-type for "/var/azuracast/stations/test230/media/radiomonster.fm_-_dropin_03.mp3": {audio=pcm(stereo)}
2024/08/20 14:33:27 [decoder.ffmpeg:3] FFmpeg recognizes "/var/azuracast/stations/test230/media/radiomonster.fm_-_dropin_03.mp3" as audio: {codec: mp3, 44100Hz, 2 channel(s)}
2024/08/20 14:33:27 [decoder.ffmpeg:3] Decoded content-type for "/var/azuracast/stations/test230/media/radiomonster.fm_-_dropin_03.mp3": {audio=pcm(stereo)}
2024/08/20 14:33:27 [playlist_jingles:3] Prepared "/var/azuracast/stations/test230/media/radiomonster.fm_-_dropin_03.mp3" (RID 3).
2024/08/20 14:33:27 [switch.3:3] Switch to source.
2024/08/20 14:33:27 [switch.4:3] Switch to on_track.2.
2024/08/20 14:33:27 [autodj_fallback:3] Switch to switch.4.
2024/08/20 14:33:27 [requests_fallback:3] Switch to autodj_fallback.
2024/08/20 14:33:27 [interrupting_fallback:3] Switch to requests_fallback.
2024/08/20 14:33:27 [cross.buffer:3] Content type is {audio=pcm(stereo)}.
[mp3float @ 0x7fdd2c0b2740] Could not update timestamps for skipped samples.
2024/08/20 14:33:27 [autocue.cue_file:3] Now autocueing: "/var/azuracast/stations/test230/media/quavo,_lenny_kravitz_-_fly.mp3"
2024/08/20 14:33:27 [autocue.cue_file:3] Blank (silence) skipping active: false, set to 0.0 s
2024/08/20 14:33:27 [autocue.cue_file:3] Clipping prevention active: false
2024/08/20 14:33:27 [autocue.cue_file:3] Writing tags: false, including ReplayGain: false
2024/08/20 14:33:27 [autocue.cue_file:3] Writing metadata to /tmp/cue_filebe6269.json
2024/08/20 14:33:27 [switch.4:3] Switch to source with transition.
2024/08/20 14:33:27 [threads:3] Thread "Clock generic" aborts with exception Invalid_argument("Content.sub")!
Thread 2 killed on uncaught exception Invalid_argument("Content.sub")
Raised at Content_base.MkContentBase.sub in file "src/core/stream/content_base.ml", line 275, characters 6-44
Called from Content_base.MkContentBase.(fun) in file "src/core/stream/content_base.ml", line 438, characters 43-71
Called from Liquidsoap_lang__Methods.map.(fun) in file "src/lang/methods.ml", line 38, characters 41-45
Called from Stdlib__List.map in file "list.ml", line 92, characters 20-23
Called from Source.operator#get_partial_frame in file "src/core/source.ml", line 354, characters 17-35
Called from Source.generate_from_multiple_sources#generate_frame.f in file "src/core/source.ml", line 642, characters 18-278
Called from Source.generate_from_multiple_sources#generate_frame in file "src/core/source.ml", line 653, characters 29-65
Called from Source.operator#instrumented_generate_frame in file "src/core/source.ml", line 514, characters 45-64
Called from Source.operator#before_streaming_cycle.(fun) in file "src/core/source.ml", line 317, characters 43-75
Called from Source.operator#peek_frame in file "src/core/source.ml", line 349, characters 12-17
Called from Source.operator#get_partial_frame in file "src/core/source.ml", line 354, characters 20-35
Called from Source.generate_from_multiple_sources#generate_frame in file "src/core/source.ml", line 620, characters 16-37
Called from Source.operator#instrumented_generate_frame in file "src/core/source.ml", line 514, characters 45-64
Called from Source.operator#before_streaming_cycle.(fun) in file "src/core/source.ml", line 317, characters 43-75
Called from Source.operator#peek_frame in file "src/core/source.ml", line 349, characters 12-17
Called from Source.operator#get_partial_frame in file "src/core/source.ml", line 354, characters 20-35
Called from Source.generate_from_multiple_sources#generate_frame in file "src/core/source.ml", line 620, characters 16-37
Called from Source.operator#instrumented_generate_frame in file "src/core/source.ml", line 514, characters 45-64
Called from Source.operator#before_streaming_cycle.(fun) in file "src/core/source.ml", line 317, characters 43-75
Called from Source.operator#peek_frame in file "src/core/source.ml", line 349, characters 12-17
Called from Source.operator#get_partial_frame in file "src/core/source.ml", line 354, characters 20-35
Called from Source.generate_from_multiple_sources#generate_frame in file "src/core/source.ml", line 620, characters 16-37
Called from Source.operator#instrumented_generate_frame in file "src/core/source.ml", line 514, characters 45-64
Called from Source.operator#before_streaming_cycle.(fun) in file "src/core/source.ml", line 317, characters 43-75
Called from Source.operator#peek_frame in file "src/core/source.ml", line 349, characters 12-17
Called from Source.operator#get_partial_frame in file "src/core/source.ml", line 354, characters 20-35
Called from Muxer.muxer#generate_frame.(fun) in file "src/core/operators/muxer.ml", line 84, characters 22-38
Called from Stdlib__List.fold_left in file "list.ml", line 121, characters 24-34
Called from Muxer.muxer#generate_frame in file "src/core/operators/muxer.ml", line 82, characters 8-486
Called from Source.operator#instrumented_generate_frame in file "src/core/source.ml", line 514, characters 45-64
Called from Source.operator#before_streaming_cycle.(fun) in file "src/core/source.ml", line 317, characters 43-75
Called from Source.operator#peek_frame in file "src/core/source.ml", line 349, characters 12-17
Called from Source.operator#get_partial_frame in file "src/core/source.ml", line 354, characters 20-35
Called from Cross.cross#child_get.(fun) in file "src/core/operators/cross.ml", line 191, characters 14-212
Called from Liquidsoap_lang__Queues.Queue.flush_iter.f in file "src/lang/queues.ml", line 32, characters 12-17
Called from Clock._tick in file "src/core/clock.ml", line 402, characters 2-76
Called from Cross.cross#child_get in file "src/core/operators/cross.ml", line 188, characters 6-304
Called from Cross.cross#buffer_before in file "src/core/operators/cross.ml", line 295, characters 24-55
Called from Cross.cross#prepare_before in file "src/core/operators/cross.ml", line 272, characters 6-42
Called from Cross.cross#get_source in file "src/core/operators/cross.ml", line 278, characters 45-64
Called from Source.generate_from_multiple_sources#can_generate_frame in file "src/core/source.ml", line 585, characters 8-101
Called from Source.operator#before_streaming_cycle in file "src/core/source.ml", line 310, characters 37-60
Called from Source.operator#is_ready in file "src/core/source.ml", line 275, characters 8-35
Called from Source.operator#before_streaming_cycle in file "src/core/source.ml", line 310, characters 37-60
Called from Source.operator#is_ready in file "src/core/source.ml", line 275, characters 8-35
Called from Muxer.muxer#sources_ready.(fun) in file "src/core/operators/muxer.ml" (inlined), line 50, characters 58-68
Called from Stdlib__List.for_all in file "list.ml", line 164, characters 12-15
Called from Source.operator#before_streaming_cycle in file "src/core/source.ml", line 310, characters 37-60
Called from Source.operator#is_ready in file "src/core/source.ml", line 275, characters 8-35
Called from Source.operator#before_streaming_cycle in file "src/core/source.ml", line 310, characters 37-60
Called from Source.operator#is_ready in file "src/core/source.ml", line 275, characters 8-35
Called from Switch.find.aux in file "src/core/operators/switch.ml", line 57, characters 11-14
Called from Switch.switch#select in file "src/core/operators/switch.ml", line 108, characters 13-184
Called from Switch.switch#get_source in file "src/core/operators/switch.ml", line 137, characters 18-213
Called from Source.generate_from_multiple_sources#can_generate_frame in file "src/core/source.ml", line 585, characters 8-101
Called from Source.operator#before_streaming_cycle in file "src/core/source.ml", line 310, characters 37-60
Called from Source.operator#is_ready in file "src/core/source.ml", line 275, characters 8-35
Called from Source.operator#before_streaming_cycle in file "src/core/source.ml", line 310, characters 37-60
Called from Source.operator#is_ready in file "src/core/source.ml", line 275, characters 8-35
Called from Clock_base.self_sync.(fun) in file "src/core/clock_base.ml", line 148, characters 13-23
Called from Stdlib__List.fold_left in file "list.ml", line 121, characters 24-34
Called from Clock_base.self_sync.(fun) in file "src/core/clock_base.ml", line 146, characters 6-319
Called from Clock._self_sync.(fun) in file "src/core/clock.ml", line 292, characters 14-25
Called from Stdlib__List.fold_left in file "list.ml", line 121, characters 24-34
Called from Clock._self_sync in file "src/core/clock.ml", line 290, characters 4-272
Called from Clock._after_tick in file "src/core/clock.ml", line 335, characters 17-36
Called from Clock._clock_thread.run in file "src/core/clock.ml", line 434, characters 8-22
Called from Tutils.create.(fun).process in file "src/core/tools/tutils.ml", line 174, characters 12-15
Re-raised at Tutils.create.(fun).process in file "src/core/tools/tutils.ml", line 218, characters 14-52
Called from Thread.create.(fun) in file "thread.ml", line 49, characters 8-14
2024/08/20 14:33:27 [threads:3] Main loop exited
2024/08/20 14:33:27 [main:3] Shutdown started!
2024/08/20 14:33:27 [threads:3] Waiting for main threads to terminate...
2024/08/20 14:33:27 [threads:3] Main threads terminated.
2024/08/20 14:33:27 [threads:3] Shutting down scheduler...
2024/08/20 14:33:27 [next_song:2] Error while fetching next request: Tutils.Exit
2024/08/20 14:33:27 [threads:3] Scheduler shut down.
2024/08/20 14:33:27 [main:3] Cleaning downloaded files...
2024/08/20 14:33:27 [main:3] Freeing memory...
2024/08/20 14:33:27 >>> LOG END
Fatal error: exception Invalid_argument("Content.sub")
Raised at Content_base.MkContentBase.sub in file "src/core/stream/content_base.ml", line 275, characters 6-44
Called from Content_base.MkContentBase.(fun) in file "src/core/stream/content_base.ml", line 438, characters 43-71
Called from Liquidsoap_lang__Methods.map.(fun) in file "src/lang/methods.ml", line 38, characters 41-45
Called from Stdlib__List.map in file "list.ml", line 92, characters 20-23
Called from Source.operator#get_partial_frame in file "src/core/source.ml", line 354, characters 17-35
Called from Source.generate_from_multiple_sources#generate_frame.f in file "src/core/source.ml", line 642, characters 18-278
Called from Source.generate_from_multiple_sources#generate_frame in file "src/core/source.ml", line 653, characters 29-65
Called from Source.operator#instrumented_generate_frame in file "src/core/source.ml", line 514, characters 45-64
Called from Source.operator#before_streaming_cycle.(fun) in file "src/core/source.ml", line 317, characters 43-75
Called from Source.operator#peek_frame in file "src/core/source.ml", line 349, characters 12-17
Called from Source.operator#get_partial_frame in file "src/core/source.ml", line 354, characters 20-35
Called from Source.generate_from_multiple_sources#generate_frame in file "src/core/source.ml", line 620, characters 16-37
Called from Source.operator#instrumented_generate_frame in file "src/core/source.ml", line 514, characters 45-64
Called from Source.operator#before_streaming_cycle.(fun) in file "src/core/source.ml", line 317, characters 43-75
Called from Source.operator#peek_frame in file "src/core/source.ml", line 349, characters 12-17
Called from Source.operator#get_partial_frame in file "src/core/source.ml", line 354, characters 20-35
Called from Source.generate_from_multiple_sources#generate_frame in file "src/core/source.ml", line 620, characters 16-37
Called from Source.operator#instrumented_generate_frame in file "src/core/source.ml", line 514, characters 45-64
Called from Source.operator#before_streaming_cycle.(fun) in file "src/core/source.ml", line 317, characters 43-75
Called from Source.operator#peek_frame in file "src/core/source.ml", line 349, characters 12-17
Called from Source.operator#get_partial_frame in file "src/core/source.ml", line 354, characters 20-35
Called from Source.generate_from_multiple_sources#generate_frame in file "src/core/source.ml", line 620, characters 16-37
Called from Source.operator#instrumented_generate_frame in file "src/core/source.ml", line 514, characters 45-64
Called from Source.operator#before_streaming_cycle.(fun) in file "src/core/source.ml", line 317, characters 43-75
Called from Source.operator#peek_frame in file "src/core/source.ml", line 349, characters 12-17
Called from Source.operator#get_partial_frame in file "src/core/source.ml", line 354, characters 20-35
Called from Muxer.muxer#generate_frame.(fun) in file "src/core/operators/muxer.ml", line 84, characters 22-38
Called from Stdlib__List.fold_left in file "list.ml", line 121, characters 24-34
Called from Muxer.muxer#generate_frame in file "src/core/operators/muxer.ml", line 82, characters 8-486
Called from Source.operator#instrumented_generate_frame in file "src/core/source.ml", line 514, characters 45-64
Called from Source.operator#before_streaming_cycle.(fun) in file "src/core/source.ml", line 317, characters 43-75
Called from Source.operator#peek_frame in file "src/core/source.ml", line 349, characters 12-17
Called from Source.operator#get_partial_frame in file "src/core/source.ml", line 354, characters 20-35
Called from Cross.cross#child_get.(fun) in file "src/core/operators/cross.ml", line 191, characters 14-212
Called from Liquidsoap_lang__Queues.Queue.flush_iter.f in file "src/lang/queues.ml", line 32, characters 12-17
Called from Clock._tick in file "src/core/clock.ml", line 402, characters 2-76
Called from Cross.cross#child_get in file "src/core/operators/cross.ml", line 188, characters 6-304
Called from Cross.cross#buffer_before in file "src/core/operators/cross.ml", line 295, characters 24-55
Called from Cross.cross#prepare_before in file "src/core/operators/cross.ml", line 272, characters 6-42
Called from Cross.cross#get_source in file "src/core/operators/cross.ml", line 278, characters 45-64
Called from Source.generate_from_multiple_sources#can_generate_frame in file "src/core/source.ml", line 585, characters 8-101
Called from Source.operator#before_streaming_cycle in file "src/core/source.ml", line 310, characters 37-60
Called from Source.operator#is_ready in file "src/core/source.ml", line 275, characters 8-35
Called from Source.operator#before_streaming_cycle in file "src/core/source.ml", line 310, characters 37-60
Called from Source.operator#is_ready in file "src/core/source.ml", line 275, characters 8-35
Called from Muxer.muxer#sources_ready.(fun) in file "src/core/operators/muxer.ml" (inlined), line 50, characters 58-68
Called from Stdlib__List.for_all in file "list.ml", line 164, characters 12-15
Called from Source.operator#before_streaming_cycle in file "src/core/source.ml", line 310, characters 37-60
Called from Source.operator#is_ready in file "src/core/source.ml", line 275, characters 8-35
Called from Source.operator#before_streaming_cycle in file "src/core/source.ml", line 310, characters 37-60
Called from Source.operator#is_ready in file "src/core/source.ml", line 275, characters 8-35
Called from Switch.find.aux in file "src/core/operators/switch.ml", line 57, characters 11-14
Called from Switch.switch#select in file "src/core/operators/switch.ml", line 108, characters 13-184
Called from Switch.switch#get_source in file "src/core/operators/switch.ml", line 137, characters 18-213
Called from Source.generate_from_multiple_sources#can_generate_frame in file "src/core/source.ml", line 585, characters 8-101
Called from Source.operator#before_streaming_cycle in file "src/core/source.ml", line 310, characters 37-60
Called from Source.operator#is_ready in file "src/core/source.ml", line 275, characters 8-35
Called from Source.operator#before_streaming_cycle in file "src/core/source.ml", line 310, characters 37-60
Called from Source.operator#is_ready in file "src/core/source.ml", line 275, characters 8-35
Called from Clock_base.self_sync.(fun) in file "src/core/clock_base.ml", line 148, characters 13-23
Called from Stdlib__List.fold_left in file "list.ml", line 121, characters 24-34
Called from Clock_base.self_sync.(fun) in file "src/core/clock_base.ml", line 146, characters 6-319
Called from Clock._self_sync.(fun) in file "src/core/clock.ml", line 292, characters 14-25
Called from Stdlib__List.fold_left in file "list.ml", line 121, characters 24-34
Called from Clock._self_sync in file "src/core/clock.ml", line 290, characters 4-272
Called from Clock._after_tick in file "src/core/clock.ml", line 335, characters 17-36
Called from Clock._clock_thread.run in file "src/core/clock.ml", line 434, characters 8-22
Called from Tutils.create.(fun).process in file "src/core/tools/tutils.ml", line 174, characters 12-15
Re-raised at Tutils.exit in file "src/core/tools/tutils.ml", line 68, characters 34-70
Called from Stdlib__List.iter in file "list.ml", line 110, characters 12-15
Called from Stdlib__List.iter in file "list.ml", line 110, characters 12-15
Called from Stdlib__List.iter in file "list.ml", line 110, characters 12-15
Called from Stdlib__List.iter in file "list.ml", line 110, characters 12-15
Called from Stdlib__List.iter in file "list.ml", line 110, characters 12-15
Called from Stdlib__List.iter in file "list.ml", line 110, characters 12-15
Called from Stdlib__List.iter in file "list.ml", line 110, characters 12-15
Called from Dune__exe__Liquidsoap in file "src/bin/liquidsoap.ml", line 1, characters 9-41

Steps to reproduce

  1. Upload Stereotool 10.30 binary to Azuracast
  2. Restart station (Liquidsoap)

Expected behavior

Steretool 10.30 to work with Liquidsoap 2.3.x RR

Liquidsoap version

Liquidsoap 2.3.0+git@d32d50956
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.3.0+git@d32d50956

 * Compilation options
   - Release build       : false
   - Git SHA             : d32d50956
   - OCaml version       : 4.14.2
   - OS type             : Unix
   - Libs versions       : alsa=0.3.0 angstrom=0.16.0 ao=0.2.4 asetmap=0.8.1 asn1-combinators=0.2.6 astring=0.8.5 base=v0.16.3 base.base_internalhash_types=v0.16.3 base.caml=v0.16.3 base.shadow_stdlib=v0.16.3 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 camlp-streams camomile.lib=2.0 cohttp=5.3.1 cohttp-lwt=5.3.0 cohttp-lwt-unix=5.3.0 conduit=6.2.3 conduit-lwt=6.2.3 conduit-lwt-unix=6.2.3 cry=1.0.3 cstruct=6.2.0 ctypes=0.22.0 ctypes-foreign=0.22.0 ctypes.stubs=0.22.0 curl=0.9.2 domain-name=0.4.0 domain_shims dssi=0.1.5 dtools=0.4.5 dune-build-info=3.16.0 dune-private-libs.dune-section=3.16.0 dune-site=3.16.0 dune-site.private=3.16.0 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.2.0 ffmpeg-avcodec=1.2.0 ffmpeg-avdevice=1.2.0 ffmpeg-avfilter=1.2.0 ffmpeg-avutil=1.2.0 ffmpeg-swresample=1.2.0 ffmpeg-swscale=1.2.0 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.1 gen=1.1 gmap=0.3.0 hkdf=1.0.4 inotify=2.0-62-g5e58536 integers ipaddr=5.6.0 ipaddr-sexp=5.6.0 ipaddr.unix=5.6.0 irc-client irc-client-unix ladspa=0.2.2 lame=0.3.7 lastfm=0.3.4 lilv=0.2.0 liquidsoap-lang=2.3.0 liquidsoap-lang.console=2.3.0 liquidsoap_alsa=rolling-release-v2.3.x-5-gd32d509 liquidsoap_ao=rolling-release-v2.3.x-5-gd32d509 liquidsoap_bjack=rolling-release-v2.3.x-5-gd32d509 liquidsoap_builtins=rolling-release-v2.3.x-5-gd32d509 liquidsoap_core=rolling-release-v2.3.x-5-gd32d509 liquidsoap_dssi=rolling-release-v2.3.x-5-gd32d509 liquidsoap_faad=rolling-release-v2.3.x-5-gd32d509 liquidsoap_fdkaac=rolling-release-v2.3.x-5-gd32d509 liquidsoap_ffmpeg=rolling-release-v2.3.x-5-gd32d509 liquidsoap_flac=rolling-release-v2.3.x-5-gd32d509 liquidsoap_frei0r=rolling-release-v2.3.x-5-gd32d509 liquidsoap_gd=rolling-release-v2.3.x-5-gd32d509 liquidsoap_irc=rolling-release-v2.3.x-5-gd32d509 liquidsoap_ladspa=rolling-release-v2.3.x-5-gd32d509 liquidsoap_lame=rolling-release-v2.3.x-5-gd32d509 liquidsoap_lastfm=rolling-release-v2.3.x-5-gd32d509 liquidsoap_lilv=rolling-release-v2.3.x-5-gd32d509 liquidsoap_lo=rolling-release-v2.3.x-5-gd32d509 liquidsoap_mad=rolling-release-v2.3.x-5-gd32d509 liquidsoap_ogg=rolling-release-v2.3.x-5-gd32d509 liquidsoap_ogg_flac=rolling-release-v2.3.x-5-gd32d509 liquidsoap_optionals=rolling-release-v2.3.x-5-gd32d509 liquidsoap_opus=rolling-release-v2.3.x-5-gd32d509 liquidsoap_osc=rolling-release-v2.3.x-5-gd32d509 liquidsoap_oss=rolling-release-v2.3.x-5-gd32d509 liquidsoap_portaudio=rolling-release-v2.3.x-5-gd32d509 liquidsoap_posix_time=rolling-release-v2.3.x-5-gd32d509 liquidsoap_prometheus=rolling-release-v2.3.x-5-gd32d509 liquidsoap_pulseaudio=rolling-release-v2.3.x-5-gd32d509 liquidsoap_runtime=rolling-release-v2.3.x-5-gd32d509 liquidsoap_samplerate=rolling-release-v2.3.x-5-gd32d509 liquidsoap_sdl=rolling-release-v2.3.x-5-gd32d509 liquidsoap_sdl_log_level=rolling-release-v2.3.x-5-gd32d509 liquidsoap_shine=rolling-release-v2.3.x-5-gd32d509 liquidsoap_soundtouch=rolling-release-v2.3.x-5-gd32d509 liquidsoap_speex=rolling-release-v2.3.x-5-gd32d509 liquidsoap_sqlite=rolling-release-v2.3.x-5-gd32d509 liquidsoap_srt=rolling-release-v2.3.x-5-gd32d509 liquidsoap_ssl=rolling-release-v2.3.x-5-gd32d509 liquidsoap_stdlib=rolling-release-v2.3.x-5-gd32d509 liquidsoap_stereotool=rolling-release-v2.3.x-5-gd32d509 liquidsoap_theora=rolling-release-v2.3.x-5-gd32d509 liquidsoap_tls=rolling-release-v2.3.x-5-gd32d509 liquidsoap_vorbis=rolling-release-v2.3.x-5-gd32d509 liquidsoap_xmlplaylist=rolling-release-v2.3.x-5-gd32d509 liquidsoap_yaml=rolling-release-v2.3.x-5-gd32d509 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.6.0 mad=0.5.3 magic-mime=1.3.1 mem_usage=0.1.1 memtrace=0.2.3 menhirLib=20231231 metadata=0.3.0 mirage-crypto=0.11.3 mirage-crypto-ec=0.11.3 mirage-crypto-pk=0.11.3 mirage-crypto-rng=0.11.3 mirage-crypto-rng.unix=0.11.3 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 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_compare.runtime-lib=v0.16.0 ppx_hash.runtime-lib=v0.16.0 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=3.2 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 sqlite3=5.1.0 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=rolling-release-v2.3.x-5-gd32d509 str=[distributed with Ocaml] stringext=1.6.0 theora=0.4.1 theora.decoder=0.4.1 threads=[distributed with Ocaml] threads.posix=[internal] tls=0.17.4 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.2.0 yaml.bindings=3.2.0 yaml.bindings.types=3.2.0 yaml.c=3.2.0 yaml.ffi=3.2.0 yaml.types=3.2.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
   - user cache        : $HOME/.cache/liquidsoap (override with $LIQ_CACHE_USER_DIR)
   - system cache      : /var/cache/liquidsoap (override with $LIQ_CACHE_SYSTEM_DIR)
   - 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
   - WAV/AIFF          : yes (native)

 * 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
   - WAV/AIFF          : yes (native)

 * Tags
   - AAC               : yes
   - FFmpeg            : yes
   - FLAC (native)     : yes
   - Flac (ogg)        : yes
   - Native decoder    : yes
   - Vorbis            : yes

 * Input / output
   - ALSA              : yes
   - AO                : yes
   - FFmpeg            : yes
   - 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        : no (requires camlimages)
   - 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          : no (requires jemalloc)
   - lastfm            : yes
   - lo                : yes
   - memtrace          : no (requires memtrace)
   - osc               : yes
   - ssl               : yes
   - sqlite3           : yes
   - tls               : yes
   - posix-time2       : yes
   - windows service   : no (requires winsvc)
   - YAML support      : yes
   - XML playlists     : yes

 * Monitoring
   - Prometheus        : yes

Installation method

From official packages in the release artifacts

Additional Info

No response

toots commented 3 months ago

Thanks for the report! For reference, a copy of the AzuraCast script would help a lot as we are not responsible not knowledgable of its content.

toots commented 3 months ago

Yeah, I'm gonna need a little more details around the stereotool integration. This simple reproduction script works fine:

s = playlist("~/sources/test-stream/audio")

s =
  stereotool(
    library_file="/path/to/shared/lib",
    s
  )

output.ao(fallible=true, s)
RM-FM commented 3 months ago

Thanks for the report! For reference, a copy of the AzuraCast script would help a lot as we are not responsible not knowledgable of its content.

# WARNING! This file is automatically generated by AzuraCast.
# Do not update it directly!

init.daemon.set(false)
init.daemon.pidfile.path.set("/var/azuracast/stations/test230/config/liquidsoap.pid")

log.stdout.set(true)
log.file.set(false)

settings.server.log.level.set(4)

settings.server.socket.set(true)
settings.server.socket.permissions.set(0o660)
settings.server.socket.path.set("/var/azuracast/stations/test230/config/liquidsoap.sock")

settings.harbor.bind_addrs.set(["0.0.0.0"])
settings.encoder.metadata.export.set(["artist","title","album","song"])

environment.set("TZ", "UTC")

autodj_is_loading = ref(true)
ignore(autodj_is_loading)

autodj_ping_attempts = ref(0)
ignore(autodj_ping_attempts)

# Track live-enabled status.
live_enabled = ref(false)
ignore(live_enabled)

# Track live transition for crossfades.
to_live = ref(false)
ignore(to_live)

# Reimplement LS's now-deprecated drop_metadata function.
def drop_metadata(~id=null(), s)
    let {metadata=_, ...tracks} = source.tracks(s)
    source(id=id, tracks)
end

# Transport for HTTPS outputs.
https_transport = http.transport.ssl()
ignore(https_transport)

azuracast_api_url = "http://127.0.0.1:6010/api/internal/2/liquidsoap"
azuracast_api_key = "(PASSWORD)"

def azuracast_api_call(~timeout=2.0, url, payload) =
    full_url = "#{azuracast_api_url}/#{url}"

    log("API #{url} - Sending POST request to '#{full_url}' with body: #{payload}")
    try
        response = http.post(full_url,
            headers=[
                ("Content-Type", "application/json"),
                ("User-Agent", "Liquidsoap AzuraCast"),
                ("X-Liquidsoap-Api-Key", "#{azuracast_api_key}")
            ],
            timeout=timeout,
            data=payload
        )

        log("API #{url} - Response (#{response.status_code}): #{response}")
        "#{response}"
    catch err do
        log("API #{url} - Error: #{error.kind(err)} - #{error.message(err)}")
        "false"
    end
end

station_media_dir = "/var/azuracast/stations/test230/media"
def azuracast_media_protocol(~rlog=_,~maxtime=_,arg) =
    "#{station_media_dir}/#{arg}"
end

protocol.add(
    "media",
    azuracast_media_protocol,
    doc="Pull files from AzuraCast media directory.",
    syntax="media:uri"
)

# AutoCue
%include "/var/azuracast/autocue/autocue.liq"

settings.autocue.cue_file.nice := true
settings.request.prefetch := 2

# Custom Configuration (Specified in Station Profile)
settings.autocue.cue_file.fade_out := 6.0  # seconds
settings.autocue.cue_file.target := -16.0  # LUFS#
settings.autocue.cue_file.sustained_loudness_drop := 40.0
settings.autocue.cue_file.overlay_longtail := -12.0  # extra LU

# Ensure AutoCue settings are valid
ignore(check_autocue_setup(shutdown=true, print=false))

playlist_default = playlist(id="playlist_default",mime_type="audio/x-mpegurl",mode="random",reload_mode="watch","/var/azuracast/stations/test230/playlists/playlist_default.m3u")

playlist_jingles = playlist(id="playlist_jingles",mime_type="audio/x-mpegurl",mode="normal",reload_mode="watch","/var/azuracast/stations/test230/playlists/playlist_jingles.m3u")
playlist_jingles = drop_metadata(playlist_jingles)

# Standard Playlists
radio = random(id="standard_playlists", weights=[3], [playlist_default])

# Once per x Songs Playlists
radio = rotate(weights=[1,2], [playlist_jingles, radio])

# AutoDJ Next Song Script
def autodj_next_song() =
    response = azuracast_api_call(
        "nextsong",
        ""
    )
    if (response == "") or (response == "false") then
        null()
    else
        request.create(response)
    end
end

# Delayed ping for AutoDJ Next Song
def wait_for_next_song(autodj)
    autodj_ping_attempts.set(autodj_ping_attempts() + 1)

    if source.is_ready(autodj) then
        log("AutoDJ is ready!")
        autodj_is_loading.set(false)
        -1.0
    elsif autodj_ping_attempts() > 200 then
        log("AutoDJ could not be initialized within the specified timeout.")
        autodj_is_loading.set(false)
        -1.0
    else
        0.5
    end
end

dynamic = request.dynamic(id="next_song", timeout=settings.autocue.cue_file.timeout(), retry_delay=10., autodj_next_song)

dynamic_startup = fallback(
    id = "dynamic_startup",
    track_sensitive = false,
    [
        dynamic,
        source.available(
            blank(id = "autodj_startup_blank", duration = 120.),
            predicate.activates({autodj_is_loading()})
        )
    ]
)
radio = fallback(id="autodj_fallback", track_sensitive = true, [dynamic_startup, radio])

ref_dynamic = ref(dynamic);
thread.run.recurrent(delay=0.25, { wait_for_next_song(ref_dynamic()) })

requests = request.queue(id="requests", timeout=settings.autocue.cue_file.timeout())
radio = fallback(id="requests_fallback", track_sensitive = true, [requests, radio])

interrupting_queue = request.queue(id="interrupting_requests", timeout=settings.autocue.cue_file.timeout())
radio = fallback(id="interrupting_fallback", track_sensitive = false, [interrupting_queue, radio])

# Skip command (used by web UI)
def add_skip_command(s) =
    def skip(_) =
        source.skip(s)
        "Done!"
    end

    server.register(namespace="radio", usage="skip", description="Skip the current song.", "skip",skip)
end

add_skip_command(radio)

# Apply amplification metadata (if supplied)
radio = amplify(override="liq_amplify", 1., radio)

# Show metadata in log (Debug)
def show_meta(m)
    label="show_meta"
    l = list.sort.natural(metadata.cover.remove(m))
    list.iter(fun(v) -> log(level=4, label=label, "#{v}"), l)

    nowplaying = ref(m["artist"] ^ " - " ^ m["title"])

    if m["artist"] == "" then
        if string.contains(substring=" - ", m["title"]) then
            let (a, t) = string.split.first(separator=" - ", m["title"])
            nowplaying := a ^ " - " ^ t
        end
    end

    # show `liq_` & other metadata in level 3
    def fl(k, _) =
        tags = ["duration", "media_id", "replaygain_track_gain", "replaygain_reference_loudness"]
        string.contains(prefix="liq_", k) or list.mem(k, tags)
    end

    liq = list.assoc.filter((fl), l)
    list.iter(fun(v) -> log(level=3, label=label, "#{v}"), liq)
    log(level=3, label=label, "Now playing: #{nowplaying()}")

    if m["liq_amplify"] == "" then
        log(level=2, label=label, "Warning: No liq_amplify found, expect loudness jumps!")
    end
    if m["liq_blank_skipped"] == "true" then
        log(level=2, label=label, "Blank (silence) detected in track, ending early.")
    end
end

radio.on_metadata(show_meta)

# Fading/crossing/segueing
def live_aware_crossfade(old, new) =
    if to_live() then
        # If going to the live show, play a simple sequence
        # fade out AutoDJ, do (almost) not fade in streamer
        sequence([
          fade.out(duration=settings.autocue.cue_file.fade_out(), old.source),
          fade.in(duration=settings.autocue.cue_file.fade_in(), new.source)
        ])
    else
        # Otherwise, use a beautiful add
        add(normalize=false, [
            fade.in(
                initial_metadata=new.metadata,
                duration=settings.autocue.cue_file.fade_in(),
                new.source
            ),
            fade.out(
                initial_metadata=old.metadata,
                duration=settings.autocue.cue_file.fade_out(),
                old.source
            )
        ])
    end
end

radio = cross(
    duration=settings.autocue.cue_file.fade_out(),
    live_aware_crossfade,
    radio
)

# Stereo Tool Pipe
radio = stereotool(
    library_file="/var/azuracast/storage/stereo_tool/libStereoTool_intel64.so",
    license_key="(LICENSE_KEY)",
    preset="/var/azuracast/stations/test230/config/stereo-tool.sts",
    radio
)

# Allow for Telnet-driven insertion of custom metadata.
radio = server.insert_metadata(id="custom_metadata", radio)

error_file = single(id="error_jingle", "/usr/local/share/icecast/web/error.mp3")

def tag_error_file(m) =
    ignore(m)
    [("is_error_file", "true")]
end
error_file = metadata.map(tag_error_file, error_file)

radio = fallback(id="safe_fallback", track_sensitive = false, [radio, error_file])

# Send metadata changes back to AzuraCast
last_title = ref("")
last_artist = ref("")

def metadata_updated(m) =
    def f() =
        if (m["is_error_file"] != "true") then
            if (m["title"] != last_title() or m["artist"] != last_artist()) then
                last_title.set(m["title"])
                last_artist.set(m["artist"])

                # Only send some metadata to AzuraCast
                def fl(k, _) =
                    tags = ["song_id", "media_id", "playlist_id", "artist", "title"]
                    string.contains(prefix="liq_", k) or string.contains(prefix="replaygain_", k) or list.mem(k, tags)
                end

                feedback_meta = list.assoc.filter((fl), metadata.cover.remove(m))

                j = json()
                for item = list.iterator(feedback_meta) do
                    let (tag, value) = item
                    j.add(tag, value)
                end

                _ = azuracast_api_call(
                    "feedback",
                    json.stringify(compact=true, j)
                )
            end
        end
    end

    thread.run(f)
end

radio.on_metadata(metadata_updated)

# Handle "Jingle Mode" tracks by replaying the previous metadata.
last_metadata = ref([])
def handle_jingle_mode(m) =
    if (m["jingle_mode"] == "true") then
        last_metadata()
    else
        last_metadata.set(m)
        m
    end
end

radio = metadata.map(update=false, strip=true, handle_jingle_mode, radio)

# Local Broadcasts
output.icecast(%mp3(samplerate=44100, stereo=true, bitrate=320), id="local_1", host = "127.0.0.1", port = 8000, password = "(PASSWORD)", mount = "/radio.mp3", name = "Test230", description = "", genre = "", public = false, encoding = "UTF-8", radio)

# Remote Relays
RM-FM commented 3 months ago

I can confirm that the issue has been resolved in the fix-empty-frame branch.

toots commented 3 months ago

That's awesome. Let me get another pass at cleaning the base fix and we should be good to go.