New:
- Rewrote the streaming API to work with immutable frame content. This
should greatly impact impredictable side-effect of the previous models w.r.t.
track marks, content sharing and more. This also impacts multiple operators
behavior. Mostly, things should be roughly the same with differences around
behaviors related to track marks (
source.on_track
and etc). See @TODO@ for more details (#3577) - Added script caching layer for faster script startup time. See: https://www.liquidsoap.info/blog/2024-06-13-a-faster-liquidsoap/ for details (#3924, #3949, #3959 and #3977)
- Rewrote the clock/streaming loop layer. This prepares our streaming system to
support multicore when the OCaml compiler is mature enough to allow it. Clocks
are now attached to sources via their
clock
methods. Returned value is a stripped downclock
variable. Users can use theclock
function to retrieve the full methods, e.g.s = sine(); c = clock(s.clock)
. This value has advanced functions for clock control such asstart
/stop
,ticks
andself_sync
to check forself-sync
. See @TODO@ for more details. (#3781) - Allow frames duration shorter than one video frames, typically values under
0.04s
. Smaller frames means less latency and memory consumption at the expense of a higher CPU usage (#3607) - Change default frame duration to
0.02s
(#4033) - Optimized runtime (#3927, #3928, #3919)
- Added
finally
to execute code regardless of whether or not an exception is raised (see: #3895 for more details). - Added support for Spinitron submission API (#4158)
- Removed gstreamer support. Gstreamer's architecture was never a good fit for us
and created a huge maintenance and debugging burden and it had been marked as
deprecated for a while. Most, if not all of its features should be available using
ffmpeg
. (#4036) - Removed
taglib
support. It is superseded by the internalocaml-metadata
module and taglib, with its dependency on the C++ runtime library, has been causing issues with binary builds portability and crashes with the (not yet supported) OCaml 5 compiler. (#4087) - Added
video.canvas
to make it possible to position video elements independently of the rendered video size (#3656, blog post) - Added cover manager from an original code by @vitoyucepi (#3651)
- Reworked scheduler queues logic, allow user-defined queues, add options to pick the queue to send asynchronous tasks to (#4151)
- Added non-interleaved API to
%ffmpeg
encoder, enabled by default when only one stream is encoded. - Allow trailing commas in record definition (#3300).
- Added
metadata.getter.source.float
(#3356). - BREAKING: Added
duration
andticks
to metadata available when computing HLS segment names (#4135) - Added optional
main_playlist_writer
tooutput.file.hls
and derivated operator (#3484) - Added
is_nan
,is_infinite
,ceil
,floor
,sign
andround
(#3407) - Added
%track.drop
to the%ffmpeg
encoder to allow partial encoding of a source's available tracks (#3480) - Added
let { foo? } = ...
pattern matching (#3481) - Added
metadata.replaygain
method to extract unified replay gain value from metadata (#3438). - Added
metadata.parse.amplify
to manually parse amplify override metadata. - Added
compute
parameter tofile.replaygain
to control gain calculation (#3438). - Added
compute
parameter toenable_replaygain_metadata
to control replay gain calculation (#3438). - Added
copy:
protocol (#3506) - Added
file.touch
. - Added support for sqlite databases (#3575).
- Added
string.of_int
andstring.spaces
. - Added
list.assoc.nullable
. - Added
source.cue
(#3620). - Added
string.chars
(#4111) - Added atomic file write operations.
- Added new
macos_say
speech synthesis protocol. Make it the default implementation for thesay:
protocol onmacos
. - Added
settings.request.timeout
to set the request timeout globally.
Changed:
- Reimplemented
request.once
,single
and more usingsource.dynamic
. Removed experiment flag onsource.dynamic
. The operator is considered stable enough to define advanced sources but the user should be careful when using it. - Mute SDL startup messages (#2913).
int
can optionally raises an error when passingnan
orinfinity
,int(infinity)
now returnsmax_int
andint(-infinity)
returnsmin_int
. (#3407)- Made default font a setting (#3507)
- Changed internal metadata format to be immutable (#3297).
- Allow a getter for the offset of
on_offset
and dropped the metadata mechanism for updating it (#3355). string.length
andstring.sub
now default toutf8
encoding (#4109)- Disable output paging when
TERM
environment variable is not set. - Allow running as
root
user insidedocker
container by default (#3406). - Run
check_next
before playlist's requests resolutions (#3625) - Set
force
totrue
by default infile.copy
to make operator behave as expected. - BREAKING: Float comparison now follows the expected specs, in particular:
nan == x
is alwaysfalse
andnan != x
is alwaystrue
. Usefloat.is_nan
to test if a float isnan
. - BREAKING:
replaygain
no longer takesebu_r128
parameter (#3438). - BREAKING: assume
replaygain_track_gain
always stores volume in dB (#3438). - BREAKING: protocols can now check for nested static uri. Typically, this means
that requests for an uri of the form:
annotate:key="value",...:/path/to/file.mp3
is now considered infallible if/path/to/file.mp3
can be decoded. - Added
parents
option offile.mkdir
(#3600, #3601). - Added
forced_major_collections
record field to the result ofruntime.gc.stat()
andruntime.gc.quick_stat()
(#3783). - Changed the port for the built-in Prometheus exporter to
9599
(#3801). - Set
segments_overheader
in HLS outputs to disable segments cleanup altogether. - Added support for caching LV2 and LADSPA plugins (#3959).
- Pulseaudio input and output now restart on pulseaudio errors (#4174).
Fixed:
- Fixed type generalization on values returned from function applications. Most notably, this should help with HTTP endpoint registration (#3303, fixed in #4030)
New:
- Added
enable_autocue_metadata
andautocue:
protocol to automatically compute cue points and crossfade parameters (#3753, #3811, @RM-FM and @Moonbase59) - Added various ffmpeg timestamps when exporting ffmpeg metadata from filters.
- Added
db_levels
method toblank.*
sources (#3790) - Added
excluded_metadata_resolvers
torequest.create
to make it possible to selectively disable specific metadata resolvers when resolving requests. - Normalized expected API from
autocue
, allow multiple implementation and adaptcross
/crossfade
to work with it out of the box with workaround for short tracks. - Added private and swapped memory reporting when compiled with
mem_usage
. - Added priorities to metadata deocoders, allows finer-control of metadata overriding. (#3887)
Changed:
- Allow to disable
http.*
url normalization. Add warning when url normalization changes the url (#3789) - Add
namespace
and optional source IDs tomix
.
Fixed:
- Prevent request metadata from overriding root metadata (#3813)
- Fixed
source.drop
andsource.dump
clock initialization. - Fixed bogus report of non-monotonous PTS content when using raw ffmpeg content.
- Fixed streaming errors when disconnecting
input.harbor
. - Fixed issues with rendered id3v2 frame that contain binary data (#3817)
- Fixed memory leaks with SRT listen socket polling callbacks.
- Fixed
%ffmpeg
copy muxer logic with some audio/video streams (#3840) - Fixed
duration
metadata calculation in the presence ofcue_in
/cue_out
metadata.
New:
- Added support for
id3v2
metadata inoutput.*.hls
when using%mp3
,%shine
or%fdkaac
encoders (#3604) - Added option to set preferred address class (
ipv4
,ipv6
or system default) when resolving hostnames in http transports andoutput.icecast
- Added
self_sync
option toinput.srt
to accommodate for streams in file mode (#3684) - Added
curve
parameter to fade functions andliq_fade_{in,skip,out}_curve
metadata override (#3691) - Added
delay
parameter to fade functions to make it possible to add delay before fade happens. Addliq_fade_{in,skip,out}_delay
metadata override. - Added
single_track
option to allowsequence
to play each source until they are unavailable while keeping track marks.
Changed:
cue_cut
operator has been removed. Cueing mechanisms have been moved to underlying file-based sources. See migration notes for more details.
Fixed:
- Fix pop/click at the end of fade out/in (#3318)
- Fix audio/video synchronization issues when decoding live streams using ffmpeg.
- Fix issues with TLS connecting clients not being properly timed out (#3598)
- Make sure reconnection errors are router through the regulat
on_error
callback inoutput.icecast
(#3635) - Fixed discontinuity count after a restart in HLS outputs.
- Fixed file header logic when reopening in
output.file
(#3675) - Fixed memory leaks when using dynamically created sources (
input.harbor
,input.ffmpeg
, SRT sources andrequest.dynamic
) - Fixed invalid array fill in
add
(#3678) - Fixed deadlock when connecting to a non-SSL icecast using the TLS transport (#3681)
- Fixed crash when closing external process (#3685)
New:
- Added
string.escape.html
(#3418, @ghostnumber7) - Add support for getters in arguments of
blank.detect
(#3452). - Allow float in source content type annotation so that it possible
to write:
source(audio=pcm(5.1))
Changed:
- Trim urls in
input.ffmpeg
by default. Disable usingtrim_url=false
(#3424) - Automatically add HLS-specific ffmpeg parameters to
%ffmpeg
encoder (#3483) - BREAKING: default
on_fail
removed onplaylist
(#3479)
Fixed:
- Allow
channel_layout
argument in ffmpeg encoder to set the number of channels. - Improved support for unitary minus, fix runtime call of optional methods (#3498)
- Fixed
map.metadata
mutating existing metadata. - Fixed reloading loop in playlists with invalid files (#3479)
- Fixed main HLS playlist codecs when using
mpegts
(#3483) - Fixed pop/clicks in crossfade and source with caching (#3318)
- Fixed pop/clicks when resampling using
libsamplerate
(#3429) - Fixed gstreamer compilation. Remember that gstreamer features are DEPRECATED! (#3459)
- Fixed html character escaping in
interactive.harbor
(#3418, @ghostnumber7) - Fixed icecast not reconnecting after erroring out while closing connection in some circumstances (#3427)
- Fixed parse-only mode (#3423)
- Fixed ffmpeg decoding failing on files with unknown codecs.
- Fixed a crash due to
wait_until
timestamp being in the past when usingposix-time2
- Make sure that temporary files are always cleaned up in HLS outputs (#3493)
Changed:
- BREAKING: on HLS outputs,
on_file_change
events are now"created"
,"updated"
and"deleted"
, to better reflect the new atomic file operations (#3284) - Added
compact
argument to thehttp.response.json
function.http.response.json
will produce minified JSON by default. Added a newline symbol to the end of the JSON data produced byhttp.response.json
. (#3299) - Bumped internal ogg decoder to make sure that it is used over the ffmpeg decoder whenever possible.
FFmpeg has issues with metadata in chained streams which needs to be fixed upstream. Unfortunately,
input.http
can only use the ffmpeg decoder at the moment. - Cleanup
output.file
encoding and file handling logic (#3328) - Added
ratio
tosource.{dump,drop}
to make it possible to control its CPU peaks. - Enhanced clock error reporting (#3317)
Fixed:
- Fixed slow memory leak in muxer operator (#3372, #3181, #3334)
- Fixed discontinuity logic error in HLS outputs after a restart.
- Fixed HTTP response status in
output.harbor
(#3255) - Make sure main HLS playlist is regenerated after being unlinked (#3275)
- Fixed hard crash on icecast disconnection errors.
- Fix
output.harbor
encoder header when encoding with%ogg
,%vorbis
and etc. (#3276) - Fixed quality argument parsing in ffmpeg encoders (#3267)
- Make all HLS file write atomic (#3284)
- Allow seek and cue operators to work with muxed sources using a single underlying source (#3252)
- Fixed export of cover art metadata (#3279)
- Remove use of
stereo:
protocol insay:
protocol: this is now handled automatically by the decoder and generates latency via high CPU usage peak. - Fixed
output.file
reopening with flac encoding (#3328)
New:
- Added support for less memory hungry audio formats, namely
pcm_s16
andpcm_f32
(#3008) - Added support for native osc library (#2426, #2480).
- SRT: added support for passphrase, pbkeylen, streamid,
added native type for srt sockets with methods, moved stats
to socket methods, added
socket()
method on srt input/outputs (#2556) - HLS: Added support for ID3 in-stream metadata (#3154) and custom tags (#2898).
- Added support for FLAC metadata (#2952)
- Added support for YAML parsing and rendering (#2855)
- Added support for the proprietary shared stereotool library (#2953)
- Added TLS support via
ocaml-tls
(#3074) - Added
video.align
. - Added
string.index
. - Added support for ffmpeg decoder parameters to allow decoding of raw PCM stream and file (#3066)
- Added support for unit interactive variables: those call a handler when their value is set.
- Added support for id3v2
v2.2.0
frames and pictures. - Added
track.audio.defer
to be used to buffer large amount of audio data (#3136) - Added
runtime.locale.force
to force the system's locale (#3231) - Added support for customizable, optimized
jemalloc
memory allocator (#3170) - Added
source.drop
to animate a source as fast as possible.. - Added in house replaygain computation:
source.replaygain.compute
to compute replaygain of a sourcefile.replaygain
to compute the replaygain of a file
- Added support for ImageLib to decode images.
- Added support for completion in emacs based on company (#2652).
- Added syntactic sugar for record spread:
let {foo, gni, ..y} = x
andy = { foo = 123, gni = "aabb", ...x}
(#2737) - Added
file.{copy, move}
(#2771) - Detect functions defining multiple arguments with the same label (#2823).
- Added
null.map
. - References of type
'a
are now objects of type(()->'a).{set : ('a) -> unit}
. This means that you should usex()
instead of!x
in order to get the value of a reference. Setting a reference can be done both byx.set(v)
andx := v
, which is still supported as a notation (#2881). - Added
ref.make
andref.map
. - Added
video.board
,video.graph
,video.info
(#2886). - Added the
pico2wave
protocol in order to perform speech synthesis using Pico TTS (#2934). - Added
settings.protocol.gtts.lang
to be able to selectgtts
' language, addedsettings.protocol.gtts.options
to be able to add any other option (#3182) - Added
settings.protocol.pico2wave.lang
to be able to selectpico2wav
language (#3182) - Added
"metadata_url"
to the default list of exported metadata (#2946) - Added log colors!
- Added
list.filter_map
andlist.flatten
. - Added
medialib
in order to store metadata of files in a folder and query them (#3115). - Added
--unsafe
option (#3113). This makes the startup much faster but disables some guarantees (and might even make the script crash...). - Added
string.split.first
(#3146). - Added
string.getter.single
(#3125).
Changed:
- Switched to
dune
for building the binary and libraries. - Changed
cry
to be a required dependency. - Changed default character encoding in
output.harbor
,output.icecast
output.shoutcast
toUTF-8
(#2704) - BREAKING: all
timeout
settings and parameters are nowfloat
values and in seconds (#2809) - BREAKING: in
output.{shoutcast,icecast}
:- Old
icy_metadata
renamed tosend_icy_metadata
and changed to a nullablebool
.null
means guess. - New
icy_metadata
now returns a list of metadata to send with ICY updates. - Added
icy_song
argument to generate default"song"
metadata for ICY updates. Defaults to<artist> - <title>
when available, otherwiseartist
ortitle
if available, otherwisenull
, meaning don't add the metadata. - Cleanup, removed parameters that were irrelevant to each operator, i.e.
icy_id
inoutput.icecast
and etc. - Make
mount
mandatory andname
nullable. Usemount
asname
whenname
isnull
.
- Old
reopen_on_error
andreopen_on_metadata
inoutput.file
and related operators are now callbacks to allow dynamic handling.- Added
reopen
method tooutput.file
. - Added support for a Javascript build an interpreter.
- Removed support for
%define
variables, superseded by support for actual variables in encoders. - Cancel pending append when skipping current track on
append
source. - Errors now report proper stack trace via their
trace
method, making it possible to programmatically point to file, line and character offsets of each step in the error call trace (#2712) - Reimplemented
harbor
http handler API to be more flexible. Added a new node/express-like registration and middleware API (#2599). - Switched default persistence for cross and fade-related overrides
to follow documented behavior. By default,
"liq_fade_out"
,"liq_fade_skip"
,"liq_fade_in"
,"liq_cross_duration"
and"liq_fade_type"
now all reset on new tracks. Usepersist_overrides
to revert to previous behavior (persist_override
forcross
/crossfade
) (#2488). - Allow running as root by default when docker container can be detected using
the presence of a
/.dockerenv
file. id3v2
argument of%mp3
encoder changed to"none"
or version number to allow to choose the metadata version.true
is still accepted and defaults to version3
. Switched to our internal implementation so that it does not requiretaglib
anymore.- Moved HLS outputs stream info as optional methods on their respective encoder.
- Changed
self_sync
ininput.ffmpeg
to be a boolean getter, changedself_sync
ininput.http
to be a nullable boolean getter. Setself_sync
totrue
ininput.http
when an icecast or shoutcast server can be detected. - Add
sorted
option tofile.ls
. - Add
buffer_length
method toinput.external.rawaudio
andinput.external.wav
(#2612). - Added full
OCaml
backtrace astrace
to runtime errors returned from OCaml code. - Removed confusing
let json.stringify
in favor ofjson.stringify()
. - Font, font size and colors are now getters for text operators (
video.text
,video.add_text
, etc.) (#2623). - Add
on_cycle
option tovideo.add_text
to register a handler when cycling (#2621). - Renamed
{get,set}env
intoenvironment.{get,set}
- Renamed
add_decoder
,add_oblivious_decoder
andadd_metadata_resolver
into, respectively,decoder.add
,decoder.oblivious.add
,decoder.metadata.add
- Deprecated
get_mime
, addedfile.mime.libmagic
andfile.mime.cli
, madefile.mime
tryfile.mime.libmagic
if present andfile.mime.cli
otherwise, changed eturned value when no mime was found tonull()
. - Return a nullable float in
request.duration
. - Removed
--list-plugins-json
and--list-plugins-xml
options. - Added
--list-functions-json
option. - Removed built-in use of
strftime
conversions in output filenames, replaced by an explicit call totime.string
(#2593) - Added nullable default to
{int,float,bool}_of_string
conversion functions, raise an exception if conversion fails and no default is given. - Deprecated
string_of
in favor ofstring
(#2700). - Deprecated
string_of_float
in favor ofstring.float
(#2700). - Added
settings.protocol.youtube_dl.timeout
to specify timeout when usingyoutube-dl
protocol (#2827). Useyt-dlp
as default binary for the protocol. - The
sleeper
operator is now scripted (#2899). - Reworked remote request file extension resolution (#2947)
- REMOVED
osx-secure-transport
. Doubt it was ever used, API deprecated upstream (#3067) - Renamed
rectangle
toadd_rectangle
, and similarly forline
.
Fixed:
- The randomization function
list.shuffle
used inplaylist
was incorrect and could lead to incorrectly randomized playlists (#2507, #2500). - Fixed srt output in listener mode to allow more than one listener at a time and prevent listening socket from being re-created on listener disconnection (#2556)
- Fixed race condition when switching
input.ffmpeg
-based urls (#2956) - Fixed deadlock in
%external
encoder (#3029) - Fixed crash in encoders due to concurrent access (#3064)
- Fixed long-term connection issues with SSL (#3067)
New:
- Added
buffer_length
method tobuffer
operator. - Always display error backtrace when a fatal exception is raised in the streaming loop.
- Added
umask()
to get the currentumask
andumask.set(...)
to set the currentumask
(#2840)
Changed:
- Add break when restarting the external process in
input.external.{rawaudio,rawvideo}
(#2860, #2872) - Removed
disconnect
method oninput.harbor
. This method was doing the same as thestop
method. Addedshutdown
method to properly shutdown the source even when not connected to an output. - Made process a string getter in
input.external.{rawaudio,rawvideo}
(#2877)
Fixed:
- Fixed parameter type for
stats_interval
in SRT I/O. - Fixed type generalization on variable and pattern bindings (#2782)
- Fixed memory leak in http requests (#2935)
- Make sure that exception raised in
request.dynamic
never crash the process (#2897) - Fixed
filename
getter being called multiple time inoutput.file
(#2842) - Fixed default directory permissions in
output.*.hls
operators (#2930) - Space trim in interactive variables set on telnet (#2785)
- Fixed internal streaming logic in
max_duration
andcrossfade
. - Make sure that there's at most one metadata at any given frame position (#2786)
- Fixed
metadata.json.parse
always returns an empty list (#2816). - Fixed
icy_id
being ignored inoutput.shoutcast
(#2819) - Fixed shutdown livelock with some ffmpeg inline encoder, decoder and filter operators.
- Fixed input polling stop (#2769)
- Fixed parsed error report in
%include
directives (#2775) - Fixed crash in external processes when received a
Unix.EINTR
event (#2861) - Fixed crash in
string.interpolate
(#2883) - Cleaned up srt support.
New:
- Added
time.string
. - Added
error.on_error
to report any error raised during the script's execution. Enhanced reported error positions (#2712) - Added
device_id
andlatency
options toinput.portaudio
andoutput.portaudio
to be able to choose the requested device. Useliquidsoap --list-portaudio-devices
to see the list of devices (#2733) - Added
disconnect
method toinput.harbor
, making it possible to disconnect a source client programmatically, including when a new client is trying to connect.
Changed:
- Send data in-memory in
http.{post,put}.file
when input data is already in memory. This allows to use plainContent-Length
instead ofchunked
transfer encoding in these case, thoughlibcurl
seems to always preferchunked
encoding forput
requests. - Better error message when an encoder is not available on windows (#2665)
- Create output directory in HLS outputs when it does not exist
using newly introduced
perms
permission argument (#2725) - Removed
restart_on_error
argument onoutput.url
and addedrestart_delay
which implements a delayed restart. Addedon_error
argument to be notified of errors (#2731) - Changed default
encoding
parameter instring.{quote, escape}
to benull
. Fallback to"ascii"
encoding when no encoding is specified and"utf8"
fails. This prevents unexpected script failures but might not be backward-compatible if you used a customescape_char
orspecial_char
function (#2738)
Fixed:
- Enhanced methods typing support (#2659)
- Add support for
song
metadata (mapped totitle
) andurl
(mapped tometadata_url
) ininput.harbor
(#2676) - Fixed
blank.*
operator types. - Fixed request metadata escaping (#2732)
- Fixed
input.external.rawadudio
mono input (#2742) - Fixed
http
response body on redirect (#2758)
New:
- Added
string.char
,string.getter.flush
andstring.getter.concat
. - Added
http.multipart_form_data
andhttp.{post,put}.file
.
Changed:
- Allow sub-second values in
sleep()
(#2610) - Allowed many new format for
taglib
(#2605) - Add
settings.ffmpeg.content.copy.relaxed_compatibility_check.set
settings to allow relaxed compatibility check for ffmpeg copy content, making it possible to encode streams with various audio samplerate or video size when the container supports it.
Fixed:
- Stop error loop when opening a listening ssl socket with non-existent certificate. (#2590)
- Youtube HLS upload for live streams.
- Fixed
data:...
uri scheme to conform to RFC 2397 (#2491) - Fixed multiple issues related to empty
ogg/opus
metadata (#2605) - Ensure that
video.add_text
fails when the source does (#2609) - Fixed metadata parsing in
server.insert_metadata
(#2619) - Fixed
extract_replaygain
path (#2624, @parnikkapore) - Fixed crash when terminating the process (#2585)
- Fixed channels conversion when using
input.rawaudio
(#2602)
Internal Change:
ref()
implementation switched to OCaml'sAtomic
to prevent race conditions,thread.mutexify
andmutexify
functions removed. (#2603)
New:
- Added
process.quote.command
to generate complex quoted command strings suitable for use withprocess.run
and os-independent.
Changed:
- Renamed
playlist.remaining
intoplaylist.remaining_files
(#2524) - Added
id
argument toreplaygain
operator (#2537). - Made
ocurl
dependency required, addeduri
as required dependency (#2551)
Fixed:
- Fixed missing ffmpeg features on windows build.
- Fixed sync issues with
ffmpeg.encode.*
inline encoders (#2584) - Fixed
http.get
issues whenuser-agent
was not set (#2517) - Fixed order of
playlist.next
returned requests. - Fixed infinite loop when reloading a failed playlist (#2576)
- Fixed http requests with urls containing spaces (#2551)
- Fixed
on_connect
type forsrt
inputs and outputs. - Fixed parsing issues with functions/variables definitions
beginning with
rec
orreplaces
(#2560) - Fixed infinite parse error loop (#2527)
- Fixed empty initial
mp4
HLS segment. - Prevent initial start for autostart and fallible sources.
New:
- Added support for variables in encoders (#1858)
- Added support for regular expressions (#1881)
- Added generalized support for value extraction patterns (#1970)
- Added support for string getter for
http.{post,put}
operations (#1984) - Added
output.youtube.live.hls
- Rewrote out internal JSON parser/renderer (#2011). Breaking change values
that cannot be represented as
JSON
will now raiseerror.json
when converted toJSON
.infinite
andnan
floats can be exported using thejson5
export format. - Added socket API (#2014).
- Added support for ffmpeg bitstream filters (#2387)
- Added
liquidsoap.version.at_least
. - Added
video.rectangle
,video.persistence
. - Added
video.vumeter
. - Added
video.slideshow
. - Added
video.add_text.camlimages
(#2202). - Added
video.text.*
and re-implementedvideo.add_text.*
from those (#2226). - Added
irc.channel
operator to retrieve the contents of an IRC channel (#2210). - Added new in-house parsing of metadata for some image and video formats (#2236).
- Added
file.download
- Added new options for
%ffmpeg
copy encoder:ignore_keyframes
andwait_for_keyframe
(#2382)
Changed:
- Removed support for partial application, which should avoid some type errors, improve performance and simplifies the code related to the reduction (#2204).
- Video dimensions (width and height) can now be specified per stream in the
type and are then used instead of the default ones. For instance, you can now
write
in order to force the decoding of a file to be performed at the 300×200 resolution (#2212).
s = (single("file.mp4") : source(video(width=300,height=200)))
- Video images are now canvas, which means that they do not directly contain the images, but are constituted of multiple images placed at various positions. This should make much more efficient operations such as making videos from multiple ones, adding a logo, etc. (#2207)
output.youtube.live
renamedoutput.youtube.live.rtmp
, removebitrate
andquality
arguments and added a single encoder argument to allow stream copy and more.source.on_metadata
andsource.on_track
now return a source as this was the case in previous versions, and associated handlers are triggered only when the returned source is pulled (#2103).- Made
streams_info
parameter ofoutput.file.hls
a record (#2173). - Disable scrolling by default in
video.add_text
. You can re-enable it by usingvideo.add_text(speed=70, ...)
. - Added "example" sections to operators documentation, we now need to populate those (#2227).
- Default implementation of
video.testsrc
is now builtin, previous implementation can be found undervideo.testsrc.ffmpeg
. - Images can now generate blank audio if needed, no need to add
mux_audio(audio=blank(),image)
anymore (#2230). - Removed deprecated
timeout
argument inhttp.*
operators. - Deprecated
request.ready
in favor ofrequest.resolved
.
Fixed:
- Fixed typo in
status
command of themix
operator. - Fixed performances issues with
input.ffmpeg
andinput.http
(#2475) - Fixed
list.shuffle
which was used to randomize playlists inplaylist
operator (#2507, #2500).
Fixed:
- Fixed memory leaks with opus bindings.
- Make sure decoding buffer and samplerate converter are only created once. (#2475)
- Make sure first metadata is always sent in icecast/shoutcast output (#2506)
New:
- Added
video/mp4
to list of recognized mime types for request resolutions.
Changed:
- Log errors when using
process.read
(##2420, @martinkirch)
Fixed:
-
Memory leak when executing
process.run
(#2424) -
Delay harbor server endpoint registration until application has started (#1589)
-
Print user-readable encoder parameter error report.
-
Fixed m3u metadata parsing when artist has a comma in their name (#2449)
-
Cleanup failed request in
playlist
operator. -
Make sure requests are always cleaned up, making
request.destroy
calls optionals.
New:
- Extended m3u EXTINF parser to support empty duration and annotations.
Changed:
- Brought back
mix
operator (#2401)
Fixed:
- Allow crossfade duration override of
0.
- Buffer synchronization issues.
- Drop methods from ffmpeg filter input source types to avoid unnecessary conflicts.
- Fix evaluation of abstract values with methods.
- Prevent some sources from being consumed when not active,
namely ffmpeg inline encoders,
soundtouch
,resample
and all the muxing operators. - Raise runtime exceptions in
string.replace
failures with useful message. (#2408) - Prevent
request.dynamic
from raising exceptions when checking if the source is ready (#2381)
New:
- Added
settings.video.add_text
to enforce consistent choice ofvideo.add_text
implementation (#2302)
Changed:
- Make sure source shutdown can only be called on sources that
can actually be shutdown:
- Remove generic
source.shutdown
- Keep
s.shutdown()
method only on sources that are active. Refs: #2259
- Remove generic
- Optimized memory usage when accessing frame content (#2266)
- Optimized memory usage when accessing ground terms.
- Allow crossfade duration getter to override duration at the end of each track if duration isn't set via metadata.
- Make sure crossfade metadata are not duplicated (#2153)
- Renamed
map_metadata
intometadata.map
, deprecatedmap_metadata
. - Deprecatdd
list.mem_assoc
- Enhanced remaining time when using
add
(#2255) - Added
timeout_ms
tohttp.*
to provide time in milliseconds, deprecatedtimeout
argument. - Connect
output.icecast
when data is available instead of when operator starts to avoid useless connections when underlying source fails immediately.
Fixed:
-
Prevent infinite loops when crossfade duration is negative (#2287)
-
Prevent mutex deadlock when recursively locking mutexes (#2274)
-
Mark method
add()
as internal inrequest.queue
, fix methodlength()
(#2274) -
Fixed
retry_delay
being ignored in some cases inrequest.dynamic
. -
Prevent race condition in external process handler.
-
Fixed A/V sync when streaming encoded data via ffmpeg encoder (#2159)
-
Prevent stopped/iddle sources from being restarted when resetting
clock(s)
after too much latency (#2278) -
Fixed registration of
video.add_text.ffmpeg
as possible implementation forvideo.add_text
(#2302) -
Fixed
http.*
calls preventing liquidsoap from shutting down. -
Fixed
http
protocol not returning an error when timing out (#2242) -
Reworked ffmpeg filters feeding mechanism.
-
Fixed inconsistencies in
playlist.parser
(#2257) -
Fixed inconsistent reselect in
rotate
(#2300) -
Fixed special characters escaping in
video.add_text.ffmpeg
(#2324) -
Fixed
input.rawaudio
andinput.rawvideo
when handling non-stereo content.
New:
- Added support for memory debugging using
memtrace
- Added
time.{zone,zone.set,make}
(#2178) - Added
runtime.gc
module, renamegarbage_collect
asruntime.gc.full_major
with deprecated compatibility wrapper, addedruntime.gc.stat
,runtime.gc.quick_stat
,runtime.gc.print_stat
andruntime.gc.{get,set}
. - Added
runtime.sys.word_size
- Added optional support for
runtime.mem_usage
- Added
runtime.memory
wrapper to get info about the system and process' memory usage. - Added
configure.camomile_dir
to export expected location of camomile directory when packaging liquidsoap. - Added
liquidsoap.chroot.make
to copy all files required for a liquidsoap install.
Changed:
- Bumped
input.harbor
default buffer to12.
to make it possible to use it withcrossfade
transitions without changing default values (#2156) year
method as returned intime.local
andtime.utc
now returns the actual year instead of years since 1900 (#2178)mday
,mon
,wday
andyday
methods as returned intime.local
andtime.utc
have been renamed to, resp.,day
,month
,week_day
andyear_day
(#2178)month
method as returned intime.local
andtime.utc
now returns the month as a number between1
and12
(#2178)week_day
method as returned intime.local
andtime.utc
now returns the week day as a number between1
and7
(#2178)year_day
method as returned intime.local
andtime.utc
now returns the week day as a number between1
and366
(#2178)- Added option to choose if
input.rtmp
should behave as a server or a client (#2197) - Allow dynamic text change in
video.add_text.ffmpeg
(#2189) - Removed
thread_name
argument fromthread.on_error
callbacks.
Fixed:
-
Make sure metadata are replayed when switching to a source for the first time in switches/fallback (#2138)
-
Bring back
video.add_text.sdl
(#2187) -
Fixed
thread.on_error
implementation (#2171) -
Fixed
ffmpeg
video scaling to make sure it always is proportional (#2211)
New:
- Show code excerpts on errors (#2086)
- Added
on_get_ready
callback to sources, to be executed after a source's has initialized. - Added
flush_and_skip
telnet command torequest.dynamic
to empty the request's queue before skipping the current track, forcing a full reload. - Added
last_metadata
method on sources to return the last metadata produced by the source.
Fixed:
-
Fixed ffmpeg copy encoder crash when switching between streams.
-
Fixed unbound buffer in muxing operators (#2054)
-
Return correct positions when parsing strings (#2095)
-
Deadlock when shutting down with
input.rtmp
(#2089) -
Add timeout to srt operations (#2082)
-
Fixed
request.queue
queue
telnet command returning nothing (#2088) -
Fixed single quotes being escaped in json stringify. (#2120)
-
Fixed frame caching issues when no initial break was present in the memoized frame. (#2109. AzuraCast/AzuraCast#4825)
-
Fixed
replay_metadata
not replaying metadata from active sources (#2109)
New:
- Added
time.predicate
to parse time predicates at runtime. - Added support for ffmpeg filter commands, unify
video.add_text.ffmpeg
with other operators, make it the default when available. (#2050)
Changed:
- Removed
encode_metadata
option ininput.file.hls
as it does nothing with the main encoder for HLS format,%ffmpeg
(#2023) - Converted
output.icecast
optional parameters tonullable
.
Fixes:
-
Fixed switch-based sources not respecting track boundaries when using default transitions one track only per selected source. (#1999)
-
Fixed playlist annotation. (#2005)
-
Raise a proper runtime exception when
string.escape
fails. (#2010) -
Account for internal caching in
request.dynamic.list
'squeue
andset_queue
methods. -
Keep buffering for crossfade when new source has track mark but is still ready.
-
Added missing output
start
/stop
commands. -
Fixed
perms
,dir_perms
andappend
not bring honored when delegating file output to the encoder. -
Fixed base directory not being created when delegating file output to the encoder (#2069).
-
Use
process.quote
in process calls (#2031)
New:
- Add support for errors with
error.*
andtry ... catch
(#1242). - Add support for optional values with
null.*
(#1242). - Add support for
x ? y : z
syntax (#1266). - Added support for list spread and deconstruction syntax (#1269).
- Add support for generic JSON objects, map
(string, 'a)
lists to regular lists, add support for json5 floats (NaN
,Infinity
), returnnull
for those otherwise, renamejson_of
intojson.stringify
andof_json
intojson.parse
with deprecation (#1824) - Added support for video encoding and decoding using
ffmpeg
(#1038). - Added support for hardware-accelerated video encoding using
ffmpeg
(#1380) - Added support for ffmpeg filters (#1038).
- Added video support to
output.hls
(#1391). - Added mp4 support to
output.hls
(#1391). - Added
output.url
for encoders that support handling data output (currently only%ffmpeg
) (#1038). - Added
output.file.dash.ffmpeg
. - Added LV2 support (#906).
- Added
string.nth
(#970). - Added
string.binary.to_int
(#970). - Added
string.hex_of_int
. - Added
file.ls
(#1011). - Added native id3v2 tag parser, as well as associated function
file.mp3.metadata
,file.mp3.parse_apic
andfile.cover
(#987). - Use a pager to display long help results (#1017).
- Added new functions for lists:
lists.exists
,list.for_all
,list.init
,list.ind
,list.index
,list.last
,list.shuffle
. - Added
request.id
. - Added a profiler for the language. It can be enabled with
profiler.enable
and the results are obtained withprofiler.stats.string
(#1027). - Added
gtts
protocol to use Google TTS (#1034). - Added
liquidsoap.executable
to get the path of the currently running Liquidsoap. - Added
source.dump
. - Added
source.elapsed
andsource.duration
- Added
synth
protocol (#1014). - Added listener and caller mode for
input.srt
andoutput.srt
(#1377) - Added support for
srt.enforced_encryption
setting. - Added support for prometheus reporting (#1000)
- Add
validate
parameter toregister
, which allows to validate a value before setting it (#1046, @CyberDomovoy) - Add
string.null_terminated
(#960). - Removed
string.utf8.escape
in favor or a unifited, utf8-awarestring.escape
. - Add
string.unescape
. - Add
file.metadata
(#1058). - Add
predicate.activates
,predicate.changes
,predicate.first
,predicate.once
,predicate.signal
(#1075). - Add
playlist.list.reloadable
andplaylist.list
(#1133). - Make it possible to disable buffer overrun logs.
- Add
accelerate
operator (#1144). - Add
video.resize
. - Add
getter.int_of_float
andgetter.float_of_int
. - Add
source.dump
(#1036). - Add
stereo
andsynth
protocols (#1036). - Add
video.add_text.ffmpeg
. - Added support for
file:///path/to/file
andfile:/path/to/file
protocols. - Added configure option to specify internal library install path (#1211).
- Add support for records and methods (#1197).
- Rename
unsafe.single.infallible
tosingle.infallible
. - Add
list.indexed
. - Added optional support for high-resolution time and latency control on POSIX systems (#1050).
- Added syntax for
for
andwhile
loops (#1252). - Added a bunch of source-related methods (#1379).
- Added
min
andmax
functions. - Added
lufs
to compute the LUFS loundness (#1497). - Added
interactive.harbor
in order to expose interactive variables over harbor (#1495). - Added
interactive.persistent
(as well asinteractive.save
andinteractive.load
) to make interactive variables persistent (#1495). - Added
server.harbor
(#1502). - Added
metronome
. - Added
playlist.files
. - Added
getter.is_constant
. - Added
assert
. - Added
source.available
. - Added
request.once
. - Added
file.getter
. - A better
normalize
function (with more reasonable parameters, more customisable, and written in Liquidsoap) is now provided. The old one is renamednormalize.old
. - New and better
compress
function. The previous one was renamedcompress.old
(#868, #869). - Added
stereo.width
. - Added
file.mkdir
. - Added support for harbor's connected address in auth function and as a method (#1364).
- Added
time.up
. - Added
video.cover
. - Added
video.still_frame
. - Added
request.status
. - Added
playlog
to record how long ago a song was last played (#333 and #1530). - Added
clock.log_delay
to configure how often clock catchup error messages should be printed. - Added
input.rtmp
(#1640). - Added
%ifversion
and%else
preprocessing commands (#1682). - Added
dtmf
anddtmf.detect
to generate and detect DTMF tones (#1796). - Added
sine.detect
to detect sines (#1796). - Added
on_air_timestamp
to request's metadata to get the request'son_air
time as a Unix timestamp (#1871)
Changed:
- Implemented per-frame clock synchronization mechanism, should allow for more advanced flexibility when working with source synchronization while keeping the default safe behavior. (#1012)
- Remove
active_source
type, make all output returnunit
type. (#1671) - Switch to YUV420 as internal image format, much more efficient (#848).
- Use bigarrays for audio buffers (#950).
- Re-implemented switch-derived operators (
fallback
,rotate
,random
) as scripted operators, removedtrack_sensitive
argument fromrotate
andrandom
as it does not have a sound meaning for them. - Added optional exit
code
toshutdown
. - Renamed
verb
argument infomethod
inoutput.icecast
. - Simplified
add
behavior, also fixing an clock issue (#668). - Switch to more efficient callback API for decoders (#979).
- Use system pagesize for buffer allocation (#915).
- Use new Strings module in order to avoid concatenations (#984).
- Native Liquidsoap implementation of list functions (#920).
- Added
fallible
option tosingle
operator. - Allow
input.ffmpeg
to control its own clock or delegate to CPU clock (#1628) - Reimplement
input.http
usingffmpeg
, deprecateinput.https
in favor of unifiedinput.http
(#1628) - Changed
input.http
andinput.ffmpeg
url
parameter into a string getter - Changed
request.queue
into a Liquidsoap implementation (#1013). - Removed
request.equeue
, such a feature could be re-implemented in Liquidsoap, seerequest.queue
. - The
playlist
operator is now fully implemented in Liquidsoap (#1015). - Removed
playlist.once
, its behavior can be achieved by passing"never"
to thereload_mode
argument ofplaylist
(#1015). - Removed
playlist.merged
: it is not that useful and can be achieved easily withmerge_tracks
on aplaylist
(#1015). - Deprecated
playlist.safe
(#1015). - Renamed
add_timeout
tothread.run.recurrent
, addedthread.run
variant, renamedexec_at
tothread.when
and renamedmutexify
tothread.mutexify
(#1019). - Changed the weights of
add
to float (#1022). - Renamed
which
tofile.which
. - Change
blank()
duration semantics to mean forever only on negative values. - Get rid of numbering of universal variables (#1037).
- Renamed
base64.decode
/base64.encode
tostring.base64.decode
/string.base64.encode
. - Vumeter is now implemented in Liquidsoap (#1103).
- Change
input.http
andinput.https
url
parameter into a string getter (#1084). - Added
path.home.unrelate
. - Use getters for arguments of
video.add_image
(#1176). - Add
x
,y
,width
andheight
argument toimage
, unify withvideo.add_image
. - Generalize
audio_to_stereo
to video frames and those without audio. - Allow crossfading for video (#1132, #1135).
- Use getters for parameters of synthesizer sources (#1036).
- Renamed
empty
tofail
. - Restored
request.dynamic
(#1213). - Requests are not typed anymore: their type is fixed at resolution time.
- Deprecated
request.create.raw
, you should userequest.create
instead. - Reference setting and access are now handled as normal builtins instead of in the kernel.
- Use records as return type of
http.*
,https.*
,rms
,peak
andrequest.queue
(#1234). - Indices of groups returned by
string.extract
are now integers instead of strings (#1240). - Generalize the
l[k]
notation so that the keyk
can be of any type (on which we know how to compare). ref
is not a keyword anymore: this means thatref x
is not accepted anymore, you need to writeref(x)
(#1254).- Renamed
file.unlink
tofile.remove
. - Deprecated
get_process_output
,get_process_lines
,test_process
andsystem
in favor ofprocess.run
,process.read
,process.read.lines
andprocess.test
. - Renamed
http_codes
tohttp.codes
and put first member as integer. - Renamed
http.response
tohttp.response
andhttp.response.stream
tohttp.response.stream
. localtime
andgmtime
now return a record.- Deprecated
{eat,strip,skip,on}_blank
in favor ofblank.{eat,strip,skip,detect}
. http{,s}.{get,post,push}
now perform redirections if needed, which can be disabled with theredirect
parameter (#1319).- Deprecated
gettimeofday
in favor ortime
, renamedlocaltime
totime.local
andgmtime
totime.utc
, and the argument of these two last functions is now optional (#1320). - Dropped optional
gavl
video converter in favor offfmpeg
. - Remove
persist
argument inoutput.*.hls
and use nullable value forpersist_at
. - Deprecated source server commands in favor or direct call to source methods. Added wrappers for some of the old commands (#1379).
- Deprecated catch-all
input
andoutput
in favor or setting your desired input or output explicitly. - Implement
interactive.*
on script side (#1493). file.write
does not return a boolean anymore, exceptions are used for exceptional cases (#1500).source.dynamic
now takes a nullable argument.- Renamed
on_end
tosource.on_end
. - Changed the name of the arguments of
fallback.skip
. - Normalize ReplayGain handling:
- we now use the standard
replaygain_track_gain
metadata - renamed the protocol from
replay_gain
toreplaygain
- added the
replaygain
operator to perform amplification
- we now use the standard
normalize
now handles all channels uniformly.- First-order filter
filter.rc
now takes the cutoff frequency instead of the time constant as argument. file.watch
now returns unit withunwatch
method.- Changed the interface for
bpm
: the bpm can now be retrieved using a method of the returned source instead of having a callback. - Removed
server.read*
andserver.write*
.
Fixed:
- Set
cloexec
on all relevant Unix calls (#1192). - Fix implementation of recursive functions (#934).
- Make
blank()
source unavailable past is expected duration (#668). - Remove
video.add_text.gstreamer
shade in background (#1190). - Improve the quality of
video.add_text.gd
(#1188). - Exit with non-zero code on errors.
- Fixed parsing of http URI arguments with
=
in them (#1340). - Fixed fade-out in crossfades when crossfade duration is the same as fade-out duration (#1351).
- Fixed osc server not working when daemonized (#1365).
- Fixed glitchy audio when using
input.harbor
(#1944) - Fixed
"tracknumber"
and"year"
returning0
in taglib (#1901)
Removed:
-
LiGuidsoap, the old Liquidsoap GUI. 🪦
New:
- Added
process.quote
to quote process' arguments (#1215)
Changed:
- Fetch mime type using curl first when available.
- Make override metadata name case-sensitive in
amplify
(#1323) - Harnessed playlist file resolver to better support some combination of protocols and file resolution (#1362)
Fixed:
-
Remote file resolution when passing URLs with spaces (#1410)
-
Fixed empty
{http,https}
body (#1417) -
Fixed
input.harbor
shoutcast client connection (#1353) -
Fixed exception reporting when output fails to start (#1372)
-
Fixed
random
track selection (#1468) -
Fixed playlist request leak when using
reload="watch"
withinotify
on a folder (#1451) -
Deadlock when LO server thread crashes (#1409)
Fixed:
-
Fixed exponential memory usage in clock unification algorithm (#1272).
New:
- Added
retry_delay
argument torequest.dynamic
(#1169). - Renamed
request.dynamic
torequest.dynamic.list
and updated its callback function type to return an array of requests, making possible to return multiple requests at once but, more importantly, to return[]
when no next requests are available. (#1169)
Changed:
- Set
audio/flac
as mime for flac (#1143). - Deprecated
request.dynamic
.
Fixed:
-
Fixed errors when installing bash-completion files (#1095)
-
Fixed failures in
extract-replaygain
script (#1125) -
Do not crash when loading playlists using
~/path/to/..
paths. -
Set
set_default_verify_paths
for SSL (#450) -
Use 443 as default port for https (#1127)
-
Fix implementation of
rotate
(#1129). -
Register audio/opus mime type for ogg decoding (#1089)
-
Re-encode name, genre and description in
output.icecast
using the given encoding (#1092) -
Accept 24 bits per sample in %flac encoder (#1073).
-
Fix rare stack overflow during clock unification (#1108).
-
Prevent metadata inserted via
insert_metadata
from being visible to underlying sources (#1115) -
Fix
cross()
fallability. -
Fix decoder remaining time when decoding is done (#1159)
-
Fixed crash when cleaning up
output.hls
-
Fix
get_process_lines
regexp logic (#1151)
New:
- Added
retry_delay
argument torequest.dynamic
(#1169). - Renamed
request.dynamic
torequest.dynamic.list
and updated its callback function type to return an array of requests, making possible to return multiple requests at once but, more importantly, to return[]
when no next requests are available. (#1169)
Changed:
- Set
audio/flac
as mime for flac (#1143). - Deprecated
request.dynamic
.
Fixed:
-
Fixed errors when installing bash-completion files (#1095)
-
Fixed failures in
extract-replaygain
script (#1125) -
Do not crash when loading playlists using
~/path/to/..
paths. -
Set
set_default_verify_paths
for SSL (#450) -
Use 443 as default port for https (#1127)
-
Fix implementation of
rotate
(#1129). -
Register audio/opus mime type for ogg decoding (#1089)
-
Re-encode name, genre and description in
output.icecast
using the given encoding (#1092) -
Accept 24 bits per sample in %flac encoder (#1073).
-
Fix rare stack overflow during clock unification (#1108).
-
Prevent metadata inserted via
insert_metadata
from being visible to underlying sources (#1115) -
Fix
cross()
fallability. -
Fix decoder remaining time when decoding is done (#1159)
-
Fixed crash when cleaning up
output.hls
-
Fix
get_process_lines
regexp logic (#1151)
Fixed:
-
Fixed
fade.final
andfade.initial
(#1009)
New:
- UTF8 parsing!
- Added support for tuples:
x = (1,"aa",false)
(#838) - Added support for deconstructing tuples:
let (z,t,_) = x
(#838) - Added
input.{file,harbor}.hls
to read HLS stream (#59, #295, #296). - Added
output.hls
to natively stream in HLS (#758). - Added
%ffmpeg
native encoder, only for audio encoding for now (#952) - Added ffmpeg-based stream decoder, limited to mime type
application/ffmpeg
for now. - Added
(to_){string,float,int,bool}_getter
operators to handle getters in script side. - Made
p
parameter insmooth_add
afloat
getter (#601) - Added
source.time
to get a source's clock time. - Added
max_duration
to limit a source's duration. - Added
file.temp_dir
to create temporary directories. - Added
file.{unlink,rmdir}
to remove, resp., file and directories. - Added
file.write
to write content to a file. - Added
file.read
to read contents of a file without loading all of it in memory. - Added
youtube-pl:<ID>
protocol to resolve and parse youtube playlists (or any playlist supported byyoutube-dl
) (#761) - Added
protocol.aws.endpoint
setting for thes3://
protocol, thanks to @RecursiveGreen. (#778) - Added support for sandboxing
run_process
calls. (#785) - Added
harbor.{http,https}.static
to serve static path. - Added
log.{critical,severe,important,info,warning,debug}
. Use aliases in code as well (#800, #801, #802) - Added
sleep
function. - Added
mkavailable
function. - Added
fade.skip
function. (#804) - Added
video.external.testsrc
function. - Added
video.frame.*
andaudio.samplerate
. - Added
input.external.ffmpeg
andoutput.external.ffmpeg
. - Added
output.youtube.live.ffmpeg
. - Added
output.file.hls.ffmpeg
. - Added
reopen
telnet command inoutput.external
. - Added
on_frame
(#886). - Enabled external decoders in windows (#742)
- Added support for bash completion.
- Added
video.add_text.native
. - Added
configure.bindir
- Added
for
andwhile
loop functions. - Added
list.case
. - Added
metadata.getter
andmetadata.getter.float
. - Added
string.contains
. - Added
request.uri
. - Added
{input,output}.srt
(#898) - Added
path.remove_extension
. - Added SSL read/write timeout options, use it for incoming socket connections (#932)
- Added ffmpeg resampler (#947).
- Added
lsl
andlsr
.
Changed:
- Depends on OCaml >= 4.08.0
- Changed return type of
http.*
andrun_process
to use tuples (#838) - Better error reporting with coloring and uniform format. (#790)
- Improved reporting of file, line and character during parsing errors.
- Remove dynamic plugin build option.
- Made
on_end
delay a float getter. - Reimplemented
fade.{in,initial,out,final}
as scripted operators. (#664) - Removed
cross
/crossfade
operators, superseded bysmart_cross
/smart_crossfade
- Rename
smart_cross
/smart_crossfade
operators ascross
/crossfade
- Default behavior of
crossfade
is old (simple) crossfade. Usesmart=true
to enable oldsmart_crossfade
behavior. - Rename
file.duration
asrequest.duration
- Removed duplicate
is_directory
- Rename
{basename,dirname}
aspath.{is_directory,basename,dirname}
- Empty playlists return by scripted resolvers is now considered a failure to resolve.
- Rewrite
smooth_add
to use newmkcross
functions. - Reimplemented
open_process_full
to get a hand onpid
and finer-grained closing workflow (#703) - Added
transition_length
toswitch
-based operators to limit transition lengths and allow garbage collection of transition sources. - SDL renders text in UTF-8. (#712)
- Made
x
andy
parameters invideo.add_text
float
getters. (#730) - Reimplemented
extract-replaygain
usingffmpeg
, added an optional replay gain option to theffmpeg2wav
protocol. Thanks to @Yamakaky for contributing on this. (#749) - The
ratio
parameter ofcompress
andlimit
is a float getter. (#745) - Removed
rewrite_metadata
which had been deprecated for a while now. - Allow string getter for
harbor
HTTP responses. - Renamed
get_clock_status
toclock.status
andlog_clocks
toclock.log
. - Renamed
rms_window
parameter ofcompress
towindow
. (#796) - Added
chop
operator. - Keep master tracks' boundaries in
mux_*
functions. (#795) - Added
new_track
optional argument to callback ininsert_metadata
. - Use getters for weights of
rotate
. (#808) - Added
conservative
,length
anddefault_duration
params toplaylist.{reloadable,once,merge}
(#818) - Renamed
input.external
intoinput.external.rawaudio
, addedinput.external.wav
. - Renamed
gstreamer.hls
tooutput.file.hls.gstreamer
. - Raise an error when using a format (e.g.
%vorbis
,%mp3
, ..) that is not enabled. (#857) - Set default encoders and ladspa plugins samplerate and channels to configured
internal
"frame.audio.samplerate"
and"frame.audio.channels"
. (#870) - Handle unary minus in the preprocessor instead of the parser in order to avoid duplicating the parser. (#860)
- Add
filter
option toplaylist.once
. - Added a
replay_delay
option to thepipe
operator to replay metadata and breaks after a delay instead of restart the piping process. (#885) - Add
buffer_length
telnet command toinput.harbor
. - Bumped default
length
parameter for request-based sources (playlist
,request.dynamic
, ..) to40.
to assure that there always is at least one request ready to play when the current one ends. - Added support for cue in/out and fade in/out/type metadata support in
ffmpeg2wav
protocol. Rename protocol toffmpeg
. (#909) list.assoc
andlist.assoc.remove
require an ordered type as first component.- Renamed
quote
tostring.quote
, removedprocess.quote
in favor orstring.quote
(#1635) - Added
phase_inversion={true/false}
to%opus
encoder (#937) - Fixed encoders forcing frame rate and audio channels too early (#933)
- Change filename to a string getter in file-based outputs. (#198)
- Changed
audio.converter.samplerate.preferred
option toaudio.converter.samplerate.converters
to give a list of possible converters.
Fixed:
-
Lack of documentation for
cross
/crossfade
(#743) -
Fixed before metadata being lost during crossfade not in conservative mode.
-
Correct types and default values for
random.int
(#767). -
Allow changing pipeline in gstreamer functions. (#762)
-
Script deadlock after a long time, most likely related to old crossfade transitions (#755)
-
AVI export fixed. (#789)
-
%external
does not stop processes anymore on each metadata. (#789) -
Fixed exit getting stuck when using
input.jack
(#769) -
Stop lo server on shutdown. (#820)
-
Fixed external process stop not detected on second and further calls (#833)
-
Add
seek
in operators where implementation is clear (#853) -
Do not enter buffering mode between tracks in
buffer
(#836) -
Fixed file descriptor leak in external processes (#865)
-
Fixed encoded output creating empty files from failing sources (#876)
-
Fixed
cue_cut
not working when used beforecross
/crossfade
(#874) -
Fixed audio glitches when seeking within a MP3 file.
-
Fixed
insert_metadata
logic when insert new track and metadata (#903) -
Fixed
replay-gain
script default location. -
Fixed audio glitches at the end of crossfade transitions.
-
Specify that
list.remove
removes only the first occurrence and avoid reversing the list (#922). -
File descriptor leak when using openssl-based operators.
-
Fixed SSL read taking too long to timeout (#932)
-
Fixed output starting when underlying source is not available (#393)
-
Fixed
string.escape
also quoting its string.
Changed:
- Reimplemented
open_process_full
to get a hand onpid
and finer-grained closing workflow (#703) - Better log message when request download times out (#708)
- Drop
log.level
forffmpeg
messages to5
Fixed:
-
Timeout when executing external processes (#691, #736, #726, #708)
-
Set buffering only when frame is partial in time_wrap.ml. Makes it work with crossfade transitions (#695)
-
Changed
Icy-MetaData:1
toIcy-MetaData: 1
in HTTP source headers. Fixes some shoutcast implementations (#727) -
Fixed deadlock in
input.http
source status command (#367)
Fixed:
-
Fixed
smart_crossfade
transitions skipping data after track marks. (#683, #652) -
Fixed
input.pulseaudio
parameters. -
Fixed crash when copying frame content (#684)
New:
- Added a bunch of base mathematics primitive,
exp
,log
,cos
,sine
, ... - Added
"extinf_duration"
to parsed#EXTINF
metadata.
Fixed:
-
Fixed inotify watch semantics (#677)
-
Enhanced
#EXTINF
parsing in ambiguous cases (#625) -
Fixed
output.youtube.live
(#630) -
Make sure server writes are synchronous (#643)
-
Fixed crash when loading some frei0r plugins (#435)
-
Fixed compilation with
osx-secure-transport
-
Fixed invalid opus stream generated when no data was ever encoded (#180)
New:
- Added
FFMPEG
decoder using the newocaml-ffmpeg
API. Thanks for @gndl for the hard work there. - Added
"init.allow_root"
setting to allow running liquidsoap as root. - Added
on_track
callback for playlists. Can be used to force a reload. - Added
server.condition
,server.wait
,server.broadcast
andserver.signal
. Used to control server command execution. - Added
server.write
,server.read{chars,line}
to write interactive server commands in conjunction with the above functions. (#544, #568) - Added
output.youtube.live
as a wrapper aroundoutput.gstreamer.audio_video
to stream live to Youtube (#498) - Added metadata extraction to
ffmpeg2wav
protocol (#623).
Changed:
- Depends on OCaml >= 4.03.0
- Depends on camomile > 1.0.0
- Use
http{s}.head
when available to fetch remote file's mime type. (win32 port) - Better log messages for root exit and buffer override.
- Switch default log to stdout. Set to file when
log.file.path
is set (#612) - Disabled Gstreamer stream decoder.
- Removed asynchronous mode for
output.gstreamer.audio_video
- Reworked
smartcross
internal logic (#596) - Enabled
replaygain
onm4a
files, thanks to @gilou (#604) - Added
encoding
parameter tooutput.shoutcast
to allow alternative string encoding for metadata updates (#411) - Deprecated
rewrite_metadata
Fixed:
-
Decouple dyntools compilation.
-
Support for OCaml >= 4.06
-
File descriptor leak in
output.icecast
(#548) -
Fixed URL regexp for
input.https
(#593) -
Multiple gstreamer fixes:
- File decoder with video.
- Memory leaks (#516, #511, #434, #318)
- Process freeze (#608, 278)
-
Duppy crash on exit (#160)
-
Fixed audio glitches when using the
pipe
operator (#614) -
Deadlock in external decoder. (#611)
New:
- Added
on_change
toregister
- Added IPv6 support for
input.harbor
. (#491) - Added
time
,localtime
andgmtime
to help with time-predicates (#481) - Added
on_start
to execute callback when liquidsoap starts. - Added
enable_external_ffmpeg_decoder
to enable ffmpeg-base external decoder. - Added
"decoder.external.{ffmpeg,ffprobe,flac,metaflac,faad,mpcdec}.path"
configuration settings.
Changed:
- Renamed secure transport harbor key paths to:
harbor.secure_transport.*
- Renamed secure transport I/O to:
{input,output}.harbor.secure_transport
. - Added
.wma
togstreamer
file decoder file extensions (#483)
Fixed:
-
Fixed memory leak in
output.icecast
connection method. (#490) -
Fixed
mutexify
-
Make sure that metadata are always passed in increasing position order in
map_metadata
(#469)
Changed:
- Removed
kick
telnet/server command, duplicate ofstop
. - Support
replaygain
for mp3 files, thanks to @d4h3r0 (#460) - Implement
input.harbor.ssl
using SecureTransport for OSX.
Fixed:
-
Fix scheduler loop causing high CPU usage when using Process_handler without some of the default callbacks. (#475)
-
Revert
wait_for
implementation to pre-1.3.0
, using a customselect
loop (#453) -
Handle mime-type arguments in
input.harbor
streams. (#456) -
Tell ocaml to use the same C compiler at build and link time. Fixes build on FreeBSD when using C++-based bindings such as taglib. (#465)
-
Accept any capitalization of HTTP(S) as regular HTTP URL (#464)
-
Fix compilation with osx-secure-transport enabled.
-
Fix deadlock calling logging functions from within
Gc.finalise
(#609)
New:
- Allow any tags allowed in
"encoder.encoder.export"
settings in vorbis streams (#418) - Allow
"audio/mp3"
mime-type for mp3 in file resolution protocol. (#451)
Fixed:
-
Fixed
run_process
,get_process_lines
,get_process_output
when compiling with OCaml <= 4.03 (#437, #439) -
Calls to
wait_for
while the scheduler isn't running (#442) -
Revert default handling of environment in
run_process
,get_process_lines
,get_process_output
to passing calling process' environment by default.
New:
- Added support for recursive functions (#406)
- Add peak and peak.stereo operators (#364)
- Change
track_sensitive
parameter to a boolean getter (fixed value or anonymous function). - Add SSL support to the various harbor operators, either via openssl or OSX's SecureTransport.
- Add optional "dj" and "next" metadata for Shoutcast v2, wrap "dj" value in a callback in output.shoutcast (#370, #388)
- Allow partial parsing of JSON objects in
of_json
. - Generalize list.assoc to allow default values. Legacy code must be updated:
list.assoc(k,l)
->list.assoc(default="",k,l)
- Generalize list.hd to allow default values. Legacy code must be updated:
list.hd(l)
->list.hd(default="",l)
- Allow to pass a default to list.nth. Legacy code must be updated:
list.nth(l,pos)
->list.nth(default=<..>,l,pos)
- Added
on_offset
to execute a callback at a given offset within a source's tracks. - Added mutexify to protect a function from being called concurrently.
- Added request.log to get log data associated with a request
- Added
overlap_sources
to rotate between sources with overlapping tracks. - Added
replay_metadata
toinput.harbor()
- Added
\<char code>
syntax for strings (#368) - Added string.sub
- Added
run_process
to run a process with optional environment and return (stdout
,stderr
,exit_status
) - Added
add_playlist_parser
to register new playlist parsers - Added optional static parameter to
protocol.add
- Added file.temp to create fresh temporary filename
- Added process: protocol
- Reimplemented curl-based fetch process using process:
- Added s3:// protocol to fetch files from AWS S3 using the AWS CLI.
- Added polly: protocol to enable speech synthesis using AWS polly. Generated
files are mono so make sure you use
audio_to_stereo()
. - Added youtube-dl: protocol to resolved requests using youtube-dl
- Added
which()
to find an executable within the $PATH - Added
register()
to allow to register new configuration settings
Changed:
- Reverted default value for
--error_as_warnings
option, renamed to--strict
. - Moved say: protocol registration to utils.liq.
- Moved
get_process_lines
andget_process_output
to utils.liq, added optional env parameter - Set
conservative=true
by default incross()
andsmartcross()
Deprecated (can be removed in any future version):
- Dynamic plugins compilation, deprecated in favor of opam rebuild mechanism.
Removed:
- aac and aacplus encoders, removed in favor of fdk-aac.
- dirac/schroedinger video encoder: obsolete, abandoned upstream.
force_mpeg
option in taglib metadata decoder. Has not been used for years and allows to decouple taglib code from the mad decoder.
Bugfixes:
-
Fix negative seek (#390)
-
Prevent flows metadata updata from stalling sources (#377)
-
Add revdns setting for telnet, set all revdns default to false (#372)
-
Fix icy metadata in output.harbor (#358)
-
Fix missing first line of headers from icy clients in
input.harbor
(#380) -
Fix timestamp in some logged output (#395)
-
Fix crash in external (download) protocol.
-
Fix
fade.{in,out}
metadata handling for new fade duration and type. -
Compute normalization regardless of child sources ready status in
add()
to avoid unexpected change of volume.
New:
- Support for https (SSL/TLS) icecast connections.
- Added
http.{put,head,delete}
,https.{get,post,head,put,delete}
. - Added
input.https
. - Added
list.mapi
. - Added
rotate.sequence
. - New
pipe()
operator to pipe audio data through an external program. - Switched to curl for request resolution/fetch.
Bugfixes:
-
Fix metadata update for shoutcast v2 when sid <> 1 (#320).
-
Fix connection to
input.harbor
using the shoutcast v1 protocol (#337).
New:
- Websocket server (#90): this means that you can stream to harbor directly from your browser!
- Add support for AIFF format (#112).
- Add
url.split_args
to split the argument of an url (#123). - Add
buffer.adaptative
to cope with small network delays (#131). - Add sleeper operator to simulate network delays and test robustness (#131).
- Add
stereo.left
andstereo.right
to extract channels from a stereo stream. - Add restart command to restart liquidsoap (#135).
- Add
file.contents
to read the contents of a file. - Add
filter.rc
for first-order RC filters.
Enhancements:
- Add support for sending OSC data (
osc.send_*
). - Native support for (some) AVI files (#256) which enables support for external video encoders (#233).
- Improve rms operator (#105) to have per channel rms (#102), the ability to dynamically set window duration (#103) and multiple monitors (#104).
- Icecast streaming can now use HTTP1.1 chunked encoding (#82, #107).
- Add support for multiple shoutcast extensions (#216).
- Fade type can be overridden by metadata in
fade.in
/fade.out
(#64). - Allow LADSPA plugins with arbitrary number of channels (#191).
- Rename shine encoder from
%mp3.fxp
to%shine
. - fdkaac: dynamic plugin (#79), set afterburner parameter, use MPEG4 by default (#83).
- Improved subtyping on lists (#125, #126).
- Add native simple JSON decoder.
- Better code: do not abusively use assertions (#137), issue more warnings and fix them (#162).
Bugfixes:
-
Correctly close connection in http.get / http.post (#72).
-
Remove
input.lastfm
which has been broken for a while. -
Lots of small bugfixes.
New:
- Add support for FDK-AAC, which seems to be the best AAC(+) encoder around for now. Replacement candidate for VO-AAC and AACPLUS
- Add %ifencoder to check whether Liquidsoap was compiled with support for a particular encoding format.
- There is now an emacs mode in scripts/liquidsoap-mode.el.
- Liquidsoap can be used as a Windows service.
Enhancements:
- Handle more OSC types (
float
,float_pair
,bool
,string
,string_pair
) and addedosc.on_*.
- Better infrastructure for decoding images.
add_image
can now handle most image file types. - Add
random.int
as well asmin_int
andmax_int
to standard library. - Add
playlist.merge
to play a whole playlist as one track. - Add
gstreamer.hls
to play http live streams (HLS). - Add
say.program
to specify text-to-speech program in scripts. - Add "random" transition type to
video.fade.*
in order to select a random transition each time. - Add max parameter to drop data on buffer overrun with
input.gstreamer.*
. - Add
bytes_per_page
parameter to ogg encoders. - Add support for DTX in speex and opus, as well as VAD for speex.
- Localize some more parsing errors in files.
Bugfixes:
-
Avoid deadlocks in harbor.
-
Correctly flush lame encoder.
-
Correct sequence operator when there is only one source.
-
Handle relative URLs in http playlists.
-
portaudio is now an active source.
-
Avoid jack I/O lowering the volume.
** This version brings some new features as well as correcting bugs. **
New:
- Add support for GStreamer decoding, processing and encoding (%gstreamer format, v4l webcam input is now implemented using GStreamer).
- Add support for opus decoding and encoding.
- Add support for the shine encoder, which can efficiently work on architectures without FPU.
- Add support for automatically computing the duration of tracks in the
"duration" metadata [LS-641]. It can be enabled with
set("request.metadata_decoders.duration",true)
- Add support for frei0r video effects.
- Allow
%define
'd variables in encoding formats [LS-634], e.g.%define BITRATE 24 %define STEREO true output.file(%mp3(bitrate = BITRATE, stereo = STEREO),"bla.mp3",s)
Enhancements:
- Taglib now reads all metadatas (even non-standard ones).
- Add a mode to automatically reload a playlist when the file was changed
[LS-363,LS-523]. For instance,
s = playlist("~/Music",reload_mode="watch")
. Also, addfile.watch
to call a callback when a file is changed, with inotify support when present. - Add support for FFMpeg as video converter, which you can use with
set("video.converter.preferred", "ffmpeg")
- Add
back_time
argument to blank operators [LS-609]. - Add a metadata to override fade.final duration.
- MIME is computed at most once when extracting replaygain.
- Default samplerate converter is now "fast".
- BPM detection (bpm) now uses a callback.
- Add
clock.unify
to unify clocks of all sources from a list. - Add
source_url
metadata toinput.http
streams. - Improved error message when theora format is not supported.
- Add list.filter function.
video.add_image
can now take any image format as input.- Add
mux_stereo
. - Support for external decoders in streams.
- Move bugtracker to https://github.com/savonet/liquidsoap/issues
Bugfixes:
-
Configure is now compatible with OCaml >= 4.0 and removed support for OCaml < 3.11 [LS-625].
-
Fix random memory access / memory leak when decoding AAC/MP4 files [LS-647].
-
Correct resampling of wav files.
-
Use the length for data indicated in header for wav files.
-
Argv.(0)
now returns the script name [LS-605]. -
Liquidsoap should now operate fine when compiled with -noassert [LS-578].
-
Better handling of inexistent MIDI channels.
-
Video decoder now correctly handles videos from Icecast.
-
Avoid visu.volume freezing Liquidsoap on shutdown.
-
Fix a memory leak when decoding both audio and video in ogg [LS-636].
-
More efficient handling of video converters, also fixes some crashes [LS-623].
-
Have the soundtouch operator preserve tags [LS-621].
-
Fix remaining time estimation in cross and
smart_cross
. -
Avoid deadlocks in harbor and
input.http
. -
Remove leftover files in configure [LS-567].
-
Handle wav files with padded fmt headers.
-
Handle end-of-stream when seeking mp3 with mad.
** This version brings bug fixes and minor enhancements over 1.0.0. **
Fixes:
- correct type for the "flush" parameter in
output.external()
thanks to Romaric Petion for pointing it out - fix bug where MP3 encoder would discard initial ID3v2 rendering
- fix bug where
smart_cross()
would stop before the end of tracks, thanks to Edward Kimber for raising the issue - load libraries in --interactive [LS-618]
- update examples, notably the installed radio.liq thanks to Emery Hemingway for noticing the problem
- generalize the types of
input.http()
andinput.harbor()
to allow variable content kinds, and also allow video for harbor [LS-601] request.equeue()
now allows to remove requests from the primary queue- fix compilation of lame dynamic plugin.
New:
-
new values for metadata fields does not override old one anymore; use setting
request.metadata_decoders.override
to restore old behavior -
stereo_mode
andinternal_quality
parameters for %mp3 encoder -
enable mad decoder for MP1 and MP2 in addition to MP3, create aliased configuration keys "decoder.file_extensions/mime_types.mad"
-
support for CUE sheet playlists and metadata in M3U
-
setting "decoder.taglib.force_mpeg" to force taglib to consider files as MPEG
-
scripting builtins
getenv()
,setenv()
andenvironment()
-
scripting builtin
source.fallible()
-
harbor is now verb-oriented, supporting GET, POST, PUT, HEAD, DELETE, OPTIONS
-
load DSSI plugins from environment variables and using
dssi.register()
-
also display the type of the whole expression when -i is passed
-
generalized custom path support for facilitating standalone distributions
-
and as usual, various improvements in the code, log and error messages, etc.
Finally, the 1.0.0 release! It brings several important fixes, but
also some nice novelties.
The most outstanding difference concerns output.icecast()
: its restart
and restart_delay
parameters are gone, replaced by a new on_stop
handler
which is called on every error (failed connection or disconnection) and
returns the new restart delay. The on_error
handler receives a string
describing the error which enables user-friendly reporting, adaptative
delays, etc.
Note that on_error
defaults to fun(_)->3
. which is equivalent to having
restart=true, restart_delay=3. in previous versions, NOT the same as the
former restart=false default. As a result, liquidsoap won't fail to startup
if an initial connection attempt fails.
Fixes:
-
LS-532,527: avoid freeze after errors in streaming threads or source initialization routines
-
LS-542: race condition in
playlist*()
breaking randomness -
LS-489: double expiration lead to illegal queue length and freeze of request-based sources
-
Avoid multiple simultaneous reloading in
playlist*()
, thanks to Fabio Costa for his help on this one! -
Pass charset information to icecast server to avoid encoding bugs
-
LS-555: timeout for icecast connection attempts
-
LS-559: permanent stop after disconnection on Ogg streams
-
LS-565: efficient and crash-free error handling in
input.http/harbor()
when the input stream has an invalid number of channels -
LS-431: proper handling of duration in
blank()
avoids abusive empty tracks -
LS-556: rework conversion operators, optimizations used to be unsafe & broken
-
LS-574: silent MIDI synthesis operators
-
LS-396:
drop*()
's types reflect that they don't support variable arities -
LS-442: allow comments not terminated by newline at end of file New:
-
on_error
handler inoutput.icecast()
, see above -
New msg param in %mp3 for marking frame headers, defaults to version string
-
output.file()
: newon_close
parameter, may be used to write exact duration -
%mp3.vbr/abr for variable bitrate MP3, %mp3 is now a synonym of %mp3.cbr
-
MP3 encoders now support ID3v2 tags
-
input.http()
: new "status" command -
LS-556:
mux_mono()
for adding a single audio channel into a stream -
video.add_text()
using libgd (gd4o) for environments without X Dependency on graphics can be disabled (to work around erreneous detection) -
script language: add infix operator mod (patch by Fabio Costa)
-
delay()
now has an "initial" parameter -
LS-557: "server.timeout" setting can now be disabled by setting it to -1
-
LS-532:
source.init()
for selective init with a way to handle errors, plus settings "clock.allow_streaming_errors" and "init.force_stat" (or --force-start on the command line) for easing dynamic uses of liquidsoap Enhancements: -
Panic crash to avoid frozen liquidsoap after duppy crashes
-
Text-to-speech: festival and sox are now only runtime dependencies
-
LS-475,516: better support for dynamic URL change in
input.http()
-
LS-484: display user-friendly error messages in interactive mode
-
LS-308: use seconds internally in request sources, avoid overflow and display more user-friendly debug messages
-
Cleanup
visu.volume()
andvideo.vis_volume()
-
LS-573: replace " " by "_" in identifiers to make them valid in the server
-
Script syntax: unary minus now usable without parenthesis after semicolon
-
Two generic queues by default, to avoid deadlocks in advanced situations
-
Documentation, build & install system, etc.
-
Feature: Added
of_json
to parse json data. Depends on json-wheel. -
Feature: Added file.exists and is_directory.
-
Feature: Added timeout options for: telnet, harbor (server), input.icecast
-
Enhancement: finer-grained timeout detection for
input.harbor
andinput.http
-
Fix: deadlock when disconnecting harbor users through server/telnet command.
-
Fix: dynlink detection in native mode with old versions of ocaml
-
Fix: deadlock when an exception is raised during startup while the clock is owned by a source (e.g.
input.alsa
). See LS-527 for more details. -
Fix:
playlist.safe()
was unusable in beta2, as a side effect of removing duplicate "timeout" parameter inplaylist()
. -
Minor enhancements to documentation, settings and reference.
This release introduces lots of fixes and cleanup, but also some new features.
Major novelties: support for fast seeking and cue points, FLAC and improved
AAC+ support, introduction of the liquidsoap yellowpages "flows",
plugin support and improved messages for scripting errors
Compatibility warning: insert_metadata
has changed, and clock.assign_new()
should be used instead of clock()
to avoid some of the new static checks
Decoders:
- New support for seeking and fast computation of durations in most formats
- New decoders: FLAC (native & Ogg) and images using Camlimages
- Fixes in Ogg decoding: LS-515 (loss of data) and LS-537 (segfault).
- Fix LS-337: periodical failures when decoding AAC(+) streams
- AAC(+): use new ocaml-faad with builtin mp4ff, easier to build
- New detection mechanism mixing extensions and MIME types (when available),
with corresponding settings
decoder.file_extensions.<format>
anddecoder.mime_types.<format>
. - Decoder order can be user-defined thanks to new settings "decoder.file_decoders", "decoder.stream_decoders" and "decoder.metadata_decoders".
- Indicate which decoder is used in the "decoder" metadata
- More helpful log for various errors
- Fix segfault with SdlImage image decoder
Encoders:
- New FLAC encoders %flac (native) and %ogg(%flac)
- New AAC+ 2.0 and vo-aacenc
- New settings to theora: keyframes make files much smaller!
- New settings for WAV encoding: headerless, samplesize.
- Fix segfaults with ocaml-aacplus
- Enhancement LS-441: filter metadata before encoding, based on the "encoder.metadata.export" setting.
- Rework infrastructure of encoded outputs to fit all formats, outputs and styles of metadata handling, file reopening (#386)
Harbor:
- New:
output.harbor()
which acts as a mini icecast server, accepting listeners directly. Encoding is shared among users, and is only performed when needed. - New: ability to register HTTP GET/POST handlers to create simpler
web services, using
harbor.http.register/remove()
. - Make all settings local: port, user and password can be set independently
for each
input.harbor()
source - New: "metadata_charset" and "icy_metadata_charset" in
input.harbor()
- Fix: race condition possibly leading to abusive "source taken" (LS-500)
Icecast:
- Add support for streaming native flac, only works when streaming to
input.harbor()
, not supported by actual Icecast servers - Fix bugs in ICY protocol support (header parsing, user name)
- Use ICY metadata updates when streaming AAC(+)
- New: "encoding" parameter for
output.icecast()
, used for recoding metadata Defaults to "latin1" with shoutcast servers - New:
icy.update_metadata()
function for manual updates - Enhance default "song" metadata, avoiding " - " when unnecessary (#467)
Input/output:
- New experimental
input.v4l/v4l2()
for webcams - New experimental
input/output.udp()
for unchecked UDP streaming, available with most formats (at your own risk) - Restore
output.pipe.external()
, now calledoutput.external()
- New parameters for most outputs and inputs (start, on_start, on_stop, fallible); cleanup and uniformize implementations (LS-365)
- New ALSA settings alsa.alsa_buffer, alsa.buffer_length and alsa.periods Setting periods=0 allows to not attempt to set the number periods, which is impossible on some devices
- New preference order in
input/output.preferred()
: pulseaudio, portaudio, oss, alsa, ao, dummy
Operators:
- New: support for cue points with
cue_cut()
- Change
insert.metadata()
which is now more script friendly, returning an insertion function rather than register a server command. The old functionality is available asserver.insert_metadata()
. - New:
rms()
operator for getting RMS of a stream, andserver.rms()
which makes this information available as a server command. - New:
track_sensitive
mode for blank detection operators - New:
playlist.reloadable()
for playing a list once, with a command for restarting it. - Remove
id.*()
which can be replaced by type annotations
Scripting API:
- New: OSC support through
osc.bool()
,osc.float()
andosc.float_pair()
- New: JSON export
json_of()
- New:
http.get()
andhttp.post()
- New:
url.encode/decode()
,base64.encode/decode()
- New:
string.recode()
for charset conversions using camomile - New:
notify_metadata()
andosd_metadata()
, suitable for use withon_track()
andon_metadata()
- New:
request.metadata()
for getting a request's metadata - New:
string.length()
- Enhance
log_clocks()
with parameter for delaying startup - Enhance
get_clock_status()
with "uptime" reference time
Server interface:
- Print the playlist's URI when calling
<playlist>.uri
without an argument. - Enhance
<queue>.ignore
now works also in the primary queue - New command for changing the URL of an
input.http()
, ref #466. The command is<id>.url
and it needs a restart (<id>.stop
, then start) to take effect. - Fixed double registration of server commands which resulted in broken "help" command (LS-521)
Script language:
- Option "-i" doesn't show types for pervasives anymore
- Pretty printing of types (LS-474) with indentation, also used in the documentation
- Enhanced type errors (LS-459): no more traces, only the relevant part of types is displayed, plus a few special friendly messages.
- Enhanced static checks (LS-123) thanks to the introduction of the
active_source
subtype, for unused variables and ignored values This should avoid common errors, help troubleshooting If needed, advanced users can work around errors using --check-lib and --errors-as-warnings
General:
- Do not attempt to install "daemon" files if user/group have not been set, unless forced using "make INSTALL_DAEMON= install"
- Fix several core "source protocol" bugs, causing assert failures and other crashes: LS-460 (source becomes not ready without operator knowing) #403 (information about being ready is not precise enough)
- Fix incorrect image accesses (LS-430) by introducing a safer VFrame API
Applies to most video operators (
video.fade()
,video.text()
, effects...) - Cleanup resource (de)allocation, which is becoming critical with dynamic
reconfigurations (e.g., dynamic output creation,
source.dynamic()
) Enforce that server commands are always deallocated (LS-495) Attempt to stop sources when initialization fails, so they cleanup as much as possible (LS-503) Avoid deadlocks upon crashes in IoRing-based operators Share code for stoppable feeding threads, use it ininput.harbor()
Avoid useless initialization of SDL systems - Dynamic loading of lame and aacplus libraries, making it possible to ship them as separate binary packages. This is particularly useless for non-free libraries and for those that depend on X (e.g., SDL) which is often undesirable on servers
- Support for separate compilation of most optional features as plugins
Use
--enable-<feature>-dynamic-plugin
in ./configure and --dynamic-plugins-dir in liquidsoap - Better Win32 support, more version checks, separate compilation of C files and compliance with Debian's OCaml standards
- Externalize many audio and video functions in the new ocaml-mm library Factorize and optimize various conversions
- Rewrite harbor and server code using the new Duppy monad, introducing camlp4 into the build system
- New regression tests (make test)
- More user-friendly exception printing
- Avoid problems preventing backtrace printing
Miscellaneous:
-
Update liguidsoap, make microphone input optional (LS-496)
-
Do not crash upon charset-recoding failures [LS-473]
-
Fix in
source.dynamic()
: missing source re-selection [LS-354] -
Avoid deadlock on startup in daemon mode [LS-229]
-
Fixes in LADSPA and SDL causing early freezing of Frame parameters.
-
Fullscreen mode for
output.sdl()
-
Fix: SIGPIPE used to cause crashes (LS-53,LS-287)
-
Fix:
video.volume()
could crash upon some end-of-track situationos -
Fix: properly escape filenames in external file duration methods
-
Rework timeout management for various sockets (notably icecast & harbor) Set nodelay, remove
TCP_*TIMEOUT
[LS-508,LS-509]
This beta version introduces two major new features: heterogeneous stream types and clocks.
New:
- Different sources can carry different types of content.
- Encoding formats have been introduced to help infer stream content types. This brings static checking for bounds in encoding parameters.
- Introduce conversions between stream contents (mono, stereo, drop audio, video, etc) and muxing.
- Allow explicit type annotations in scripts.
- Introduce clocks, cleanly allowing for the coexistence of different time flows, and avoiding inconsistencies that can result from it. Soundcard I/O and cross-based operators notably make use of it.
- Remove root.sync, replaced by attaching a source s to clock(sync=false,s).
- Enable dynamic source creation and
source.shutdown()
. - Extend and adapt MIDI and video operators.
- Introduce purely metadata streams (audio=video=midi=0 channels) and metadata stream decoder.
- Support WAV streams in
input.http/harbor()
. - Introduce static image decoder using SDL image.
- Remove bound of request identifies (RID).
- Experimental:
source.dynamic()
for advanced dangerous hacking. - Make path relative to script in
%include "PATH"
, and introduce%include <...>
where path is relative to liquidsoap library directory. - Add
channels_matrix
parameter tooutput.ao()
. - Add
on_(dis)connect
hooks ininput.harbor()
.
Cleanup and fixes:
-
Lots of cleanup and fixes as with all major code rewriting.
-
Optimize video and stabilize it a little bit... still not perfect.
-
Rewrite stream and file decoding API, as well as file format detection.
-
Enhance shutdown and error message reporting, notably for icecast and request-based sources.
-
Avoid quasi-infinite loop in failed request resolving.
This release is a bugfix of the latest snapshot (0.9.2). It will be the last bugfix before 1.0.
Bugs fixed:
-
Add "audio/mpegurl" to the list of mime-type for basic playlist parsing.
-
Decode arguments passed to
input.harbor
. -
Use Camomile framework to try to recode arguments and user/password passed to
input.harbor
. -
Support Theora 1.1 API via ocaml-theora 0.2.0.
-
Fixed
input.lastfm
. -
Fixed SDL output.
-
Allow magic file type detection to follow symlinks.
This release is a SNAPSHOT of upcoming features. It also contains several important bugfixes. As a snapshot, it contains experimental or unpolished features, and also breaks compatibility with previous versions. You should in particular notice the two "New" items below:
random(strict=true)
is now calledrotate()
;- request sources (
playlists
,request.*
) have a new queuing behavior, check the doc (request-sources.html) or revert to conservative=true.
Bugs fixed:
- Ogg encoder now muxes pages according to their ending time.
- Support "ogg/audio" and "ogg/video" mime types for HTTP ogg streams.
- Changed external encoder's "restart_encoder" to the more relevant "restart_on_new_track". Added optional "restart_after_delay" to restart the encoder after some delay. Also completely rewrite stop mechanism. Stop operation now waits for the encoding process to finish, allowing proper restart_on_new_track like for ogg encoded data.
- Factorized buffered I/O code. Also added a blocking API, which avoids
"no available frame" and "reader not ready" messages and audio glitches.
It enforces that
root.sync
be deactivated for these sources, such that synchronization is done by the source. (#203) - Factorized file decoding code.
- Fixed reversed order when parsing playlists using
playlist.parse()
. - Avoid bad crashes when resources lack, e.g. no more memory.
- Tighten and enforce the inter-source protocol.
- All outputs: fix the autostart server command. With the former code, a modification of the autostart parameter was only taken into account one start/stop cycle later.
on_blank()
: fix a bug that prevented the first call to on_noise.- Fixed estimated remaining samples on ogg files, fixes issues with
operators relying on this value, in particular
crossfade()
and request-based sources when operating in non-conservative mode. - Fixed socket descriptor leak in
input.http
. (#318) - Fixed deadlock at init when an exception was raised at wake_up phase. (#319)
- Fix
delay()
which could sometimes incorrectly declare itself ready, and thus try to get some data from its unavailable input source. - Bug in queue duration estimation led to infinite feeding of the queue, until all request IDs are taken.
- Several fixes enforcing clean (non-deadlocking) sleep/shutdown.
New:
- The operator
rotate()
replaces random(strict=true), andrandom()
does not have a strict parameter anymore. - Switch to new behaviour in request-based sources. Use conservative=true to get to the old behaviour.
on_blank()
: provide anon_noise
handler.playlist*()
: add server commands for reloading the playlist and changing its URI.- Fallible outputs: all outputs now have a fallible mode, in which they accept fallible sources, and automatically start/stop when the child fails to stream.
- EXPERIMENTAL ogg/dirac encoding support.
output.*.aacplus()
: native outputs encoding in AAC+ using ocaml-aacplus.- Switched to a custom implementation of the various shout protocols. It notably allows arbitrary content-type settings which enables AAC+ streaming. Enabled wrappers for external encoders for AAC+ format aacplusenc (#220 and #136). Also added custom IRC, AIM and ICQ headers to shoutcast wrappers (#192).
- Harbor now supports Shoutcast/ICY headers properly. This allows in particular the use of any supported data format for the source client.
- Harbor sources now also consider "song" field when updating metadata.
- Added built-in support for m4a audio files and metadata. Made external support optional through enable_faad.
- Added optional resampling for output.external operators (#273).
- Added optional host and port parameters for audioscrobbling submissions. Allows to use alternate systems, such as libre.fm of jamendo's compatibility API. Added nowplaying submission, and various wrappers, including a full submission process (now playing at beginning, submit some times before the end).
- New variables in the script language:
liquidsoap.version
andconfigure.{libdir,pidfile,logdir}
. - Added built-in support for replay_gain, through the replay_gain protocol
(enabled by default) and the replay gain metadata resolver (to be enabled
using
enable_replaygain_metadata()
). (#103 & #317) - Reverse DNS operations can be disabled using settings keys
server.telnet.reverse_dns
andharbor.reverse_dns
.
Experimental:
- MIDI: file decoding, synthesis, virtual keyboard.
Removed:
-
RTP input and output.
-
Removed decoders using ocaml-natty. Slow, unmaintained and superseded by the mplayer decoder.
Bugs fixed:
- Fixed request task not ending properly for request-driven sources (playlist, request.queue, request.equeue). Fixes a problem reported when reloading an empty playlist multiple times. (#269)
- Fixed math.h usage in rgb_c.c.
- Fixed append operator. (#284)
- Fixed OSS compilation for non-linux systems.
- Disconnect idle harbor sources after timeout has expired. Thanks to Roman Savrulin for reporting and fixing !
- Taglib metadata resolver is only used on files decoded by the MP3 decoder.
New:
-
Get a node's striping status when stripping blank with
strip_blank
(#260). -
on_connect
function forinput.harbor
now receives the list of headers given by the connected source (#266). -
Added
on_end
operator, to execute a handler when a track ends. -
Added estimated remaining time in the queue length for request-driven sources (
request.{equeue,queue}
,playlist
). This allows these sources to prepare less files in advance. In particular, primary queue may only contain the file currently played. Default behaviour has been set to the old behaviour, and a conservative option has been added to switch to the new behaviour. New behavivour will be the default for the next release. fixes #169, references #146
Bugs fixed:
- Fixed byte swapping function.
- Fixed unix server socket failure (#160).
- Fixed mp3 audio glitches when decoding files with picture id3v2 tags using ocaml-mad (#162).
- Fixed liquidsoap crash on weird telnet and harbor input (#164).
- Fixed
request.queue()
not considering initial queue on wake-up (#196). - Fixed source leak in
append()
. - Fixed
after_output
propagation in the transitions of switches (#208). - Fixed compilation for ocaml 3.11 (#216).
- Fixed (again) Vorbis mono output (#211).
- Avoid crashing on broken symlinks when parsing directories (#154).
- Use random temporary file in liGuidsoap.
- Fixed liGuidsoap to use the (not so) new metadata field initial_uri.
- Fix bugs in the life cycle (sleep/wake_up) of queued request sources,
which made
say_metadata
unfunctional. - Remove buggy unbuffered
{input,output}.jack
. (#231) - Fixed audio information sent to icecast. (#226)
- Fixed global reset starting inactive sources. (#227)
- Fixed shoutcast source initial answer in harbor. (#254)
- Fixed frame and metadata duplication in cross operators. (#257)
- Fixed several sources (outputs, external streams) that were not going to sleep correctly.
Changes:
- Warning:
interactive_float()
is nowinteractive.float()
.
New:
-
Compatible with OCaml 3.09.
-
Faster shutdown.
-
Rewrote ogg decoding, for files and streams.
-
Support for ogg skeletons, currently only used for theora.
-
Cleanup icecast class hierarchy and restart mechanism, especially with respect to the encoder.
-
Support for breaks and metadata in generators. As a result,
input.http()
andinput.harbor()
now fully support them. See new_track_on_metadata parameters there. -
Switch operators (fallback,random and switch) can now replay the metadata of a source that has been left in the middle of a track.
-
New
force_mime
parameter forinput.http()
. -
New
insert_missing
parameter forappend()
. -
Multi-line strings in liq scripts, with a caml-like syntax.
-
Slight modification of the scripting syntax, handling unary minus.
-
Added
user_agent
parameter forinput.http
andinput.lastfm
-
Added speex support for files and HTTP streams.
-
Added EXPERIMENTAL support for AU, AIFF and NSV mp3 audio files using ocaml-natty.
-
Added "prefix" parameter to the playlist operators. Allows to prefix each uri in order to force resolution through a specific protocol, like replaygain: for instance. (#166)
-
Support for external processes as audio encoder:
- Added output.icecast.lame to output to icecast using the lame binary.
- Added output.icecast.flac to output to icecast using the flac binary.
- Full generic support awaits some changes in libshout.
-
Support for external processes as audio stream decoder:
- Added
input.mplayer
to stream data coming from mplayer.
- Added
-
Support for external processes as audio file decoder:
- Added support for flac audio files using the flac binary.
- Added support for m4a files using the faad binary.
- Added optional support for mplayer, enabled with
enable_mplayer()
.
-
Support for external metadata decoders.
-
Support for generic authentication function in harbor, also available for ICY (shoutcast) clients.
-
Added optional support for the samplerate library, and dynamic configuration of resampling routine.
-
Added
lag()
operator, which delays a stream by a constant time. -
Initial support for PulseAudio.
-
Added experimental support for
{input,output}.marshal
, allowing raw communication between various liquidsoap instances. -
Added optional alternatives to store buffered audio data:
- raw: in memory, s16le format
- disk: on disk, several big files
- disk_manyfiles: on disk, a lot of small files See documentation for more details.
-
Added EXPERIMENTAL video support:
- Support for ogg/theora file input.
- Support for ogg/theora file and icecast output
- Support for SDL output.
- Optional support for ocaml-gavl as video converter.
- Support for video in some existing operators, including switches,
add()
, metadata/track manipulations. - Added operators:
video.fade.*
,video.fill
,video.greyscale
,video.image
,video.invert
,video.lomo
,video.noise
,video.opacity
,video.opacity.blur
,video.rotate
,video.scale
,video.sepia
,video.text
,video.tile
,video.transparent
,video.volume
.
-
Fixed metadata propagation during default transition in smart_crossfade
-
Changed transition evaluation order in smart_crossfade
-
Fixed transition function in smart_crossfade
Bugs fixed:
- Vorbis mono output is now working
- Fixed parameter parameter description in the documentation
- Propagate new delay in add_timeout
- Fixed inter-thread mutex lock/unlock in playlist.ml
- Fixed "next" playlist command
- Fixed race conditions in request_source.ml feeding task
- cross/smartcross: raise the default for inhibition as setting it to exactly duration is not enough
- Don't fail when $HOME is not set
- Fixed metadata update in
input.harbor
with icecast2 source protocol - Fixed shutdown function. Fixes #153
- Fixed
input.oss
. Liquidsoap now works with OSS4 ! Fixes #158
New:
- Added a hook to execute a function when playlist.once ends
- Enhanced smart_crossfade
- Added string.case and string.capitalize
- New "exec_at" operator, to execute a function depending on a given predicate
- Added script example in the documentation to listen to radio Nova and get the metadata from a web page.
- Changed parameters name in fallback.skip to reflect who are the fallback and input source.
- Added a dump file parameter to
input.harbor
, for debugging purpose. - Added an auth function parameter to
input.harbor
for custom authentifications. Fixes #157 - Added "primary_queue" and "secondary_queue" commands to request.queue and request.equeue sources. Also set the metadata "queue" to either "primary" or "secondary" for each request in the queue. Documented it too.
- Insert latest metadata for a node of a switch source when switching back to it in a middle of a track.
- Added a 'conservative' parameter to cross, smilar to the one in smartcross.
Internal:
-
Enhanced liqi documentation parser to build the website.
Bugs fixed:
- Now works on FreeBSD and hopefully other unices that are stricter than Linux about Mutex usage.
input.http()
now has abind_address
parameter.- Harbor socket now has a timeout for lost connections.
smartcross()
is now more compliant with the inter-sources protocol, fixes several "get frame didn't change the buffer" bugs.- Ogg packeting bugs.
- Buffering policy in
input.http/harbor()
. - No "." in IDs and labels.
- Resources: FD leaks, useless threads (threads leaks?) in
input.http()
. fade.out()
used to run into infinite loops when the delay was 0.
New:
- New documentation system and website.
- Self-documenting server with a more helpful "help" command.
- Moved to duppy: less threads, lighter load, and an configurable scheduler.
- Moved to Taglib for more reliable access to MP3 metadata.
- MIME types, notably for playlists and MP3 files.
- New Jack support. The old one has been renamed to
in/output.jack.legacy()
. - Harbor: per-mount passwords and the stop command to kick a source client.
- Official Last.FM client.
- Metadata is no more punctual but interval-based, which suppresses some surprising behaviours.
- Perfected daemon behaviour.
- All
output.file.*()
now have the features that used to be only inoutput.file.vorbis()
, notable re-opening. Added %w to the strftime-like format codes allowed in their filename parameter. - Add
clear_metadata()
andmap_metadata()
. Now,rewrite_metadata()
is a simple specialization ofmap_metadata()
, written in utils.liq. - Dynamic amplification factor in
amplify()
, e.g. useful for replay gain. - Lots of new functions in the scripting API: for lists, requests, system interaction, shutdown, command-line parsing, scripted server commands, etc.
As always:
-
code cleanup, style, etc.
Bugfix release:
-
Close Http socket
-
Add http socket timeout
-
Close playlist file after reading its content
-
Fix http redirect support for lastfm files
-
Fix file open leak in camomile support
-
Fix playlist uri ending with "/"
Bugfix release:
-
Fixed #57: scpls and mpegurl playlist parsing
-
Fixed #46: Late cross-scripts bindings
Notation: "-" stands for a change, "+" for an addition.
-
Language
- Support for polymorphism, subtyping and basic ad-hoc polymorphism, which allows a much simpler API, notably for maths and serialization.
- Added
interactive_*()
for mutable values.
- The right syntax for settings is now set("var", value) and can be used anywhere in the scripts.
- The volume parameters of most operators are now in dB.
- Many builtin functions added.
- Nicer type error messages.
-
Sources
- Added
input.lastfm()
to relay last.fm streams. - Added
input.harbor()
to received Icecast2 source streams. - Added
noise()
to generate white noise
- Reimplemented playlist support, added various xml and text formats.
- Added mpd protocol to find files using mpd.
- Added
-
Operators
- New effects:
compress()
,flanger()
,pan()
. - New filters:
filter.fir.*()
,filter.iir.*()
,filter.biquad.*()
,comb()
. - Added support for LADSPA effects.
- Added
eat_blank()
to remove blanks.
- New effects:
-
Outputs
- Added non-default restart option for
output.icecast.*()
. - Added the possibility to tweak some settings at runtime.
- Split
output.icecast.vorbis()
intooutput.icecast.vorbis.*()
to distinguish between encoding modes -- and similarly for output.file.vorbis and mp3. - Better handling of Icecast disconnections.
- Added non-default restart option for
-
IO
- Added portaudio support.
- Jack support is now somewhat working.
-
As usual, lots of bug fixes, careful polishing & much more...
-
Major cleanup of the core stream representation; moved to float arrays, removing several back-and-forth conversions and enhancing the perfs a lot; reviewed all sources and operators, made many minor enhancements btw.
-
Lots of sound processing operators: compand, compress, normalize, pitch, bpm, soundtouch, saw, square, etc. Add more shapes to
fade.*()
. -
New track processing operators: insert_metadata, on_track.
-
Smart cross: allows to select a transition based on the volumes around the end-of-track.
-
Support for AAC encoding/decoding.
-
Several fixes to output.icecast.mp3 in order to support shoutcast servers.
-
Automatic format recognition for
input.http()
, support for playlists. -
OSS I/O.
-
Unbuffered ALSA I/O for low latency.
-
Server interface via UNIX domain sockets.
-
Better output.file.vorbis with support for re-opening the file, appending, interpolate strftime format codes, etc.
-
Add pre-processing and math primitives to the language, new
_[_]
notation forassoc()
, ruby-style anti-quotation("..#{..}..")
,add_timeout()
,execute()
,log()
... -
Ability to tweak the internal PCM stream format.
-
Classify sources and operators in categories for more structured doc.
-
Started a few visualization operators, text and graphics based.
-
Several bug fixes: request leaks, sine frequency, switch, etc.
-
New portable output to speakers using
libao()
. -
Updated liGuidsoap to use it until ALSA gets enhanced.
-
Implemented a decent estimation of the remaining time in a track.
-
Added the
cross()
operator allowing cross-fading. -
Generalized
say_metadata()
intoappend()
andprepend()
. -
Per-track settings for
cross()
,fade.*()
,prepend()
andappend()
using requests' metadatas. -
Implemented
input.http.mp3()
, including support for icy metadata. -
New
pipe()
operator which allows one to filter the raw audio through an external program. However, sox and other common tools aren't suitable for that because they don't flush their output often enough. -
New
on_blank()
operator for calling a callback on excessive blanks. -
Restart outputs on insane latencies.
-
Type checkings for settings.
-
Setting for not starting the internal telnet server.
-
Now handles old and new versions of Camomile correctly.
-
Internal fixes and polishing (switches' cached selection, empty tracks..)
-
More standards-compliant tarball
-
Generate doc with locally built liquidsoap
-
Try to cope with ill-formed mp3
-
Updated for newer versions of Camomile
-
So-called "strict" random-mode
-
Many minor and major fixes at every level!
-
Conversion of metadata to UTF8.
-
Got rid of too many threads by scheduling all download tasks in a single thread, and handling all of the server's clients in another single thread.
-
Simplified the time interval syntax and integrated it to the script language.
-
New protocol: Wget for FTP, HTTP and HTTPS.
-
Ability to define a new protocol from the script, typically using an external app/script for resolution, such as bubble.
-
Ability to use an external app/script for dynamically creating requests.
-
New
on_metadata
operator for performing arbitrary actions (typically a call to an external script) when metadata packets occur in a stream. -
MP3 encoding, to file or shout.
-
API renamings and simplification.
-
Supports transition, as functions of type (source,source) -> source in all switching operators: schedule, random, fallback.
-
Restart icecast2 outputs on failures.
-
Major changes to the scripting language which is more uniform and flexible, has functions, a helpful (?) type inference, and a simple Ruby-like syntax.
-
Timing constraints and synchronization are managed by Root in a centralized way, no more by the many outputs which need it.
-
Audio decoding is no more based on file extensions, but on the existence of a valid decoder.
-
Added the equeue operators which allows interactive building of playlists, supporting insertion and moving of queued requests -- queue only allows you to push requests and cancel queued requests.
-
A Python-Gtk GUI for controlling operators, or more specifically as a console for creating your live show -- to be updated, still unstable.
-
Alsa input and output.
-
Blank detection, automatically skips on too long blanks, or strip them.
-
Http ogg/vorbis relay, the way to relay live shows.
-
Interactive mixer.
-
The request system was mostly rewritten to really fulfill its specification.
-
The server is no more associated to the queue operator but is now something external, in which all operators can plug commands. This much more logical design lead to many more interactive controls. The syntax of command outputs was also simplified for easier automated processing.
-
Dynamic loading of plugins.
-
Outputs are now operators. It makes it possible to output different streams in a single instance of Liquidsoap, which RadioPi needed. As a consequence we removed the restriction that one source must have at most one father, without any extra burden for the user.
-
Proper initial release.
-
Release for academic demonstration, not functional.