Skip to content

Releases: savonet/liquidsoap

Liquidsoap Rolling Release 2.4.x

02 Mar 22:15

Choose a tag to compare

Pre-release

This release provides liquidsoap assets before they are published as a new versioned release.

You can use it to install the latest stable code before it is published and test/prepare your production environment for it.

Rolling releases can also be useful for us to quickly detect and report bugs before the final published release!

⚠️ Warning ⚠️
Assets in this release will be deleted. If you are looking for permanent links to release assets, please head over to https://github.com/savonet/liquidsoap-release-assets/releases

For more details about our release process, please checkout https://github.com/savonet/liquidsoap#release-details

2.4.5 (unreleased)

Fixed:

  • Fixed crash when external input (input.process, input.ffmpeg, etc.) encounters an EOF (thanks to @MikaSappi, #5139)
  • Fixed harbor.remove_http_handler discarding all registered handlers except the one being removed

Optimized:

  • Clock sync-source propagation is now push-based and O(1) per tick instead of scanning all sources (#5133)
  • Stream format/kind dispatch now uses O(1) int-indexed array lookup instead of iterating a queue (#5136)
  • Optimized content_length and timed blit hot paths (#5137)
  • Chunk total length is now cached in the chunks record to avoid recomputation (#5140)
  • Chunk length is now pre-computed on lift (#5135)
  • Watcher before/after cycle callbacks are only registered when watchers are actually present
  • WeakQueue now uses geometric doubling and a RW-lock for faster concurrent access (#5118)
  • Use direct Int comparison functions in stream hot paths

Liquidsoap 2.4.4

20 Apr 14:30

Choose a tag to compare

This is a quick follow-up to Liquidsoap 2.4.3.

A big thank you to everyone who tested 2.4.3 and reported issues so swiftly — your feedback made this patch possible! We recommend skipping 2.4.3 entirely and migrating directly to 2.4.4.

Notable fixes

  • Shared encoder crash: A crash that could occur when multiple streams shared the same encoder, caused by incorrect child clock controller initialization, is now fixed.
  • input.harbor 403 response: Clients connecting to an already-taken mountpoint now receive a proper 403 error instead of a confusing "Unknown error".
  • Sub-clock leak: A leak that could cause gradual resource growth when on_sleep deregistered a source during has_stopped is resolved.
  • is_binary charset detection: A subtle bug that caused is_binary to skip charset conversion for non-UTF-8 text content is now corrected.

Liquidsoap 2.4.3

11 Apr 21:09

Choose a tag to compare

This is the third bugfix release of Liquidsoap 2.4.x.

This release has been extensively tested and should be rock solid. We still recommend trying it on your staging environment before rolling out to production.

This release is intended to be the last of the 2.4.x branch. We've already started working on 2.5.x and there are some exciting things in store!

⚠️ Note for Ubuntu Noble users: this is the last release that includes binary packages for Ubuntu Noble. To keep up with the latest FFmpeg releases, we need to move forward to more recent Ubuntu versions.

New features

  • Raw string syntax {|...|} and {id|...|id}: a new string literal form where no escape sequences or string interpolation (#{}) are processed. This is especially useful in automated or user-facing setups where external input (filenames, URLs, user-provided values) is embedded directly in a script — with regular strings, a value containing #{...} would be silently evaluated as code. Raw strings prevent this entirely, making scripts that handle untrusted input safer and more predictable.

Notable fixes

  • Audio glitches with crossfade: Two separate issues caused clicks or audio gaps when using cue points and crossfades together — both are now resolved.
  • HLS fMP4 audio+video: Multiplexed HLS streams using fragmented MP4 containers were broken; this is now fixed.
  • Playlist initialization slowdown: A performance regression that made large playlists slow to start is gone.
  • Process I/O reliability: Several edge cases around reading stdout/stderr and handling EINTR signal interruptions have been addressed, making external process integration more robust.
  • Sequence resource cleanup: The sequence operator now releases sources it no longer needs early, reducing resource usage in scripts with many fallback sources.
  • Better error messages: Invalid_value errors now include a call stack, making it much easier to track down where an invalid value originated at runtime.

📢 6th Liquidshop Workshop — Friday, 29 May 2026!

We're gearing up for the 6th Liquidshop workshop and we'd love to see you there! If you'd like to share what you've built or how you use Liquidsoap, please consider contributing a talk — and everyone is welcome to attend. We love connecting with the community!


2.4.3 (2026-04-11)

New:

  • Added raw string syntax {|...|} and {id|...|id} for strings
    with no escape sequences (#4959)
  • Added optional replay_metadata and add_new_track to
    the buffer operator to replay latest metadata and insert
    track marks when the buffer becomes available again.
  • Added support for array options in ffmpeg filters (#4799)

Changed:

  • DEPRECATED telnet/server request.on_air command is enabled when
    settings.request.deprecated_on_air_metadata is true.
  • Add back missing "status" telnet/server command for outputs.
  • Reduced default buffer size throughout the app to improve memory efficiency
    (#4919)
  • Refactored XML parsing to be type-driven, support optional fields with
    custom element name aliases (#4926, #4927)
  • Removed self_sync parameter from input.jack and output.jack (#5017)
  • Make posix build target paths configurable via env vars (#5046)

Fixed:

  • sequence now releases unused sources early, reducing resource usage when
    earlier sources in the sequence are no longer needed (#5082)
  • Improved error messages: Invalid_value errors now include the call stack
    to help pinpoint the origin of the invalid value (#5090)
  • Fixed clicks/glitches when combining liq_cue_in with liq_fade_in due to fade.in firing too late on new tracks (#5019)
  • Prevent crashing when getting out-of-bound mark in split_frame (#5054)
  • Fixed clock source detach when clock is running (#5051)
  • Fixed ?? operator type inference in conditional branches (#4922)
  • Prevent double nullable types (#4925)
  • Make active stereotool really be active.. (#4882)
  • Fixed fMP4 HLS support for audio+video streams (#4841)
  • Fixed crossfade clocks inconsistencies leading to weird caching audio glitches (#4851)
  • Fixed first frame of new track getting lost when crossfading with fade.in duration is set to 0. (#4887)
  • Fixed crash with concurrent stop/start operations (#4849)
  • Fixed metadata leak from underlying ffmpeg ogg demuxer in ffmpeg stream
    decoder (#4848)
  • Fixed performance regression when initializing playlist (#4913)
  • Make sure that we read all stdout/stderr before considering a process closed. (#4918, #4934, #4941)
  • Fixed EINTR signal interruption in process I/O, read, and flush operations (#4947, #4949, #4951)
  • Improved string binary detection heuristics by checking for valid UTF-8 and max length; added settings.string.max_printable_length configuration key
  • Make sure output.file does not create files without data (#4899)
  • Fixed content type propagation through free type variables (#4988)
  • Improved runtime error reporting by wrapping low-level exceptions into proper
    runtime errors (#5004)
  • Fixed syslog support and added it to build configuration detection (#5009)
  • Fixed sub-clock accumulation causing gradual CPU growth over time (#5032)

Liquidsoap 2.4.2

17 Jan 16:46

Choose a tag to compare

This is the second bugfix release of liquidsoap 2.4.x.

The first bugfix had some issues with sources not being properly cleaned up so this one is coming out right off the bat to fix this!

But, fear not, we have also added some exciting new changes to counterbalance!

As usual, please try this version on a staging/testing environment. Otherwise, we do believe it is safe to upgrade from any 2.4.0 or 2.4.1 version.

2.4.2 (2025-01-17)

New:

  • Added pretty-print of clocks and source graphs! Use via --describe-<clocks/sources> in the command line or clocks.dump and clocks.dump_sources on telnet/server! (#4837, #4836)

Changed:

  • Batch calls to thread.when to preserve performances, warn when using thread.when too intensively (#4832)
  • Added pretty-print of telnet help list of commands. This might break compatibility with automated telnet readers! (Remember: telnet is a user-facing API, not designed for machine consumption!).

Fixed:

  • Fixed sources leaks in source.dynamic (#4835)
  • Optimized Queues implementation: fast, atomic access, slow, mutex-protected mutation (#4831)

Liquidsoap 2.4.1

10 Jan 18:09

Choose a tag to compare

⚠️ This release has issues, please head over to https://github.com/savonet/liquidsoap/releases/tag/v2.4.2 ⚠️

This is the first bugfix release of the 2.4.x release cycle!

Most of the heavy lifting in terms of internal rewrite and new features has now been done we are now fully committed to bringing more stability and long-term enhancements to the framework.

This release should be safe to upgrade to for all users on the 2.4.0 release. In general, we strongly suggest migrating your code to our latest release: our resources are limited and the latest stable release if where we put all our efforts to fix bugs.

As usual, we do recommend testing the release on a staging/testing environment before pushing it to your production runtime.

A few new things with this release, mostly to facilitate user's life:

  • Initial metadata support for the %ffmpeg encoder to help support container-level setup such as DVB Service and Provider names (see: #4665)
  • start/stop server/telnet commands for outputs
  • A new settings.syslog.level to help set the syslog level.

Other important enhancements concern clocks and dynamic source collection, which is still a hotspot for us. If you're using a lot of dynamic sources and outputs, make sure to keep in touch with us, we want to keep making this as stable and usable as possible but we do not always think about all the possible use-case!

Lastly, the issues where large covert art binary data kept showing up in logs when logging metadata should finally be fixed! These strings are now tagged as binary internally and filtered out during logging/printing!

Here's the full changelog:

Liquidsoap 2.4.1 (2025-01-10)

New:

  • Added support for explicit metadata to pass to the output
    when creating a %ffmpeg encoder (#4667)
  • Added start/stop telnet commands for outputs.
  • Added settings.syslog.level to set syslog level (#4686)
  • Added active parameter to stereotool and output.stereotool (#4749)
  • Added file.mime.extension to get the file extension's associated
    with a MIME/content-type as registered in settings.http.mime.extnames

Changed:

  • Do not normalize sources in mix by default.
  • Added json.value to make it possible to mix different value
    types when returning json values (#4712)
  • Allow referring to pulseaudio devices by name (#4732)
  • output.shoutcast: make dj argument a getter.
  • Exclude metadata listed in settings.encoder.metadata.cover
    from automatic metadata recoding. (#4690)

Fixed:

  • Fix input.harbor initial metadata when switching with
    fades (#4736)
  • Fix audio artifact in crossfade transitions (#4739)
  • Make sure that sources re-used in source.dynamic are never
    inadvertently cleaned up (#4713)
  • Fix sources not being properly collected (#4670)
  • Raise a proper error on parse error raised during %include
    parsing.
  • Don't print metadata coverart string (#4730)
  • Make sure fetch always fetches a new request in request.dynamic (#4745)
  • Fixed start/stop logic in output.harbor (#4666)
  • Fixed fade.in/fade.out logic w.r.t. override metadata (#4759)
  • Fixed video.cover

Liquidsoap 2.4.0

18 Nov 04:39

Choose a tag to compare

The first release of the 2.4.x release cycle is out! 🎉✨

This release includes several new features focused on improving user's experience!

We have summarized the most important changes in our 2.4.0 blog post: https://www.liquidsoap.info/blog/2025-08-11-liquidsoap-2.4.0/

This release has been carefully tested and does not include any major rewrite of the core components. Therefore, we highly recommend switching to it as soon as possible.

As usual, however, we recommend testing your script in a staging environment before pushing to production. Please report any regression or issues to us and we will work on it as soon as time allows.

⚠️ Warning ⚠️
Assets in this release will be deleted. If you are looking for permanent links to release assets, please head over to https://github.com/savonet/liquidsoap-release-assets/releases

For more details about our release process, please checkout https://github.com/savonet/liquidsoap#release-details

2.4.0 (2025-09-01)

New:

Language:

  • Allow destructing function arguments using the same patterns as for
    variable assignment (#4562)
  • Enhanced labeled arguments syntax (#4526)
  • Add warning when erasing top-level variables (#4518)
  • null can now be used directly without having to call null().
    null(value) calls are still valid and can be used to create
    non-null values with nullable types. Calls to null() are marked
    as deprecated (#4516)
  • Added liquidsoap.script.path that contains the path to the current
    script's file, if available.

Core:

  • BREAKING: Most callbacks have been moved to source methods and are now
    executed asynchronously by default. See migration notes for all the
    details.
  • BREAKING: Added new file-to-file external decoder.add API. This
    makes it much easier and safer to write external decoders (#4531)
  • Deprecated insert_metadata, added default insert_metadata method on
    every source (#4541)
  • Added client certificate support to http.transport.tls (#4589, @DelilahHoare)

Utilities:

  • Added cron.parse, cron.{add,remove} and a cron thread
    to allow registration of cron-like asynchronous tasks (#4579)
  • Added LUFS-based per-track loudness correction (#4545)

Changed:

Language:

  • BREAKING: Error methods have been removed by default.
    Use error.methods to get them! (#4537)
  • Make sure that let { foo = gni } = v assigns a value to
    gni but not to foo (#4561)

Core:

  • Turned initial memory compaction on by default. This
    has show to greatly reduce initial memory consumption.
  • Improved source and clock naming (#4497)
  • Support for ImageLib has been removed. The library is not
    maintained anymore and causes issues with dangling external
    processes (#4595)

Utilities:

  • Deprecated replaygain operator, introduced unified
    normalize_track_gain which works with both ReplayGain
    and LUFS (#4545)

Fixed:

  • Fixed issues with autocue start_next. This brings autocue's behavior
    inline with its expectation but can change existing script's output (#4605)
  • Fix error when loading script path having non-ascii characters in them
    (#4343)
  • Fix concurrent inline encoders (#4638)
  • Fix error with interactive variables (#4592, @myeungdev)
  • Prevent concurrent reload and request fetch in playlists (#4316)
  • Don't mark source as ready until their clock has started. (#4496)
  • Fixed mutex deadlock caused by aggressive inlining (#4540)
  • Fixed segfault when using SRT on windows (#4538)
  • Fixed memleak in ffmpeg inline encoder (#4501)
  • Fixed tmp: protocol logic (#4544)
  • Fixed dangling file descriptors with file.*.stream (#4639, reported by @limebar)

Liquidsoap Rolling Release 2.3.x

27 Mar 16:17

Choose a tag to compare

Pre-release

This release provides liquidsoap assets before they are published as a new versioned release.

You can use it to install the latest stable code before it is published and test/prepare your production environment for it.

Rolling releases can also be useful for us to quickly detect and report bugs before the final published release!

⚠️ Warning ⚠️
Assets in this release will be deleted. If you are looking for permanent links to release assets, please head over to https://github.com/savonet/liquidsoap-release-assets/releases

For more details about our release process, please checkout https://github.com/savonet/liquidsoap#release-details
\n\n
2.3.4 (unreleased)

Changed:

  • Improved source and clock naming (#4497)

Fixed:

  • Don't mark source as ready until their clock has started. (#4496)

Liquidsoap 2.3.3

26 May 17:37

Choose a tag to compare

This is the third bug-fix release of the 2.3.x release cycle! 🎉

This release was triggered by a segfault caused by a memory corruption in the new lufs C code that was introduced with release 2.3.2. If you are using this code and this release, please consider upgrading.

Otherwise, the release includes minor fixes. It should be suitable for production but can be updated at your earliest convenience.

This release is also the first one to include builds for both versions of OCaml: 4.14.x and 5.x. As of now, the memory usage with Ocaml 5 is still significantly higher and not suitable for production in our opinion. However, we will need to make the switch one day or another so we decided to start providing both build to make sure that we stay compatible with the latest ocaml 5 code and can continuously test and improve memory optimization with this version.

⚠️ WHILE WE HAVE YOUR ATTENTION! ⚠️

Want to hear more from the liquidsoap community? Want to present your liquidsoap setup or the people using it?

Please consider attending our 5th liquidshop workshop!! More info: https://www.liquidsoap.info/liquidshop/5/

2.3.3 (2025-05-16)

New:

  • input.srt: add ipv6only to allow to bind only to ipv6 addresses.
    Set it to true when bind_address is ipv6.
  • Allow HLS segment names to contain sub-directories.
  • Implicitly convert ffmpeg raw audio data, making it much more practical
    to write scripts using the raw ffmpeg format (#4478)

Changed:

  • Made defer more user-friendly by operating directly on generic source(audio=pcm('a))
    sources. Renamed old defer to defer.pcm_s16
  • dtools, duppy and xmlplaylist have been moved into the liquidsoap code
    base and will no longer be developed or required as stand-alone packages (#12582)
  • Changed default value of metadata.map strip argument to true and insert_missing
    to false Added settings.metadata.map.strip and settings.metadata.map.insert_missing
    configuration keys to revert to previous defaults. (#4447)

Fixed:

  • Do not send empty metadata to shoutcast servers (#4408)
  • Automatically close file descriptor opened via scripted values with a log message
    warning of file descriptor leaks (#4481)
  • Fixed segfault in new lufs C code introduced with release 2.3.2 (#4490)

Liquidsoap 2.3.2

02 Apr 15:08

Choose a tag to compare

Not an april's fool joke! 😄

This is the second bugfix release of the 2.3.x release branch of liquidsoap!

⚠️ This release includes some important fix with the long-term behavior of scripts that create dynamic sources such as when using crossfade or autocue. ⚠️

We recommend that everyone on the 2.3.x release branch update to this version!

Other than the fix above, this release contains low-level bugfix and should be safe for everyone to use.

🚨 While we have your attention! Liquidshop 5 is taking place on Friday June 13th! Please feel free to register and maybe submit a talk. We want to hear about your projects, community and more! More details here 🚨

2.3.2 (2025-04-01) 🃏

New:

  • Added support for multiple metadata fields in
    ogg and flac metadata
  • Added support for track-level REM ALBUM in cue file parsing
    (#4381)

Changed:

  • Added "pic" to list of excluded metadata for automatic charset conversion.
  • Added settings.charset.max_string_length setting to prevent automatic charset
    conversions of strings over that length.

Fixed:

  • Optimized CPU usage (#4369, #4370)
  • Fixed empty initial HLS segment (#4401)
  • Fixed support for duration metadata in image decoder (#4397)
  • Fixed cue-out bug in cue file parsing (#4381)
  • Bring back parse error location. (#4362)
  • Fixed SRT encoding when restarting a stream with reverse data flow
    (#4399)
  • Make sure that audioscrobbler on_track/on_end operations are
    sent to a asynchronous task queue.
  • Fixed resources accumulation leading to catchup when using crossfade
    (#4419, #4410)
  • Fixed source reselection logic issue that was causing crashes when using
    switch and fallback operators (#4420)
  • Fixed self-sync logic with pulse audio outputs (#4429)
  • Fixed script caching on windows.

Liquidsoap 2.3.1

05 Feb 19:05

Choose a tag to compare

⚠️ Wanna help us know our users and plan the next release cycle? Fill up this form ⚠️

This is the first bugfix release of the liquidsoap 2.3.x release cycle!

So far, the 2.3.0 release has shown to be a pretty solid one! Therefore, this release only has minor bugfixes, most importantly about alsa devices and flac encoder.

Along with it are a couple of exciting features to keep things moving:

  • The lastfm scrobbler implementation has been fixed and came with support for xml parsing and rendering.
  • The CUE file parser for playlists has been rewritten natively and now supports many more dialects of the CUE file.

So, if you have a bunch of 90s CDs ripped with EAC that you want to scrobble to lastfm, this is your release! 😅

Also, we recommend that everyone else update to this version as well. It contains more bug fixes that may be affecting you and should be just as stable as 2.3.0!

⚠️ Warning ⚠️
Assets in this release may be deleted or updated. If you are looking for permanent links to release assets, please head over to https://github.com/savonet/liquidsoap-release-assets/releases

Full changelog:

2.3.1 (2025-02-05)

New:

  • Added support for address resolution preference in SRT (#4317)
  • Added global address resolution settings for SRT and Icecast (#4317)
  • Added support for parsing and rendering XML natively (#4252)
  • Added support for WAVE_FORMAT_EXTENSIBLE to the internal wav decoder.
  • Added optional buffer_size parameter to input.alsa and output.alsa (#4243)
  • Reimplemented audioscrobbler support natively using the more recent protocol (#4250)
  • Added boolean getter to disable/enable normalization (#4308)

Changed:

  • Make alsa I/O work with buffer size different than liquidsoap internal frame (#4236)
  • Reimplemented CUE file parser in native liquidsoap script, added support for multiple files and EAC non-compliant extension (#1373, #4330)
  • Make "song" metadata mapping to "title" metadata in input.harbor disabled when either "artist" or "title" is also passed. Add a configuration key to disable this mechanism. (#4235, #2676)
  • output.icecast now re-sends the last metadata when connecting to the remote server unless explicitly disabled using the send_last_metadata_on_connect option (#3906)
  • Add full explicit support for ipv4 vs. ipv6 resolution in SRT inputs and outputs, add global settings.srt.prefer_address and settings.icecast.prefer_address (#4317)
  • Added generic SRT socket get/set API. Added new socket options, including latency and ipv6only.

Fixed:

  • Fixed request resolution loop when enabling both autocue and replaygain metadata resolvers (#4245, fixed in #4246)
  • Fixed flac encoding segfault (#4286, #4274)
  • Fixed source last_metadata not being properly updated (#4262)
  • Convert all ICY (icecast) metadata from input.http to utf8.
  • Fixed inotify unwatching due to GC cleanup (#4275)
  • Fixed delay initial conditions (#4281)