Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recording live broadcast breaks liquidsoap #3537

Closed
netbladenl opened this issue Nov 15, 2023 · 16 comments
Closed

Recording live broadcast breaks liquidsoap #3537

netbladenl opened this issue Nov 15, 2023 · 16 comments
Assignees

Comments

@netbladenl
Copy link

netbladenl commented Nov 15, 2023

Describe the bug
I'm using the latest rolling release of Azuracast, and when the function to record live broadcasts is on liquidsoap stops working correctly. ID3 information is not being showed correctly. And when the streamer is disconnecting most of the time the autodj of liquidsoap dont play. and if it works you can hear the last seconds of the song being played before the streamer connects instead of directly a new song.

To Reproduce
In azuracast you have to go to edit station profile -> streamers/dj's
Turn on the option "Record Live Broadcasts" connect with butt or anything else that is able to set up a shoutcast/icecast stream and disconnect after a minute. Most likely the autodj doesnt play as it should. Turning this off solves the problem but live streamers wont be recorded.

Expected behavior
When streamer disconnects the autodj should be playing, and when the streamer is connected the ID3 information should be showed instead of the song before playing when the streamer connects

Version details

  • OS: Ubuntu
  • Version 22.04.3

Install method
It's included within the docker distribution of Azuracast

Ticket at github of Azuracast ; AzuraCast/AzuraCast#6727

@netbladenl
Copy link
Author

netbladenl commented Nov 15, 2023

Logs :

2023/11/11 18:02:28 [lang:3] API feedback - Response (200): true
2023/11/11 18:03:12 [lang:3] API auth - Sending POST request to 'http://127.0.0.1:6010/api/internal/1/liquidsoap/auth' with body: { "user": "user", "password": "****" }
2023/11/11 18:03:12 [lang:3] API auth - Response (200): true
2023/11/11 18:03:12 [lang:3] DJ Source connected! Last authenticated DJ: iwan - [("Authorization", "Basic **Password**="), ("Host", "streaming.youradio.nl:8005"), ("User-Agent", "butt 0.1.39"), ("Content-Type", "audio/mpeg"), ("ice-name", "no name"), ("ice-public", "0"), ("ice-audio-info", "ice-bitrate=320;ice-channels=2;ice-samplerate=48000"), ("Expect", "100-continue")]
2023/11/11 18:03:12 [lang:3] API djon - Sending POST request to 'http://127.0.0.1:6010/api/internal/1/liquidsoap/djon' with body: { "user": "iwan" }
2023/11/11 18:03:12 [lang:3] API djon - Response (200): true
2023/11/11 18:03:12 [input_streamer:3] Decoding...
2023/11/11 18:03:42 [input_streamer:2] Error while reading from client: Timed out after waiting for 30.02 sec.
2023/11/11 18:03:42 [lang:3] API djoff - Sending POST request to 'http://127.0.0.1:6010/api/internal/1/liquidsoap/djoff' with body: { "user": "iwan" }
2023/11/11 18:03:42 [lang:3] API djoff - Response (200): true
2023/11/11 18:03:42 [input_streamer:2] Feeding stopped: Avutil.Error(Invalid data found when processing input).
2023/11/11 18:03:42 [lang:3] API djoff - Sending POST request to 'http://127.0.0.1:6010/api/internal/1/liquidsoap/djoff' with body: { "user": "" }
2023/11/11 18:03:42 [lang:3] API djoff - Response (200): true
2023/11/11 18:03:57 [lang:3] API auth - Sending POST request to 'http://127.0.0.1:6010/api/internal/1/liquidsoap/auth' with body: { "user": "iwan", "password": "***" }
2023/11/11 18:03:57 [lang:3] API auth - Response (200): true
2023/11/11 18:03:57 [lang:3] DJ Source connected! Last authenticated DJ: iwan - [("Authorization", "Basic *****="), ("Host", "streaming.youradio.nl:8005"), ("User-Agent", "butt 0.1.39"), ("Content-Type", "audio/mpeg"), ("ice-name", "no name"), ("ice-public", "0"), ("ice-audio-info", "ice-bitrate=320;ice-channels=2;ice-samplerate=48000"), ("Expect", "100-continue")]
2023/11/11 18:03:57 [lang:3] API djon - Sending POST request to 'http://127.0.0.1:6010/api/internal/1/liquidsoap/djon' with body: { "user": "iwan" }
2023/11/11 18:03:57 [lang:3] API djon - Response (200): true
2023/11/11 18:03:57 [input_streamer:3] Decoding...
2023/11/11 18:04:16 [input_streamer:2] Feeding stopped: Avutil.Error(Invalid data found when processing input).
2023/11/11 18:04:16 [lang:3] API djoff - Sending POST request to 'http://127.0.0.1:6010/api/internal/1/liquidsoap/djoff' with body: { "user": "iwan" }
2023/11/11 18:04:16 [lang:3] API djoff - Response (200): true
2023/11/11 18:04:35 [lang:3] API auth - Sending POST request to 'http://127.0.0.1:6010/api/internal/1/liquidsoap/auth' with body: { "user": "", "password": "" }
2023/11/11 18:04:35 [lang:3] API auth - Response (200): true
2023/11/11 18:04:35 [lang:3] DJ Source connected! Last authenticated DJ: iwan - [("Host", "streaming.youradio.nl:8005"), ("icy-name", "No Name"), ("icy-pub", "0"), ("icy-br", "320"), ("content-type", "audio/mpeg")]
2023/11/11 18:04:35 [lang:3] API djon - Sending POST request to 'http://127.0.0.1:6010/api/internal/1/liquidsoap/djon' with body: { "user": "iwan" }
2023/11/11 18:04:35 [lang:3] API djon - Response (200): true
2023/11/11 18:04:35 [input_streamer:3] Decoding...
2023/11/11 18:05:05 [input_streamer:2] Error while reading from client: Timed out after waiting for 30.00 sec.
2023/11/11 18:05:05 [lang:3] API djoff - Sending POST request to 'http://127.0.0.1:6010/api/internal/1/liquidsoap/djoff' with body: { "user": "iwan" }
2023/11/11 18:05:05 [lang:3] API djoff - Response (200): true

Liquidsoap config:

# WARNING! This file is automatically generated by AzuraCast.
# Do not update it directly!


init.daemon.set(false)
init.daemon.pidfile.path.set("/var/azuracast/stations/radio_netblade/config/liquidsoap.pid")

log.stdout.set(true)
log.file.set(false)

settings.server.log.level.set(4)

settings.server.socket.set(true)
settings.server.socket.permissions.set(0o660)
settings.server.socket.path.set("/var/azuracast/stations/radio_netblade/config/liquidsoap.sock")

settings.harbor.bind_addrs.set(["0.0.0.0"])
settings.encoder.metadata.export.set(["artist","title","album","song"])

environment.set("TZ", "Europe/Amsterdam")

autodj_is_loading = ref(true)
ignore(autodj_is_loading)

autodj_ping_attempts = ref(0)
ignore(autodj_ping_attempts)

# Track live-enabled status.
live_enabled = ref(false)
ignore(live_enabled)

# Track live transition for crossfades.
to_live = ref(false)
ignore(to_live)

# Reimplement LS's now-deprecated drop_metadata function.
def drop_metadata(~id=null(), s)
    let {metadata=_, ...tracks} = source.tracks(s)
    source(id=id, tracks)
end

# Transport for HTTPS outputs.
https_transport = http.transport.ssl()
ignore(https_transport)

azuracast_api_url = "http://127.0.0.1:6010/api/internal/4/liquidsoap"
azuracast_api_key = "(PASSWORD)"

def azuracast_api_call(~timeout=2.0, url, payload) =
    full_url = "#{azuracast_api_url}/#{url}"

    log("API #{url} - Sending POST request to '#{full_url}' with body: #{payload}")
    try
        response = http.post(full_url,
            headers=[
                ("Content-Type", "application/json"),
                ("User-Agent", "Liquidsoap AzuraCast"),
                ("X-Liquidsoap-Api-Key", "#{azuracast_api_key}")
            ],
            timeout=timeout,
            data=payload
        )

        log("API #{url} - Response (#{response.status_code}): #{response}")
        "#{response}"
    catch err do
        log("API #{url} - Error: #{error.kind(err)} - #{error.message(err)}")
        "false"
    end
end

station_media_dir = "/var/azuracast/stations/radio_netblade/media"
def azuracast_media_protocol(~rlog=_,~maxtime=_,arg) =
    ["#{station_media_dir}/#{arg}"]
end

protocol.add(
    "media",
    azuracast_media_protocol,
    doc="Pull files from AzuraCast media directory.",
    syntax="media:uri"
)

playlist_default = playlist(id="playlist_default",mime_type="audio/x-mpegurl",mode="randomize",reload_mode="watch","/var/azuracast/stations/radio_netblade/playlists/playlist_default.m3u")
playlist_default = cue_cut(id="cue_playlist_default", playlist_default)

playlist_jingles = playlist(id="playlist_jingles",mime_type="audio/x-mpegurl",mode="randomize",reload_mode="watch","/var/azuracast/stations/radio_netblade/playlists/playlist_jingles.m3u")
playlist_jingles = cue_cut(id="cue_playlist_jingles", playlist_jingles)
playlist_jingles = drop_metadata(playlist_jingles)

# Standard Playlists
radio = random(id="standard_playlists", weights=[3], [playlist_default])

# Once per x Songs Playlists
radio = rotate(weights=[1,3], [playlist_jingles, radio])

# AutoDJ Next Song Script
def autodj_next_song() =
    response = azuracast_api_call(
        "nextsong",
        ""
    )
    if (response == "") or (response == "false") then
        null()
    else
        r = request.create(response)
        if request.resolve(r) then
            r
        else
            null()
       end
    end
end

# Delayed ping for AutoDJ Next Song
def wait_for_next_song(autodj)
    autodj_ping_attempts.set(autodj_ping_attempts() + 1)

    if source.is_ready(autodj) then
        log("AutoDJ is ready!")
        autodj_is_loading.set(false)
        -1.0
    elsif autodj_ping_attempts() > 200 then
        log("AutoDJ could not be initialized within the specified timeout.")
        autodj_is_loading.set(false)
        -1.0
    else
        0.5
    end
end

dynamic = request.dynamic(id="next_song", timeout=20.0, retry_delay=10., autodj_next_song)
dynamic = cue_cut(id="cue_next_song", dynamic)

dynamic_startup = fallback(
    id = "dynamic_startup",
    track_sensitive = false,
    [
        dynamic,
        source.available(
            blank(id = "autodj_startup_blank", duration = 120.),
            predicate.activates({autodj_is_loading()})
        )
    ]
)
radio = fallback(id="autodj_fallback", track_sensitive = true, [dynamic_startup, radio])

ref_dynamic = ref(dynamic);
thread.run.recurrent(delay=0.25, { wait_for_next_song(ref_dynamic()) })

requests = request.queue(id="requests")
requests = cue_cut(id="cue_requests", requests)
radio = fallback(id="requests_fallback", track_sensitive = true, [requests, radio])

interrupting_queue = request.queue(id="interrupting_requests")
interrupting_queue = cue_cut(id="cue_interrupting_requests", interrupting_queue)
radio = fallback(id="interrupting_fallback", track_sensitive = false, [interrupting_queue, radio])

# Skip command (used by web UI)
def add_skip_command(s) =
    def skip(_) =
        source.skip(s)
        "Done!"
    end

    server.register(namespace="radio", usage="skip", description="Skip the current song.", "skip",skip)
end

add_skip_command(radio)

# Apply amplification metadata (if supplied)
radio = amplify(override="liq_amplify", 1., radio)

# Replaygain Metadata
enable_replaygain_metadata()
radio = replaygain(radio)

def live_aware_crossfade(old, new) =
    if to_live() then
        # If going to the live show, play a simple sequence
        sequence([fade.out(old.source),fade.in(new.source)])
    else
        # Otherwise, use the smart transition
        cross.smart(old, new, fade_in=3.00, fade_out=3.00)
    end
end

radio = cross(minimum=0., duration=4.50, live_aware_crossfade, radio)

# DJ Authentication
last_authenticated_dj = ref("")
live_dj = ref("")

def dj_auth(login) =
    auth_info =
        if (login.user == "source" or login.user == "") and (string.match(pattern="(:|,)+", login.password)) then
            auth_string = string.split(separator="(:|,)", login.password)
            {user = list.nth(default="", auth_string, 0),
            password = list.nth(default="", auth_string, 2)}
        else
            {user = login.user, password = login.password}
        end

    response = azuracast_api_call(
        timeout=5.0,
        "auth",
        json.stringify(auth_info)
    )

    if (response == "true") then
        last_authenticated_dj.set(auth_info.user)
        true
    else
        false
    end
end

def live_connected(header) =
    dj = last_authenticated_dj()
    log("DJ Source connected! Last authenticated DJ: #{dj} - #{header}")

    live_enabled.set(true)
    live_dj.set(dj)

    _ = azuracast_api_call(
        timeout=5.0,
        "djon",
        json.stringify({user = dj})
    )
end

def live_disconnected() =
    _ = azuracast_api_call(
        timeout=5.0,
        "djoff",
        json.stringify({user = live_dj()})
    )

    live_enabled.set(false)
    live_dj.set("")
end

# A Pre-DJ source of radio that can be broadcast if needed
radio_without_live = radio
ignore(radio_without_live)

# Live Broadcasting
live = input.harbor("/", id = "input_streamer", port = 9025, auth = dj_auth, icy = true, icy_metadata_charset = "UTF-8", metadata_charset = "UTF-8", on_connect = live_connected, on_disconnect = live_disconnected, buffer = 5.00, max = 10.00)

def insert_missing(m) =
    if m == [] then
        [("title", "Live Broadcast"), ("is_live", "true")]
    else
        [("is_live", "true")]
    end
end
live = metadata.map(insert_missing, live)

radio = fallback(id="live_fallback", track_sensitive=false, replay_metadata=true, [live, radio])

# Skip non-live track when live DJ goes live.
def check_live() =
    if live.is_ready() then
        if not to_live() then
            to_live.set(true)
            radio_without_live.skip()
        end
    else
        to_live.set(false)
    end
end

# Continuously check on live.
radio = source.on_frame(radio, check_live)

# Record Live Broadcasts
recording_base_path = "/var/azuracast/stations/radio_netblade/temp"
recording_extension = "mp3"

output.file(
    %mp3(samplerate=44100, stereo=true, bitrate=128),
    fun () -> begin
        if (live_enabled()) then
            time.string("#{recording_base_path}/#{live_dj()}/stream_%Y%m%d-%H%M%S.#{recording_extension}.tmp")
        else
            ""
        end
    end,
    live,
    fallible=true,
    on_close=fun (tempPath) -> begin
        path = string.replace(pattern=".tmp$", (fun(_) -> ""), tempPath)

        log("Recording stopped: Switching from #{tempPath} to #{path}")

        process.run("mv #{tempPath} #{path}")
        ()
    end
)

# Allow for Telnet-driven insertion of custom metadata.
radio = server.insert_metadata(id="custom_metadata", radio)

radio = ladspa.master_me(
    bypass = false,
    target = -14,
    brickwall_bypass = false,
    brickwall_ceiling = -1.00,
    brickwall_release = 75.00,
    eq_bypass = false,
    eq_highpass_freq = 5.00,
    eq_side_bandwidth = 1.00,
    eq_side_freq = 600.00,
    eq_side_gain = 1.00,
    eq_tilt_gain = 0.00,
    gate_attack = 0.00,
    gate_bypass = true,
    gate_hold = 50.00,
    gate_release = 430.50,
    gate_threshold = -90.00,
    kneecomp_attack = 20.00,
    kneecomp_bypass = false,
    kneecomp_dry_wet = 50,
    kneecomp_ff_fb = 50,
    kneecomp_knee = 6.00,
    kneecomp_link = 60,
    kneecomp_makeup = 0.00,
    kneecomp_release = 340.00,
    kneecomp_strength = 20,
    kneecomp_tar_thresh = -4.00,
    leveler_brake_threshold = -10.00,
    leveler_bypass = false,
    leveler_max = 10.00,
    leveler_max__ = 10.00,
    leveler_speed = 20,
    limiter_attack = 3.00,
    limiter_bypass = false,
    limiter_ff_fb = 50,
    limiter_knee = 3.00,
    limiter_makeup = 0.00,
    limiter_release = 40.00,
    limiter_strength = 80,
    limiter_tar_thresh = 6.00,
    mscomp_bypass = false,
    high_attack = 8.00,
    high_crossover = 8000.00,
    high_knee = 12.00,
    high_link = 30,
    high_release = 30.00,
    high_strength = 30,
    high_tar_thresh = -12.00,
    low_attack = 15.00,
    low_crossover = 60.00,
    low_knee = 12.00,
    low_link = 70,
    low_release = 150.00,
    low_strength = 10,
    low_tar_thresh = -3.00,
    makeup = 1.00,
    dc_blocker = false,
    input_gain = 0.00,
    mono = false,
    phase_l = false,
    phase_r = false,
    stereo_correct = false,
    radio
)

error_file = single(id="error_jingle", "/usr/local/share/icecast/web/error.mp3")

def tag_error_file(m) =
    ignore(m)
    [("is_error_file", "true")]
end
error_file = metadata.map(tag_error_file, error_file)

radio = fallback(id="safe_fallback", track_sensitive = false, [radio, error_file])

# Send metadata changes back to AzuraCast
last_title = ref("")
last_artist = ref("")

def metadata_updated(m) =
    def f() =
        if (m["is_error_file"] != "true") then
            if (m["title"] != last_title() or m["artist"] != last_artist()) then
                last_title.set(m["title"])
                last_artist.set(m["artist"])

                j = json()

                if (m["song_id"] != "") then
                    j.add("song_id", m["song_id"])
                    j.add("media_id", m["media_id"])
                    j.add("playlist_id", m["playlist_id"])
                else
                    j.add("artist", m["artist"])
                    j.add("title", m["title"])
                end

                _ = azuracast_api_call(
                    "feedback",
                    json.stringify(j)
                )
            end
        end
    end

    thread.run(f)
end

radio.on_metadata(metadata_updated)

# Handle "Jingle Mode" tracks by replaying the previous metadata.
last_metadata = ref([])
def handle_jingle_mode(m) =
    if (m["jingle_mode"] == "true") then
        last_metadata()
    else
        last_metadata.set(m)
        m
    end
end

radio = metadata.map(update=false, strip=true, handle_jingle_mode, radio)

# Local Broadcasts
output.icecast(%fdkaac(channels=2, samplerate=44100, bitrate=128, afterburner=false, aot="mpeg4_aac_lc", sbr_mode=true), id="local_1", host = "127.0.0.1", port = 9021, password = "(PASSWORD)", mount = "/radio.aac", name = "Radio NetBlade", description = "netblade radio 10's", genre = "alternative", public = false, encoding = "UTF-8", radio)
output.icecast(%mp3(samplerate=44100, stereo=true, bitrate=320), id="local_2", host = "127.0.0.1", port = 9021, password = "(PASSWORD)", mount = "/radio.mp3", name = "Radio NetBlade", description = "netblade radio 10's", genre = "alternative", public = true, encoding = "UTF-8", radio)

# Remote Relays

@vitoyucepi
Copy link
Collaborator

Hi @netbladenl,
I think the problem is in liquidsoap. I can't fix it, but I can reproduce it. It's not necessary for you to repeat the reproduction steps.

Reproduction

  1. Start liquidsoap with the following script
    s = sine(200.)
    
    l = input.harbor("/test", port=8000)
    
    l = metadata.map(fun(_) -> [], l)
    
    r = fallback([l, s], track_sensitive=false)
    
    output.file(%mp3, {"/tmp/f.mp3"}, l, fallible=true)
    output.dummy(r)
  2. It will start and output [switch:3] Switch to sine.
  3. Stream with the ffmpeg command.
    ffmpeg -hide_banner -re -f lavfi -i "sine=frequency=1000:duration=20" -b:a 128k -c:a mp3 -f mp3 icecast://source:hackme@127.0.0.1:8010/test.
  4. After the stream is finished, liquidsoap will become unresponsive.
    It will also output in a loop.
    [output_file:2] Warning: there may be an infinite sequence of empty tracks!
    

Versions

  • liquidsoap: since 2.2.2

@toots toots self-assigned this Nov 16, 2023
@toots
Copy link
Member

toots commented Nov 16, 2023

Thanks so much for the detailed steps @vitoyucepi. I haven't been able to reproduce, however, either with my local dev env or using savonet/liquidsoap:v2.2.2 on docker. Could you provide more details on the reproduction steps on your end?

Thanks!

@vitoyucepi
Copy link
Collaborator

OK, here's a docker-compose setup.

  1. compose.yaml
    version: "3.8"
    services:
      liquidsoap:
        image: savonet/liquidsoap:v2.2.2
        command:
          - "/tmp/test/main.liq"
        ports:
          - "127.0.0.1:8010:8000"
        logging:
          driver: "json-file"
          options:
            max-size: "1m"
            max-file: "3"
        volumes:
          - ./:/tmp/test
  2. mail.liq
    s = sine(200.)
    
    l = input.harbor("/test", port=8000)
    
    l = metadata.map(fun(_) -> [], l)
    
    r = fallback([l, s], track_sensitive=false)
    
    output.file(%mp3, {"/tmp/f.mp3"}, l, fallible=true)
    output.dummy(r)
  3. Start the compose project with the docker compose up command in the first terminal.
  4. In the second terminal, open docker stats and look for cpu usage.
    top will also work.
  5. In the third terminal, start the stream with ffmpeg -hide_banner -re -f lavfi -i "sine=frequency=1000:duration=30" -b:a 128k -c:a mp3 -f mp3 icecast://source:hackme@127.0.0.1:8010/test.
    I'm not sure if the duration of the stream makes any difference.
  6. In the stats monitor, you'll see the following sequence of events.
    1. While loading liquidsoap, the container will use 100% of the CPU.
      That's okay.

      Logs
      test1-liquidsoap-1  | INFO: Loading Sdl_image, Target = linux
      test1-liquidsoap-1  | INFO: Loading Sdl_ttf, Target = linux
      test1-liquidsoap-1  | 2023/11/17 00:30:14 >>> LOG START
      test1-liquidsoap-1  | 2023/11/17 00:30:09 [ffmpeg.filter.bitstream:3] No valid mode found for filter pgs_frame_merge!
      test1-liquidsoap-1  | 2023/11/17 00:30:09 [main:3] Liquidsoap 2.2.2
      test1-liquidsoap-1  | 2023/11/17 00:30:09 [main:3] Using: alsa=0.3.0 angstrom=0.15.0 ao=0.2.4 asetmap=0.8.1 asn1-combinators=0.2.6 astring=0.8.5 base64=3.5.1 bigarray=[distributed with OCaml] bigarray-compat=1.1.0 bigstringaf=0.9.1 bjack=0.1.6 bos=0.2.1 bytes=[distributed with OCaml] ca-certs=v0.2.3 camlimages.all_formats=4.2.6 camlimages.core=5.0.4 camlimages.exif=5.0.4 camlimages.gif=5.0.4 camlimages.jpeg=5.0.4 camlimages.png=5.0.4 camlimages.tiff=5.0.4 camlimages.xpm=5.0.4 camlp-streams camomile.lib=2.0 cohttp=5.1.0 cohttp-lwt=5.1.0 cohttp-lwt-unix=5.1.0 conduit=6.2.0 conduit-lwt=6.2.0 conduit-lwt-unix=6.2.0 cry=1.0.2 cstruct=6.2.0 ctypes=0.20.2 ctypes.foreign=0.20.2 ctypes.stubs=0.20.2 curl=0.9.2 domain-name=0.4.0 dssi=0.1.5 dtools=0.4.5 dune-build-info=3.8.2 dune-private-libs.dune-section=3.8.2 dune-site=3.8.2 dune-site.private=3.8.2 duppy=0.9.3 eqaf=0.9 eqaf.bigstring=0.9 eqaf.cstruct=0.9 faad=0.5.2 fdkaac=0.3.3 ffmpeg-av=1.1.9 ffmpeg-avcodec=1.1.9 ffmpeg-avdevice=1.1.9 ffmpeg-avfilter=1.1.9 ffmpeg-avutil=1.1.9 ffmpeg-swresample=1.1.9 ffmpeg-swscale=1.1.9 fileutils=0.6.4 flac=0.5.0 flac.decoder=0.5.0 flac.ogg=0.5.0 fmt=0.9.0 fpath=0.7.3 frei0r=0.1.2 gd=1.0a5 gen=1.1 gmap=0.3.0 hkdf=1.0.4 inotify=2.4.1 integers ipaddr=5.5.0 ipaddr-sexp=5.5.0 ipaddr.unix=5.5.0 irc-client irc-client-unix jemalloc ladspa=0.2.2 lame=0.3.7 lastfm=0.3.3 lilv=0.1.0 liquidsoap-lang=2.2.2 liquidsoap-lang.console=2.2.2 liquidsoap_alsa=v2.2.2-1-g93f305b liquidsoap_ao=v2.2.2-1-g93f305b liquidsoap_bjack=v2.2.2-1-g93f305b liquidsoap_builtins=v2.2.2-1-g93f305b liquidsoap_camlimages=v2.2.2-1-g93f305b liquidsoap_core=v2.2.2-1-g93f305b liquidsoap_dssi=v2.2.2-1-g93f305b liquidsoap_faad=v2.2.2-1-g93f305b liquidsoap_fdkaac=v2.2.2-1-g93f305b liquidsoap_ffmpeg=v2.2.2-1-g93f305b liquidsoap_flac=v2.2.2-1-g93f305b liquidsoap_frei0r=v2.2.2-1-g93f305b liquidsoap_gd=v2.2.2-1-g93f305b liquidsoap_irc=v2.2.2-1-g93f305b liquidsoap_jemalloc=v2.2.2-1-g93f305b liquidsoap_ladspa=v2.2.2-1-g93f305b liquidsoap_lame=v2.2.2-1-g93f305b liquidsoap_lastfm=v2.2.2-1-g93f305b liquidsoap_lilv=v2.2.2-1-g93f305b liquidsoap_lo=v2.2.2-1-g93f305b liquidsoap_mad=v2.2.2-1-g93f305b liquidsoap_magic=v2.2.2-1-g93f305b liquidsoap_mem_usage=v2.2.2-1-g93f305b liquidsoap_memtrace=v2.2.2-1-g93f305b liquidsoap_ogg=v2.2.2-1-g93f305b liquidsoap_ogg_flac=v2.2.2-1-g93f305b liquidsoap_optionals=v2.2.2-1-g93f305b liquidsoap_opus=v2.2.2-1-g93f305b liquidsoap_osc=v2.2.2-1-g93f305b liquidsoap_oss=v2.2.2-1-g93f305b liquidsoap_portaudio=v2.2.2-1-g93f305b liquidsoap_posix_time=v2.2.2-1-g93f305b liquidsoap_prometheus=v2.2.2-1-g93f305b liquidsoap_pulseaudio=v2.2.2-1-g93f305b liquidsoap_runtime=v2.2.2-1-g93f305b liquidsoap_samplerate=v2.2.2-1-g93f305b liquidsoap_sdl=v2.2.2-1-g93f305b liquidsoap_shine=v2.2.2-1-g93f305b liquidsoap_soundtouch=v2.2.2-1-g93f305b liquidsoap_speex=v2.2.2-1-g93f305b liquidsoap_srt=v2.2.2-1-g93f305b liquidsoap_ssl=v2.2.2-1-g93f305b liquidsoap_stereotool=v2.2.2-1-g93f305b liquidsoap_taglib=v2.2.2-1-g93f305b liquidsoap_theora=v2.2.2-1-g93f305b liquidsoap_tls=v2.2.2-1-g93f305b liquidsoap_vorbis=v2.2.2-1-g93f305b liquidsoap_xmlplaylist=v2.2.2-1-g93f305b liquidsoap_yaml=v2.2.2-1-g93f305b lo=0.2.0 logs=0.7.0 logs.fmt=0.7.0 logs.lwt=0.7.0 lwt=5.6.1 lwt.unix=5.6.1 macaddr=5.5.0 mad=0.5.3 magic=0.7.3 magic-mime=1.3.0 mem_usage=0.0.4 memtrace=0.2.3 menhirLib=20230608 metadata=0.2.0 mirage-crypto=0.11.1 mirage-crypto-ec=0.11.1 mirage-crypto-pk=0.11.1 mirage-crypto-rng=0.11.1 mirage-crypto-rng.unix=0.11.1 mm=0.8.4 mm.audio=0.8.4 mm.base=0.8.4 mm.image=0.8.4 mm.midi=0.8.4 mm.video=0.8.4 ocplib-endian ocplib-endian.bigstring ogg=0.7.4 ogg.decoder=0.7.4 opus=0.2.3 opus.decoder=0.2.3 osc osc-unix parsexp=v0.16.0 pbkdf pcre=7.5.0 portaudio=0.2.3 posix-base=b516d46 posix-socket=b516d46 posix-socket.constants=b516d46 posix-socket.stubs=b516d46 posix-socket.types=b516d46 posix-time2=b516d46 posix-time2.constants=b516d46 posix-time2.stubs=b516d46 posix-time2.types=b516d46 posix-types=b516d46 posix-types.constants=b516d46 ppx_sexp_conv.runtime-lib=v0.16.0 prometheus=1.2 prometheus-app=1.2 ptime=1.1.0 ptime.clock.os=1.1.0 pulseaudio=0.1.6 re=1.10.4 result=1.5 rresult=0.7.0 samplerate=0.1.7 sedlex=a1362bd seq=[distributed with OCaml 4.07 or above] sexplib=v0.16.0 sexplib0=v0.16.0 shine=0.2.3 soundtouch=0.1.9 speex=0.4.2 speex.decoder=0.4.2 srt=0.3.0 srt.constants=0.3.0 srt.stubs=0.3.0 srt.stubs.locked=0.3.0 srt.types=0.3.0 ssl=0.7.0 stdlib-shims=0.3.0 stereotool=v2.2.2-1-g93f305b str=[distributed with OCaml] stringext=1.6.0 taglib=0.3.10 theora=0.4.1 theora.decoder=0.4.1 threads=[distributed with OCaml] threads.posix=[distributed with OCaml] tls=0.17.0 tsdl=v1.0.0 tsdl-image=0.5 tsdl-ttf=0.5 unix=[distributed with OCaml] unix-errno=52c6ecb unix-errno.errno_bindings=52c6ecb unix-errno.errno_types=52c6ecb unix-errno.errno_types_detected=52c6ecb unix-errno.unix=52c6ecb uri=4.2.0 uri-sexp=4.2.0 uri.services=4.2.0 vorbis=0.8.1 vorbis.decoder=0.8.1 x509=0.16.4 xmlm=1.4.0 xmlplaylist=0.1.5 yaml=3.1.0 yaml.bindings=3.1.0 yaml.bindings.types=3.1.0 yaml.c=3.1.0 yaml.ffi=3.1.0 yaml.types=3.1.0 zarith=1.12
      test1-liquidsoap-1  | 2023/11/17 00:30:09 [clock:3] Using native (high-precision) implementation for latency control
      test1-liquidsoap-1  | 2023/11/17 00:30:14 [main:3] Standard library loaded in 4.25 seconds.
      test1-liquidsoap-1  | 2023/11/17 00:30:14 [frame:3] Using 44100Hz audio, 25Hz video, 44100Hz main.
      test1-liquidsoap-1  | 2023/11/17 00:30:14 [frame:3] Video frame size set to: 1280x720
      test1-liquidsoap-1  | 2023/11/17 00:30:14 [frame:3] Frame size must be a multiple of 1764 ticks = 1764 audio samples = 1 video samples.
      test1-liquidsoap-1  | 2023/11/17 00:30:14 [frame:3] Targeting 'frame.duration': 0.04s = 1764 audio samples = 1764 ticks.
      test1-liquidsoap-1  | 2023/11/17 00:30:14 [frame:3] Frames last 0.04s = 1764 audio samples = 1 video samples = 1764 ticks.
      test1-liquidsoap-1  | 2023/11/17 00:30:14 [sandbox:3] Sandboxing disabled
      test1-liquidsoap-1  | 2023/11/17 00:30:14 [startup:3] DSSI plugins registration: 0.00s
      test1-liquidsoap-1  | 2023/11/17 00:30:14 [startup:3] FFmpeg filters registration: 0.02s
      test1-liquidsoap-1  | 2023/11/17 00:30:14 [startup:3] FFmpeg bitstream filters registration: 0.00s
      test1-liquidsoap-1  | 2023/11/17 00:30:14 [startup:3] Lilv plugins registration: 0.00s
      test1-liquidsoap-1  | 2023/11/17 00:30:14 [startup:3] Frei0r plugin registration: 0.00s
      test1-liquidsoap-1  | 2023/11/17 00:30:14 [startup:3] LADSPA plugins registration: 0.00s
      test1-liquidsoap-1  | 2023/11/17 00:30:14 [startup:3] Typechecking: 4.02s
      test1-liquidsoap-1  | 2023/11/17 00:30:14 [startup:3] Evaluation: 0.01s
      test1-liquidsoap-1  | 2023/11/17 00:30:14 [startup:3] Typechecking: 0.02s
      test1-liquidsoap-1  | 2023/11/17 00:30:14 [startup:3] Evaluation: 0.00s
      test1-liquidsoap-1  | 2023/11/17 00:30:14 [startup:3] Typechecking: 0.00s
      test1-liquidsoap-1  | 2023/11/17 00:30:14 [startup:3] Evaluation: 0.00s
      test1-liquidsoap-1  | 2023/11/17 00:30:14 [startup:3] Loaded /tmp/test/main.liq: 0.00s
      test1-liquidsoap-1  | 2023/11/17 00:30:14 [input.harbor:3] Content type is {audio=pcm(stereo)}.
      test1-liquidsoap-1  | 2023/11/17 00:30:14 [harbor:3] Adding mountpoint '/test' on port 8000
      test1-liquidsoap-1  | 2023/11/17 00:30:14 [output_file:3] Content type is {audio=pcm(stereo)}.
      test1-liquidsoap-1  | 2023/11/17 00:30:14 [metadata_map.2:3] Content type is {audio=pcm(stereo)}.
      test1-liquidsoap-1  | 2023/11/17 00:30:14 [metadata_map:3] Content type is {}.
      test1-liquidsoap-1  | 2023/11/17 00:30:14 [dummy:3] Content type is {audio=pcm(stereo)}.
      test1-liquidsoap-1  | 2023/11/17 00:30:14 [sine:3] Content type is {audio=pcm(stereo)}.
      test1-liquidsoap-1  | 2023/11/17 00:30:14 [clock.main:3] Streaming loop starts in auto-sync mode
      test1-liquidsoap-1  | 2023/11/17 00:30:14 [clock.main:3] Delegating synchronization to CPU clock
      test1-liquidsoap-1  | 2023/11/17 00:30:14 [video.converter:3] Using preferred video converter: ffmpeg.
      test1-liquidsoap-1  | 2023/11/17 00:30:14 [audio.converter:3] Using samplerate converter: libsamplerate.
      test1-liquidsoap-1  | 2023/11/17 00:30:14 [video.text:3] Using sdl implementation
      test1-liquidsoap-1  | 2023/11/17 00:30:14 [switch:3] Switch to sine.
      
    2. After that, the CPU usage will decrease.

    3. Start the stream.

      Logs
      test1-liquidsoap-1  | 2023/11/17 00:30:18 [input.harbor:3] Decoding...
      test1-liquidsoap-1  | 2023/11/17 00:30:30 [switch:3] Switch to metadata_map.2 with transition.
      test1-liquidsoap-1  | 2023/11/17 00:30:30 [replay_metadata:3] Content type is {audio=pcm(stereo)}.
      test1-liquidsoap-1  | 2023/11/17 00:30:38 [input.harbor:2] Feeding stopped: Ffmpeg_decoder.End_of_file.
      
    4. After that, the CPU usage will increase to 100%.

@toots
Copy link
Member

toots commented Nov 17, 2023

I can reproduce now but weirdly enough, on amd64 only. The issue does not seem to pop out on arm64, that's puzzling.

@SkillenUK
Copy link

SkillenUK commented Nov 18, 2023

I'm having this same issue in 2.2.2. I just came on here to see if there was a solution, I may just roll back to 2.2.1 for now.

@toots
Copy link
Member

toots commented Nov 20, 2023

I'll get to this as soon as possible. Thanks for y'all patience.

@toots
Copy link
Member

toots commented Nov 25, 2023

I believe that the changes in this CI build might fix the problem: https://github.com/savonet/liquidsoap/actions/runs/6991394869 Any chance one of y'all could test them?

@vitoyucepi
Copy link
Collaborator

Version 2.2.3+git@b2df6ca has the same problem.

Log
2023/11/26 05:46:57 >>> LOG START
2023/11/26 05:46:53 [main:3] Liquidsoap 2.2.3+git@b2df6caed
2023/11/26 05:46:53 [main:3] Using: alsa=0.3.0 angstrom=0.15.0 ao=0.2.4 asetmap=0.8.1 asn1-combinators=0.2.6 astring=0.8.5 base64=3.5.1 bigarray=[distributed with Ocaml] bigarray-compat=1.1.0 bigstringaf=0.9.1 bjack=0.1.6 bos=0.2.1 bytes=[distributed with OCaml 4.02 or above] ca-certs=v0.2.3 camlimages.all_formats=4.2.6 camlimages.core=5.0.4 camlimages.exif=5.0.4 camlimages.gif=5.0.4 camlimages.jpeg=5.0.4 camlimages.png=5.0.4 camlimages.tiff=5.0.4 camlimages.xpm=5.0.4 camlp-streams camomile.lib=2.0 cohttp=5.3.0 cohttp-lwt=5.3.0 cohttp-lwt-unix=5.3.0 conduit=6.2.0 conduit-lwt=6.2.0 conduit-lwt-unix=6.2.0 cry=1.0.2 cstruct=6.2.0 ctypes=0.21.1 ctypes-foreign=0.21.1 ctypes.stubs=0.21.1 curl=0.9.2 domain-name=0.4.0 dssi=0.1.5 dtools=0.4.5 dune-build-info=3.11.1 dune-private-libs.dune-section=3.11.1 dune-site=3.11.1 dune-site.private=3.11.1 duppy=0.9.3 eqaf=0.9 eqaf.bigstring=0.9 eqaf.cstruct=0.9 faad=0.5.2 fdkaac=0.3.3 ffmpeg-av=1.1.9 ffmpeg-avcodec=1.1.9 ffmpeg-avdevice=1.1.9 ffmpeg-avfilter=1.1.9 ffmpeg-avutil=1.1.9 ffmpeg-swresample=1.1.9 ffmpeg-swscale=1.1.9 fileutils=0.6.4 flac=0.5.1 flac.decoder=0.5.1 flac.ogg=0.5.1 fmt=0.9.0 fpath=0.7.3 frei0r=0.1.2 gd=1.0a5 gen=1.1 gmap=0.3.0 hkdf=1.0.4 inotify=2.4.1 integers ipaddr=5.5.0 ipaddr-sexp=5.5.0 ipaddr.unix=5.5.0 irc-client irc-client-unix jemalloc ladspa=0.2.2 lame=0.3.7 lastfm=0.3.3 lilv=0.1.0 liquidsoap-lang=2.2.3 liquidsoap-lang.console=2.2.3 liquidsoap_alsa=76de133-dirty liquidsoap_ao=76de133-dirty liquidsoap_bjack=76de133-dirty liquidsoap_builtins=76de133-dirty liquidsoap_camlimages=76de133-dirty liquidsoap_core=76de133-dirty liquidsoap_dssi=76de133-dirty liquidsoap_faad=76de133-dirty liquidsoap_fdkaac=76de133-dirty liquidsoap_ffmpeg=76de133-dirty liquidsoap_flac=76de133-dirty liquidsoap_frei0r=76de133-dirty liquidsoap_gd=76de133-dirty liquidsoap_irc=76de133-dirty liquidsoap_jemalloc=76de133-dirty liquidsoap_ladspa=76de133-dirty liquidsoap_lame=76de133-dirty liquidsoap_lastfm=76de133-dirty liquidsoap_lilv=76de133-dirty liquidsoap_lo=76de133-dirty liquidsoap_mad=76de133-dirty liquidsoap_magic=76de133-dirty liquidsoap_mem_usage=76de133-dirty liquidsoap_memtrace=76de133-dirty liquidsoap_ogg=76de133-dirty liquidsoap_ogg_flac=76de133-dirty liquidsoap_optionals=76de133-dirty liquidsoap_opus=76de133-dirty liquidsoap_osc=76de133-dirty liquidsoap_oss=76de133-dirty liquidsoap_portaudio=76de133-dirty liquidsoap_posix_time=76de133-dirty liquidsoap_prometheus=76de133-dirty liquidsoap_pulseaudio=76de133-dirty liquidsoap_runtime=76de133-dirty liquidsoap_samplerate=76de133-dirty liquidsoap_sdl=76de133-dirty liquidsoap_shine=76de133-dirty liquidsoap_soundtouch=76de133-dirty liquidsoap_speex=76de133-dirty liquidsoap_srt=76de133-dirty liquidsoap_ssl=76de133-dirty liquidsoap_stereotool=76de133-dirty liquidsoap_taglib=76de133-dirty liquidsoap_theora=76de133-dirty liquidsoap_tls=76de133-dirty liquidsoap_vorbis=76de133-dirty liquidsoap_xmlplaylist=76de133-dirty liquidsoap_yaml=76de133-dirty lo=0.2.0 logs=0.7.0 logs.fmt=0.7.0 logs.lwt=0.7.0 lwt=5.7.0 lwt.unix=5.7.0 macaddr=5.5.0 mad=0.5.3 magic=0.7.3 magic-mime=1.3.1 mem_usage=0.0.4 memtrace=0.2.3 menhirLib=20230608 metadata=0.2.0 mirage-crypto=0.11.2 mirage-crypto-ec=0.11.2 mirage-crypto-pk=0.11.2 mirage-crypto-rng=0.11.2 mirage-crypto-rng.unix=0.11.2 mm=0.8.4 mm.audio=0.8.4 mm.base=0.8.4 mm.image=0.8.4 mm.midi=0.8.4 mm.video=0.8.4 ocplib-endian ocplib-endian.bigstring ogg=0.7.4 ogg.decoder=0.7.4 opus=0.2.3 opus.decoder=0.2.3 osc osc-unix parsexp=v0.16.0 pbkdf pcre=7.5.0 portaudio=0.2.3 posix-base=5a7f328 posix-socket=5a7f328 posix-socket.constants=5a7f328 posix-socket.stubs=5a7f328 posix-socket.types=5a7f328 posix-time2=5a7f328 posix-time2.constants=5a7f328 posix-time2.stubs=5a7f328 posix-time2.types=5a7f328 posix-types=5a7f328 posix-types.constants=5a7f328 ppx_sexp_conv.runtime-lib=v0.16.0 prometheus=1.2 prometheus-app=1.2 ptime=1.1.0 ptime.clock.os=1.1.0 pulseaudio=0.1.6 re=1.11.0 result=1.5 rresult=0.7.0 samplerate=0.1.7 sedlex=3.2 seq=[distributed with OCaml 4.07 or above] sexplib=v0.16.0 sexplib0=v0.16.0 shine=0.2.3 soundtouch=0.1.9 speex=0.4.2 speex.decoder=0.4.2 srt=0.3.0 srt.constants=0.3.0 srt.stubs=0.3.0 srt.stubs.locked=0.3.0 srt.types=0.3.0 ssl=0.7.0 stdlib-shims=0.3.0 stereotool=76de133-dirty str=[distributed with Ocaml] stringext=1.6.0 taglib=0.3.10 theora=0.4.1 theora.decoder=0.4.1 threads=[distributed with Ocaml] threads.posix=[internal] tls=0.17.1 tsdl=v1.0.0 tsdl-image=0.5 tsdl-ttf=0.6 unix=[distributed with Ocaml] unix-errno=52c6ecb unix-errno.errno_bindings=52c6ecb unix-errno.errno_types=52c6ecb unix-errno.errno_types_detected=52c6ecb unix-errno.unix=52c6ecb uri=4.4.0 uri-sexp=4.4.0 uri.services=4.4.0 vorbis=0.8.1 vorbis.decoder=0.8.1 x509=0.16.5 xmlm=1.4.0 xmlplaylist=0.1.5 yaml=3.2.0 yaml.bindings=3.2.0 yaml.bindings.types=3.2.0 yaml.c=3.2.0 yaml.ffi=3.2.0 yaml.types=3.2.0 zarith=1.13
2023/11/26 05:46:53 [main:3] 
2023/11/26 05:46:53 [main:3] DISCLAIMER: This version of Liquidsoap has been compiled from a snapshot of the
2023/11/26 05:46:53 [main:3] development code. As such, it should not be used in production unless you know
2023/11/26 05:46:53 [main:3] what you are doing!
2023/11/26 05:46:53 [main:3] 
2023/11/26 05:46:53 [main:3] We are, however, very interested in any feedback about our development code and
2023/11/26 05:46:53 [main:3] committed to fix issues as soon as possible.
2023/11/26 05:46:53 [main:3] 
2023/11/26 05:46:53 [main:3] If you are interested in collaborating to the development of Liquidsoap, feel
2023/11/26 05:46:53 [main:3] free to drop us a mail at <savonet-devl@lists.sf.net> or to join the slack chat
2023/11/26 05:46:53 [main:3] at <http://slack.liquidsoap.info>.
2023/11/26 05:46:53 [main:3] 
2023/11/26 05:46:53 [main:3] Please send any bug report or feature request at
2023/11/26 05:46:53 [main:3] <https://github.com/savonet/liquidsoap/issues>.
2023/11/26 05:46:53 [main:3] 
2023/11/26 05:46:53 [main:3] We hope you enjoy this snapshot build of Liquidsoap!
2023/11/26 05:46:53 [main:3] 
2023/11/26 05:46:53 [clock:3] Using native (high-precision) implementation for latency control
2023/11/26 05:46:57 [main:3] Standard library loaded in 3.46 seconds.
2023/11/26 05:46:57 [frame:3] Using 44100Hz audio, 25Hz video, 44100Hz main.
2023/11/26 05:46:57 [frame:3] Video frame size set to: 1280x720
2023/11/26 05:46:57 [frame:3] Frame size must be a multiple of 1764 ticks = 1764 audio samples = 1 video samples.
2023/11/26 05:46:57 [frame:3] Targeting 'frame.duration': 0.04s = 1764 audio samples = 1764 ticks.
2023/11/26 05:46:57 [frame:3] Frames last 0.04s = 1764 audio samples = 1 video samples = 1764 ticks.
2023/11/26 05:46:57 [sandbox:3] Sandboxing disabled
2023/11/26 05:46:57 [startup:3] DSSI plugins registration: 0.00s
2023/11/26 05:46:57 [startup:3] FFmpeg filters registration: 0.02s
2023/11/26 05:46:57 [startup:3] FFmpeg bitstream filters registration: 0.00s
2023/11/26 05:46:57 [startup:3] Lilv plugins registration: 0.00s
2023/11/26 05:46:57 [startup:3] Frei0r plugin registration: 0.00s
2023/11/26 05:46:57 [startup:3] LADSPA plugins registration: 0.00s
2023/11/26 05:46:57 [startup:3] Typechecking: 3.25s
2023/11/26 05:46:57 [startup:3] Evaluation: 0.01s
2023/11/26 05:46:57 [startup:3] Typechecking: 0.03s
2023/11/26 05:46:57 [startup:3] Evaluation: 0.00s
2023/11/26 05:46:57 [startup:3] Typechecking: 0.00s
2023/11/26 05:46:57 [startup:3] Evaluation: 0.00s
2023/11/26 05:46:57 [startup:3] Loaded /tmp/test/main2.liq: 0.00s
2023/11/26 05:46:57 [input.harbor:3] Content type is {audio=pcm(stereo)}.
2023/11/26 05:46:57 [harbor:3] Adding mountpoint '/test' on port 8000
2023/11/26 05:46:57 [output_file:3] Content type is {audio=pcm(stereo)}.
2023/11/26 05:46:57 [metadata_map.2:3] Content type is {audio=pcm(stereo)}.
2023/11/26 05:46:57 [metadata_map:3] Content type is {}.
2023/11/26 05:46:57 [dummy:3] Content type is {audio=pcm(stereo)}.
2023/11/26 05:46:57 [sine:3] Content type is {audio=pcm(stereo)}.
2023/11/26 05:46:57 [clock.main:3] Streaming loop starts in auto-sync mode
2023/11/26 05:46:57 [clock.main:3] Delegating synchronization to CPU clock
2023/11/26 05:46:57 [video.converter:3] Using preferred video converter: ffmpeg.
2023/11/26 05:46:57 [audio.converter:3] Using samplerate converter: libsamplerate.
2023/11/26 05:46:57 [video.text:3] Using sdl implementation
2023/11/26 05:46:57 [switch:3] Switch to sine.
2023/11/26 05:47:35 [input.harbor:3] Decoding...
2023/11/26 05:47:47 [switch:3] Switch to metadata_map.2 with transition.
2023/11/26 05:47:47 [replay_metadata:3] Content type is {audio=pcm(stereo)}.
2023/11/26 05:48:05 [input.harbor:2] Feeding stopped: Ffmpeg_decoder.End_of_file.
2023/11/26 05:48:17 [switch:3] Switch to sine with forgetful transition.
2023/11/26 05:48:17 [output_file:3] Source failed (no more tracks) stopping output...
2023/11/26 05:48:28 [input.harbor:3] Decoding...
2023/11/26 05:48:40 [switch:3] Switch to metadata_map.2 with transition.
2023/11/26 05:48:40 [replay_metadata.2:3] Content type is {audio=pcm(stereo)}.
2023/11/26 05:48:58 [input.harbor:2] Feeding stopped: Ffmpeg_decoder.End_of_file.
2023/11/26 05:50:46 [output_file:2] Warning: there may be an infinite sequence of empty tracks!
2023/11/26 05:50:46 [output_file:2] Warning: there may be an infinite sequence of empty tracks!
2023/11/26 05:50:46 [output_file:2] Warning: there may be an infinite sequence of empty tracks!

@toots
Copy link
Member

toots commented Nov 27, 2023

I was able to test and confirm that the latest commit on the fix-has-ticked-2.2.x branch does fix the issue.

Reproduction was tricky because it relied on two elements:

  • Source sharing, achieved via the two outputs
  • Partial frame fill.

Partial frame fill can depend on timing such as when the harbor gets available. By changing the duration to 20.03 (frame sizes are 0.04 by default), I was able to make the test case reproducible.

@netbladenl
Copy link
Author

netbladenl commented Nov 28, 2023

Thanks for your work, unfortunately the problem still exists with the new version of liquidsoap

2023/11/28 13:09:30 [lang:3] API djon - Response (200): true
2023/11/28 13:09:30 [input_streamer:3] Decoding...
2023/11/28 13:09:39 [live_fallback:3] Switch to metadata_map.4 with transition.
2023/11/28 13:09:39 [metadata_map.7:3] Inserting missing metadata.
2023/11/28 13:10:09 [input_streamer:2] Error while reading from client: Harbor.Make(T).Websocket_closed
2023/11/28 13:10:09 [lang:3] API djoff - Sending POST request to 'http://127.0.0.1:6010/api/internal/4/liquidsoap/djoff' with body: { "user": "iwan" }
[matroska,webm @ 0x7f84e2e17000] File ended prematurely at pos. 198330 (0x306ba)
[matroska,webm @ 0x7f84e2e17000] Seek to desired resync point failed. Seeking to earliest point available instead.
2023/11/28 13:10:09 [lang:3] API djoff - Response (200): true
2023/11/28 13:10:09 [input_streamer:2] Feeding stopped: Ffmpeg_decoder.End_of_file.
2023/11/28 13:10:09 [lang:3] API djoff - Sending POST request to 'http://127.0.0.1:6010/api/internal/4/liquidsoap/djoff' with body: { "user": "" }
2023/11/28 13:10:09 [lang:3] API djoff - Response (200): true

[2023-11-28 13:10:20] WARN source/_source_read Nothing received on /radio.aac for 3 seconds
[2023-11-28 13:10:20] WARN source/_source_read Nothing received on /radio.mp3 for 3 seconds
[2023-11-28 13:10:20] WARN source/_source_read Nothing received on /radio.aac for 3 seconds
[2023-11-28 13:10:20] WARN source/_source_read Nothing received on /radio.mp3 for 3 seconds
[2023-11-28 13:10:20] WARN source/_source_read Nothing received on /radio.aac for 3 seconds
[2023-11-28 13:10:28] WARN source/_source_read Disconnecting /radio.aac due to socket timeout
[2023-11-28 13:10:28] WARN source/_source_read Disconnecting /radio.mp3 due to socket timeout
[2023-11-28 13:11:01] WARN fserve/fserve_client_create req for file "/usr/local/share/icecast/web/radio.mp3" No such file or directory
[2023-11-28 13:12:21] WARN fserve/fserve_client_create req for file "/usr/local/share/icecast/web/radio.mp3" No such file or directory
[2023-11-28 13:12:22] WARN fserve/fserve_client_create req for file "/usr/local/share/icecast/web/radio.mp3" No such file or directory

The autodj dont come back, after the streamer disconnects

@toots
Copy link
Member

toots commented Nov 28, 2023

Sorry to hear. How did you test it? The rolling release guide hasn't completed yet..

@netbladenl
Copy link
Author

commit on the fix-has-ticked-2.2.x branch does fix the issue.

Oh I thought that the patch was already released, my bad. I've asked Buster to use the newest rolling release of liquidsoap with the Azuracast rolling release.
Maybe I'm a bit to fast.

@vitoyucepi
Copy link
Collaborator

vitoyucepi commented Nov 28, 2023

2.2.3+git@4181a8c works fine.

@toots
Copy link
Member

toots commented Nov 28, 2023

The build of rolling-release-v2.2.x including the fix has just finished!

@netbladenl
Copy link
Author

The problem has been resolved, thanks for all of your help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants