From 371dac18b7a7765db837e18ad972a31d1520f25f Mon Sep 17 00:00:00 2001 From: Youenn Piolet Date: Tue, 16 Jul 2024 01:51:12 +0200 Subject: [PATCH] feat(streamer): backport autofallback from transcoder --- example/liquidsoap/mystreamer.liq | 23 ++++------ example/liquidsoap/mystreamersurround.liq | 31 +++++++++---- scripts/streamer/00-live.liq | 8 +++- scripts/streamer/50-inputs.liq | 56 +++++++++++++++++++++++ scripts/streamer/inputs/playlist.liq | 17 +++++-- 5 files changed, 105 insertions(+), 30 deletions(-) create mode 100644 scripts/streamer/50-inputs.liq diff --git a/example/liquidsoap/mystreamer.liq b/example/liquidsoap/mystreamer.liq index aab0f92..27ddef2 100644 --- a/example/liquidsoap/mystreamer.liq +++ b/example/liquidsoap/mystreamer.liq @@ -1,40 +1,35 @@ streamer_name = "mystreamer" -# streamer settings harbor_http_port = 7020 prometheus_server_port = 9021 liquidsoap_log_level = 3 - -# tmp -input_playlist_file = "/audio/lib/#{streamer_name}.m3u" +livesource_state_path = "/state/#{streamer_name}.livesourcestate" input_list = [ { name="voieA", - kind=fun (input_kinds) -> input_kinds.restream, + kind="restream", input="udp://228.0.6.102:1026", - is_autofallback=true, - priority=100 + playlist_file="", + is_autofallback=true }, { name="voieB", - kind=fun (input_kinds) -> input_kinds.restream, + kind="restream", input="./example/liquidsoap/mystreamer-voieB.sdp", input_options="protocol_whitelist='file,udp,rtp'", - is_autofallback=true, - priority=101 + playlist_file="", + is_autofallback=true }, { name="localPlaylist", - kind=fun (input_kinds) -> input_kinds.playlist, + kind="playlist", playlist_file="/audio/lib/#{streamer_name}.m3u", - is_autofallback=true, - priority=102 + is_autofallback=true } ] -# SRT output configuration output_list = [ { diff --git a/example/liquidsoap/mystreamersurround.liq b/example/liquidsoap/mystreamersurround.liq index 3d44c6b..3942f01 100644 --- a/example/liquidsoap/mystreamersurround.liq +++ b/example/liquidsoap/mystreamersurround.liq @@ -1,16 +1,27 @@ -streamer_name = "mystreamer" +streamer_name = "mystreamersurround" -# Radio settings -formats_picker = fun (formats) -> formats.flac.surround harbor_http_port = 7030 prometheus_server_port = 9031 liquidsoap_log_level = 3 +livesource_state_path = "/state/#{streamer_name}.livesourcestate" -# Inputs configuration -input_playlist_file = "/audio/lib/#{streamer_name}.m3u" +input_list = + [ + { + name="localPlaylist", + kind="playlist", + playlist_file="/audio/lib/#{streamer_name}.m3u", + is_autofallback=true + } + ] -# SRT output configuration -srt_host = "liquidsoap-myradiosurround" - -# voieA_caller1 -srt_port = 10010 +output_list = + [ + { + name="transcoder1", + kind="srtcaller", + output_host="liquidsoap-myradiosurround", + output_port=10010, + output_preset=fun (presets) -> presets.flac.surround + } + ] diff --git a/scripts/streamer/00-live.liq b/scripts/streamer/00-live.liq index 6a5a89f..737259f 100755 --- a/scripts/streamer/00-live.liq +++ b/scripts/streamer/00-live.liq @@ -1,9 +1,13 @@ #!/usr/bin/liquidsoap %include "10-settings.liq" -%include "20-prometheus.liq" -%include "inputs/playlist.liq" +# We define the default preferred_live_source (for the switch "live" defined +# later on) as being the first input in the input_list. We need to do that here, +# so we can define update_source_metrics callback in 20-prometheus.liq +preferred_live_source = ref(list.nth(input_list, 0).name) +%include "20-prometheus.liq" +%include "50-inputs.liq" %include "80-outputs.liq" %include "90-http.liq" diff --git a/scripts/streamer/50-inputs.liq b/scripts/streamer/50-inputs.liq new file mode 100644 index 0000000..69825fc --- /dev/null +++ b/scripts/streamer/50-inputs.liq @@ -0,0 +1,56 @@ +# Inputs + +input_sources = [] + +%include "inputs/playlist.liq" + +def is_playing(n) = + fun () -> n == preferred_live_source() +end + +def mk_switch_source(s) = + (is_playing(s.name), s.source) +end + +def mk_fallback_source(result, s) = + if + s.is_autofallback + then + [...result, (s.source : source(audio=pcm))] + else + result + end +end + +# get the livesourcestate on disk if it exist +if + file.exists(livesource_state_path) +then + content = file.contents(livesource_state_path) + + # check that the livesource exist in input list + if + list.exists(fun (s) -> s.name == content, input_sources) + then + preferred_live_source := content + end +end + +real_live_source = ref("") + +live = + switch( + id="switch_live", + track_sensitive=false, + list.map(mk_switch_source, input_sources) + ) + +radio = + fallback( + id="fallback_prod", + track_sensitive=false, + [ + (live : source(audio=pcm)), + ...list.fold(mk_fallback_source, [], input_sources) + ] + ) diff --git a/scripts/streamer/inputs/playlist.liq b/scripts/streamer/inputs/playlist.liq index f557f06..96d318c 100644 --- a/scripts/streamer/inputs/playlist.liq +++ b/scripts/streamer/inputs/playlist.liq @@ -1,4 +1,13 @@ -# Build the playlist -radio = playlist(input_playlist_file) -radio = mksafe(id="playlist", radio) -radio = crossfade(fade_out=3., fade_in=3., duration=5., radio) +# Build inputs of kind playlist + +def mk_playlist_source(s) = + let {name, playlist_file} = s + radio = playlist(playlist_file) + radio = mksafe(id="#{name}", radio) + radio = crossfade(fade_out=3., fade_in=3., duration=5., radio) + radio +end + +input_list_playlists = list.filter(fun (i) -> i.kind == "playlist", input_list) + +list.append(input_sources, list.map(mk_playlist_source, input_list_playlists))