liquidsoap
liquidsoap copied to clipboard
output.harbor does not send ICY metadata
Using Liquidsoap in docker via official savonet/liquidsoap:b9b936d image from docker http://hub.docker.com,
when connecting directly to output.harbor
, ICY metadata is not sent (though metadata seems to be read from files).
Listening to same stream via IceCast2, ICY metadata is received in player.
using:
INFO: Loading Sdl_image, Target = linux
INFO: Loading Sdl_ttf, Target = linux
Liquidsoap 2.2.1+git@b9b936dbb
Copyright (c) 2003-2023 Savonet team
Liquidsoap is open-source software, released under GNU General Public License.
See <http://liquidsoap.info> for more information.
and this test script:
set("log.level", 6)
set("log.stdout", true)
set("log.file", false)
song1 = single("music/song1.mp3")
song2 = single("music/song2.mp3")
ad = single("music/ad_placeholder.mp3")
source = rotate([song1, ad, song2, ad])
# MP3 stream
output.harbor(%mp3(bitrate=192),
port = 8500, mount = "/stream.mp3",
metaint=512, mksafe(source))
# AAC stream
output.harbor(%fdkaac(channels=2, samplerate=44100, bandwidth="auto",
bitrate=128, afterburner=false, aot="mpeg4_aac_lc",
transmux="adts", sbr_mode=false),
port = 8500, mount = "/stream.aac",
metaint=512, mksafe(source))
connecting to stream output.harbor
via:
> mpv --http-header-fields='Icy-MetaData: 1' 'http://127.0.0.1:8500/stream.mp3'
Liquidsoap shows:
2023/08/29 15:14:49 [harbor:4] Method: GET, uri: /stream.mp3, protocol: HTTP/1.1
2023/08/29 15:14:49 [harbor:4] Header: User-Agent, value: libmpv.
2023/08/29 15:14:49 [harbor:4] Header: Accept, value: */*.
2023/08/29 15:14:49 [harbor:4] Header: Range, value: bytes=0-.
2023/08/29 15:14:49 [harbor:4] Header: Connection, value: close.
2023/08/29 15:14:49 [harbor:4] Header: Host, value: 127.0.0.1:8500.
2023/08/29 15:14:49 [harbor:4] Header: Icy-MetaData, value: 1.
2023/08/29 15:14:49 [harbor:4] http/unix GET request on /stream.mp3.
2023/08/29 15:14:49 [harbor:4] Found handler 'GET ^/stream.mp3$' on port 8500.
2023/08/29 15:14:49 [/stream_mp3:4] Serving client 127.0.0.1:41534.
2023/08/29 15:14:49 [/stream_mp3:4] Client 127.0.0.1:41534 connected
2023/08/29 15:15:12 [decoder:2] Decoding "music/song2.mp3" ended: Ffmpeg_decoder.End_of_file.
2023/08/29 15:15:12 [decoder:4] Raised at Ffmpeg_decoder.mk_decoder.(fun).f in file "src/core/decoder/ffmpeg_decoder.ml", line 827, characters 12-29
2023/08/29 15:15:12 [decoder:4] Called from Decoder.mk_decoder.fill in file "src/core/decoder/decoder.ml", line 504, characters 10-31
2023/08/29 15:15:12 [decoder:4]
2023/08/29 15:15:13 [single.2:4] Finished with "music/song2.mp3".
2023/08/29 15:15:13 [single.3:3] Prepared "music/ad_placeholder.mp3" (RID 2).
2023/08/29 15:15:13 [switch:3] Switch to single.3 with forgetful transition.
2023/08/29 15:15:13 [replay_metadata.5:5] Activations changed: static=[], dynamic=[].
2023/08/29 15:15:13 [source:4] Source replay_metadata.5 gets down.
2023/08/29 15:15:13 [single.2:5] Activations changed: static=[], dynamic=[switch.2:mksafe:/stream_mp3:/stream_mp3, switch:on_track:switch.2:mksafe:/stream_mp3:/stream_mp3].
2023/08/29 15:15:13 [replay_metadata.6:5] Assigning source content type for frame type: {audio : pcm(stereo)}
2023/08/29 15:15:13 [replay_metadata.6:5] Content type: {audio=pcm(stereo)}
2023/08/29 15:15:13 [source:4] Source replay_metadata.6 gets up with content type: {audio=pcm(stereo)}.
Same thing on /stream.aac
Using savonet/liquidsoap:v2.2.0
, same behavior as above.
Using savonet/liquidsoap:v2.1.4
, everything works as expected.
It seems to be the exact same behavior as described by bug https://github.com/savonet/liquidsoap/issues/358, which is now marked as closed, so maybe a regression was introduced?
I would like to include additional information regarding this issue.
- Create two files
ffmpeg -f lavfi -i "sine=frequency=100:duration=5" -metadata title=1 1.mp3
ffmpeg -f lavfi -i "sine=frequency=200:duration=5" -metadata title=2 2.mp3
-
main.liq
s1 = single("1.mp3") s2 = single("2.mp3") s = rotate([s1, s2]) output.harbor( %mp3(bitrate=320), mksafe(s), port=8000, mount="/stream", metaint=512, )
Tests:
-
curl https://localhost:8000/stream -H 'Icy-MetaData: 1' -s -v
curl https://localhost:8000/stream -H 'icy-metadata: 1' -s -v
Should printicy-metaint: 512
. Because http headers should be case insensitive. -
curl https://localhost:8000/stream -H 'Icy-MetaData: 1' -s | head -c 700 | grep -aoP 'StreamTitle=.*?;
Should printStreamTitle='1';
orStreamTitle='2';
-
for i in $(seq 1 10);do curl https://localhost:8000/stream -H 'Icy-MetaData: 1' -s | head -c 700 | grep -aoP 'StreamTitle=.*?;';done
Should printStreamTitle='1';
orStreamTitle='2';
10 times.
ok, had to adapt the main.liq a bit since i'm running liquidsoap from a docker container
❯ ls
main.liq music
❯ ls music
1.mp3 2.mp3
❯ cat main.liq
s1 = single("music/1.mp3")
s2 = single("music/2.mp3")
s = rotate([s1, s2])
output.harbor(
%mp3(bitrate=320),
mksafe(s),
port=8000,
mount="/stream",
metaint=512,
)
starting liquidsoap container with version v2.2.0
:
docker run --rm -v $(pwd)/main.liq:/etc/liquidsoap/liquidsoap.liq -v $(pwd)/music:/music --network host --name liq savonet/liquidsoap:v2.2.0 /etc/liquidsoap/liquidsoap.liq
:exclamation: had to use http
instead of https
running curl http://localhost:8000/stream -H 'Icy-MetaData: 1' -s -v
:
❯ curl http://localhost:8000/stream -H 'Icy-MetaData: 1' -s -v
* Trying 127.0.0.1:8000...
* Connected to localhost (127.0.0.1) port 8000 (#0)
> GET /stream HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/7.81.0
> Accept: */*
> Icy-MetaData: 1
>
* Received HTTP/0.9 when not allowed
* Closing connection 0
running curl http://localhost:8000/stream -H 'icy-metaData: 1' -s -v
:
❯ curl http://localhost:8000/stream -H 'icy-metaData: 1' -s -v
* Trying 127.0.0.1:8000...
* Connected to localhost (127.0.0.1) port 8000 (#0)
> GET /stream HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/7.81.0
> Accept: */*
> icy-metaData: 1
>
* Received HTTP/0.9 when not allowed
* Closing connection 0
running curl http://localhost:8000/stream -H 'Icy-MetaData: 1' -s | head -c 700 | grep -aoP 'StreamTitle=.*?;'
does not output anything. same for:
for i in $(seq 1 10);do curl https://localhost:8000/stream -H 'Icy-MetaData: 1' -s | head -c 700 | grep -aoP 'StreamTitle=.*?;';done
Now, running same commands on liquidsoap container with version v2.1.4
:
docker run --rm -v $(pwd)/main.liq:/etc/liquidsoap/liquidsoap.liq -v $(pwd)/music:/music --network host --name liq savonet/liquidsoap:v2.1.4 /etc/liquidsoap/liquidsoap.liq
i get the following:
❯ curl http://localhost:8000/stream -H 'Icy-MetaData: 1' -s -v
* Trying 127.0.0.1:8000...
* Connected to localhost (127.0.0.1) port 8000 (#0)
> GET /stream HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/7.81.0
> Accept: */*
> Icy-MetaData: 1
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-type: audio/mpeg
< icy-metaint: 512
* no chunk, no close, no size. Assume close to signal end
<
* Failure writing output to destination
* Closing connection 0
*
❯ curl http://localhost:8000/stream -H 'icy-metaData: 1' -s -v
* Trying 127.0.0.1:8000...
* Connected to localhost (127.0.0.1) port 8000 (#0)
> GET /stream HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/7.81.0
> Accept: */*
> icy-metaData: 1
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-type: audio/mpeg
* no chunk, no close, no size. Assume close to signal end
<
* Failure writing output to destination
* Closing connection 0
❯ curl http://localhost:8000/stream -H 'Icy-MetaData: 1' -s | head -c 700 | grep -aoP 'StreamTitle=.*?;'
StreamTitle='1';
❯ for i in $(seq 1 10);do curl http://localhost:8000/stream -H 'Icy-MetaData: 1' -s | head -c 700 | grep -aoP 'StreamTitle=.*?;';done
StreamTitle='2';