From 4466c67f7e55adbb1e57caae1f2f625a30392072 Mon Sep 17 00:00:00 2001
From: Loxbie <ole@freirad.at>
Date: Wed, 10 Apr 2024 14:44:06 +0200
Subject: [PATCH] Refactor: improve stream endpoints

---
 src/out_stream.liq | 142 ++++++++++++++-------------------------------
 1 file changed, 44 insertions(+), 98 deletions(-)

diff --git a/src/out_stream.liq b/src/out_stream.liq
index 6cc45d9..2ce9efa 100644
--- a/src/out_stream.liq
+++ b/src/out_stream.liq
@@ -17,50 +17,36 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 # Output streaming settings
-# What a mess...
-# s0_encoding =
-#   get_setting("ogg", "stream_0_encoding", "AURA_ENGINE_STREAM_OUTPUT_ENCODING")
-# s0_bitrate =
-#   int_of_string(
-#     get_setting("192", "stream_0_bitrate", "AURA_ENGINE_STREAM_OUTPUT_BITRATE")
-#   )
-# s0_host = get_setting("", "stream_0_host", "AURA_ENGINE_STREAM_OUTPUT_HOST")
-# s0_port =
-#   int_of_string(
-#     get_setting("0", "stream_0_port", "AURA_ENGINE_STREAM_OUTPUT_PORT")
-#   )
-# s0_user = get_setting("", "stream_0_user", "AURA_ENGINE_STREAM_OUTPUT_USER")
-# s0_pass =
-#   get_setting("", "stream_0_password", "AURA_ENGINE_STREAM_OUTPUT_PASSWORD")
-# s0_mount =
-#   get_setting("", "stream_0_mountpoint", "AURA_ENGINE_STREAM_OUTPUT_MOUNTPOINT")
-# s0_url = get_setting("", "stream_0_url", "AURA_ENGINE_STREAM_OUTPUT_URL")
-# s0_desc =
-#   get_setting(
-#     "", "stream_0_description", "AURA_ENGINE_STREAM_OUTPUT_DESCRIPTION"
-#   )
-# s0_genre = get_setting("", "stream_0_genre", "AURA_ENGINE_STREAM_OUTPUT_GENRE")
-# s0_name = get_setting("", "stream_0_name", "AURA_ENGINE_STREAM_OUTPUT_NAME")
-# s0_channels =
-#   get_setting("", "stream_0_channels", "AURA_ENGINE_STREAM_OUTPUT_CHANNELS")
 
-# FIXME: this should move into the list of streams
-# What is this used for anyway?
-s0_connected = ref("")
-
-# s1_connected = ref('')
-# s2_connected = ref('')
-# s3_connected = ref('')
-# s4_connected = ref('')
-
-# number of streams
+# counter of streams
 stream_count = ref(0)
 
 # list of streams
 stream_list = ref([])
 
+# create a stream with the given stream record
 def create_stream(stream) =
-  let url = string(stream.url)
+  # status of the stream
+  connected = ref("false")
+
+  # on error try to reconnect after 5 seconds. This goes up to 120 seconds.
+  retry_time = ref(5.)
+
+  def on_error(msg) =
+    connected := "false"
+    retry_time := retry_time() < 120. ? retry_time() + 5. : retry_time()
+    log(msg)
+    retry_time()
+  end
+
+  def on_connect() =
+    connected := "true"
+    log(
+      "Successfully connected to stream_#{stream_count()}"
+    )
+  end
+
+  # FIXME: make enc more flexible, read bitrate etc from settings
   enc = ref(%vorbis(stereo = true))
 
   # set icy_metadata accoring to the encoder (enc) to send
@@ -73,24 +59,6 @@ def create_stream(stream) =
     snd_icy_metadata := true
   end
 
-  # register a server function for every stream
-  # TODO: what is this used for?
-  server.register(
-    namespace="out_http_#{stream_count()}",
-    "connected",
-    fun (s) ->
-      begin
-        ignore(s)
-        s0_connected()
-      end
-  )
-
-  # create a list of streams to keep track of the created streams
-  # if
-  #   list.assoc.mem(url, stream_list())
-  # then
-  #   "Stream for url #{url} already exists!"
-  # else
   out_stream =
     output.icecast(
       id="out_http_#{stream_count()}",
@@ -104,55 +72,33 @@ def create_stream(stream) =
       name=stream.name,
       genre=stream.genre,
       user=stream.user,
+      on_error=on_error,
+      on_connect=on_connect,
       send_icy_metadata=snd_icy_metadata(),
       enc(),
       output_source
     )
-  stream_count := stream_count() + 1
 
-  # append the new stream to the list of streams, the key is the url
-  # if we could alter the unit (stream) with all its values we could
-  # save all of this in the stream unit itself
-  stream_list := [...stream_list(), (url, out_stream.shutdown)]
-
-  print(
-    "Stream: #{url}"
+  # register a server function for every stream
+  # this shows the status for each stream
+  server.register(
+    namespace="out_http_#{stream_count()}",
+    "connected",
+    fun (s) ->
+      begin
+        ignore(s)
+        connected()
+      end
   )
-end
+  stream_count := stream_count() + 1
 
-# def create_stream(stream) =
-#   server.register(
-#     namespace="out_http_#{stream_count()}",
-#     "connected",
-#     fun (s) ->
-#       begin
-#         ignore(s)
-#         s0_connected()
-#       end
-#   )
-#   stream_to_icecast(
-#     "out_http_#{stream_count()}",
-#     stream.encoding,
-#     int_of_string(stream.bitrate),
-#     stream.host,
-#     int_of_float(stream.port),
-#     stream.password,
-#     stream.mount,
-#     stream.url,
-#     stream.desc,
-#     stream.genre,
-#     stream.user,
-#     output_source,
-#     "#{stream_count()}",
-#     s0_connected,
-#     stream.name,
-#     stream.channels
-#   )
-#   stream_count := stream_count() + 1
-#   print(
-#     "Registered stream #{stream.url}"
-#   )
-# end
+  # append the new stream to the list of streams, the key is the url if we could
+  # alter the unit (stream) with all its values we could save all of this in the
+  # stream unit itself
+  stream_list := [...stream_list(), (stream.url, out_stream.shutdown)]
+end
 
-# itterate over all stream units (read from the yaml config)
+# iterate over all stream units (read from the yaml config)
+# here we could read the env variables and create an endpoint if the env
+# variables are set. But this would be ugly and bloat the code
 list.iter(create_stream, config.stream)
-- 
GitLab