Skip to content

Commit

Permalink
Send last metadata when connecting to icecast.
Browse files Browse the repository at this point in the history
Fix last metadata.

Fixes: #4262, #3906
  • Loading branch information
toots committed Dec 14, 2024
1 parent 8eb3049 commit 86f8228
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 4 deletions.
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,15 @@ Changed:
`input.harbord` disabled when either `"artist"` or `"title"`
is also passed. Add a configuration key to disable this mechanism.
(#4235, #2676)
- `output.icecast` now re-sends the last metadata when connecting to the
remote server unless explicitly disabled using the `send_last_metadata_on_connect`
option (#3906)

Fixed:

- Fixed request resolution loop when enabling both `autocue`
and `replaygain` metadata resolvers (#4245, fixed in #4246)
- Fixed source `last_metadata` not being properly updated (#4262)
- Convert all ICY (icecast) metadata from `input.http` to `utf8`.

---
Expand Down
23 changes: 20 additions & 3 deletions src/core/outputs/icecast2.ml
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,12 @@ let proto frame_t =
Some
"Timeout for establishing network connections (disabled is negative)."
);
( "send_last_metadata_on_connect",
Lang.bool_t,
Some (Lang.bool true),
Some
"Send the source's last metadata when connecting to the remote \
icecast server." );
( "timeout",
Lang.float_t,
Some (Lang.float 30.),
Expand Down Expand Up @@ -341,6 +347,9 @@ class output p =
let msg = Printexc.to_string error in
Lang.to_float (Lang.apply on_error [("", Lang.string msg)])
in
let send_last_metadata_on_connect =
e Lang.to_bool "send_last_metadata_on_connect"
in
let data = encoder_data p in
let chunked = Lang.to_bool (List.assoc "chunked" p) in
let protocol =
Expand Down Expand Up @@ -603,20 +612,28 @@ class output p =
try List.assoc "User-Agent" headers
with Not_found -> Printf.sprintf "liquidsoap %s" Configure.version
in
let source =
let handler =
Cry.connection ~host ~port ~user ~password ?genre ?url ?description
~name ~public ~protocol ~mount ~chunked ~audio_info ~user_agent
~content_type:data.format ()
in
List.iter
(fun (x, y) ->
(* User-Agent has already been passed to Cry.. *)
if x <> "User-Agent" then Hashtbl.replace source.Cry.headers x y)
if x <> "User-Agent" then Hashtbl.replace handler.Cry.headers x y)
headers;
try
Cry.connect connection source;
Cry.connect connection handler;
self#log#important "Connection setup was successful.";

(match (Lang.to_source source)#last_metadata with
| Some m when send_last_metadata_on_connect -> (
try
self#insert_metadata
(Frame.Metadata.Export.from_metadata ~cover:false m)
with _ -> ())
| _ -> ());

(* Execute on_connect hook. *)
on_connect ()
with
Expand Down
3 changes: 2 additions & 1 deletion src/core/source.ml
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,8 @@ class virtual operator ?(stack = []) ?clock ?(name = "src") sources =
"generate_frame: got metadata at position %d: calling handlers..." i;
List.iter (fun fn -> fn m) on_metadata)
metadata;
if has_track_mark then self#execute_on_track buf;
if has_track_mark then self#execute_on_track buf
else self#set_last_metadata buf;
self#iter_watchers (fun w ->
w.generate_frame ~start_time ~end_time ~length ~has_track_mark
~metadata);
Expand Down
31 changes: 31 additions & 0 deletions tests/streams/dune.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1022,6 +1022,37 @@
(:run_test ../run_test.exe))
(action (run %{run_test} huge-playlist.liq liquidsoap %{test_liq} huge-playlist.liq)))

(rule
(alias citest)
(package liquidsoap)
(deps
icecast_last_meta.liq
./file1.mp3
./file2.mp3
./file3.mp3
./jingle1.mp3
./jingle2.mp3
./jingle3.mp3
./file1.png
./file2.png
./jingles
./playlist
./huge_playlist
./replaygain_track_gain.mp3
./r128_track_gain.mp3
./replaygain_r128_track_gain.mp3
./replaygain_track_gain.opus
./r128_track_gain.opus
./replaygain_r128_track_gain.opus
./without_replaygain_track_gain.mp3
./crossfade-plot.old.txt
./crossfade-plot.new.txt
../../src/bin/liquidsoap.exe
(package liquidsoap)
(:test_liq ../test.liq)
(:run_test ../run_test.exe))
(action (run %{run_test} icecast_last_meta.liq liquidsoap %{test_liq} icecast_last_meta.liq)))

(rule
(alias citest)
(package liquidsoap)
Expand Down
43 changes: 43 additions & 0 deletions tests/streams/icecast_last_meta.liq
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
port = 6723

s = sine()

s = insert_metadata(s)

insert_metadata = s.insert_metadata

output.dummy(s)

thread.run(
delay=0.1,
{
insert_metadata(
[
(
"title",
"some title"
)
]
)
}
)

thread.run(
delay=0.3, {output.icecast(port=port, mount="metadata_test", %mp3, s)}
)

i = input.harbor(buffer=2., port=port, "metadata_test")

i =
source.on_metadata(
i,
fun (m) ->
if
m["title"] ==
"some title"
then
test.pass()
end
)

output.dummy(fallible=true, i)

0 comments on commit 86f8228

Please sign in to comment.