savonet / liquidsoap

Liquidsoap is a statically typed scripting general-purpose language with dedicated operators and backend for all thing media, streaming, file generation, automation, HTTP backend and more.
http://liquidsoap.info
GNU General Public License v2.0
1.35k stars 122 forks source link

Metadata decoder function runs twice #3960

Open vitoyucepi opened 3 weeks ago

vitoyucepi commented 3 weeks ago

Describe the bug The external metadata decoder is called twice. For example, autocue analyzes each file twice.

[lang:3] test called
[lang:3] /tmp/test/music/2.mp3 []
[lang:3] test called
[lang:3] /tmp/test/music/2.mp3 [("encoder", "Lavf60.16.100"), ("title", "music_2")]

To Reproduce

  1. ffmpeg -f lavfi -i "sine=frequency=100:duration=3" -c:a libmp3lame -b:a 128k -metadata title=music_1 -y 1.mp3
  2. main.liq

    music_dir = "/tmp/test/"
    
    def test(~metadata, filename)
     log("test called")
     log("#{filename} #{metadata}")
     []
    end
    decoder.metadata.add("test", test)
    
    radio = playlist("/tmp/test/")
    
    output.dummy(radio, fallible=true)
  3. services:
     liquidsoap:
       image: savonet/liquidsoap:v2.2.5
       command:
         - /tmp/test/main.liq
       volumes:
         - ./:/tmp/test

Expected behavior The Metadata decoder function should be called only once.

Version details

Install method source

Common issues

3887, #3874.

https://github.com/savonet/liquidsoap/discussions/3957#discussioncomment-9729079

Moonbase59 commented 3 weeks ago

I wonder if that happens because enable_autocue_metadata() just reads file tags, and when an annotated request hits in, we want the annotated values as well? Just guessing, of course.

We’ve been having problems there, and in AzuraCast we’re now just using the protocol, not enable… anymore.

In

def cue_file(~request_metadata, ~file_metadata, filename) =

I actually get two kinds of metadata, and must consolidate them:

  # combine request & file metadata into one list, where
  # request_metadata (annotations) takes precedence
  metadata = list.fold(
    fun(res, entry) ->
      if list.assoc.mem(fst(entry), res) then
        res
      else
        [...res, entry]
      end,
      request_metadata,
      file_metadata
  )
vitoyucepi commented 3 weeks ago

I used git bisect to find the commit after which the behavior manifested itself. In the 2.2.x branch, it was c11cc5ef3e60fbd8877c2455d03678261b25a50b. In the main branch it was 939eba26a13b35a4edae2db13b6a22cd6bbccac8, but the output is slightly different, but test is called twice.