Covers from metadata in Liquidsoap – Mikulski
Site Overlay

Covers from metadata in Liquidsoap

DISCLAIMER:
I am not a programmer and not a linuxoid, but only a copy-paster-enthusiast who shares what he could figure out. Therefore, it is possible that knowledgeable experts may find some points or formulations incorrect or ridiculous.

The submission of this material assumes that you have a basic level of knowledge of Liquidsoap.
This example is relevant for Liquidsoap version 2.2.1.
Anyway, the following articles and tutorials will help you figure it out:
Creating a 24/7 stream(Liquidsoap)
Creating a 24/7 stream part 2(Liquidsoap)

mp3

Liquidsoap is able to extract cover images from the metadata of mp3 files using the metadata.cover operator. Which, of course, can be displayed via video.add_image. The simplest demonstration of this technique will look like this (an example from here is taken as a basis):

music = mksafe(playlist("/path/to/mp3"))

def extract_cover(m)
file.write(append=false, data="#{metadata.cover(coverart_mime='image/png', m)}", "/path/to/cover.png")
end

music.on_track(extract_cover)

You can make sure that when track is changing, the cover (if there is one) will be exported to the specified file.
There are several problems: video.add_image, for some reason, does not read the path again, even if you use ref and wrap the re-reading in a function:

music = mksafe(playlist("/path/to/mp3"))
background = single("/path/to/.gif")

cover_file = ref("/path/to/cover.png")

def extract_cover(m)
file.write(append=false, data="#{metadata.cover(coverart_mime='image/png', m)}", "/path/to/cover.png")
cover_file.set("/path/to/cover.png")
end

music.on_track(extract_cover)

background = video.add_image(x=0, y=0, width=128, height=128, file=cover_file, background)

I admit that I am doing something wrong, but I have tried different approaches and always had the same result: the image is set only once at the start and does not change anymore.

The second problem is that if a file does not have a cover in metadata (or a file of another format that is not supported by metadata.cover), then this leads to errors in Liquidsoap. Therefore, in this case, it is desirable to have some way to resolve this conflict.

I won’t beat around the bush: a full-fledged ready-made solution is all in the same discussion on Github, from where the example above was taken: https://github.com/savonet/liquidsoap/discussions/3402

Many thanks to the user vitoyucepi for sharing the code!

Don’t be afraid of the volume: in fact, it’s enough just to edit the path to the default image in the line
cover_files = cover_files_manager(default_cover_file="default.png"
configure the video.add_image parameters as you need, and do not forget to link the callback function to the playlist source.
music.on_track(cover_files.extract_from_metadata)
Just expand full_script, read how it works and everything will become clear.

My case

In my case, the above scenario is not suitable, since I use video files in mp4 format for my broadcast. Extracting the cover from mp4 metadata leads to the export of unreadable files.
But there is only one music performer (me :)), and the year of creation was always fixed for the tracks, then this greatly facilitated the task.
The following idea came up: put all the covers in the covers directory and write the path to each of them for video.add_image, according to the year indicated in the metadata.

To my surprise, I quickly managed to build a simple workable function:

videos = mksafe(playlist("path/to/mp4"))

cover_file = ref("/path/to/covers/default.png")

def change_cover (m)
  cover_year = list.assoc(default="none", "year", m)
  if cover_year == '2020' then
  cover_file.set("/path/to/covers/2020.jpg") 
end
if cover_year == '2021' then
  cover_file.set("/path/to/covers/2021.jpg")
end
if cover_year == '2022' then
  cover_file.set("/path/to/covers/2022.jpg") 
end
if cover_year == '2023' then
  cover_file.set("/path/to/covers/2023.jpg")
end
if cover_year == 'none' then
cover_file.set("/path/to/covers/default.png")
end

end

videos.on_metadata(change_cover)

videos = video.add_image(x=0, y=0, width=100, height=100, file=cover_file, videos)

In general, everything is elementary: the function checks the year in the metadata and, in accordance with this, exposes a predefined image.
An important point: for the list.assoc operator, you must specify the default="" argument, otherwise Liquidsoap will crash as soon as a file gets into the queue, which will have an empty “Year” tag in the metadata. For such cases (for jingles in particular), I added a default image that will be displayed every time the “Year” turns out to be empty, which will prevent Liquidsoap crashes.

Offtop

But, of course, it was not without hassle. Since I prescribed only Artist – Title metadata for video files, it was necessary to add the Year column to all available 185 files. On my home PC, I use the mp3tag program to edit tags, but I decided to try editing files using the exiftool utility directly on the server.
I added a year to one file, downloaded it, made sure that the tag is correctly recognized by different players. And quickly, thanks to the auto-completion (the “Tab” key), I made all the necessary edits. I don’t know what I overlooked, but despite the fact that the tag was everywhere (I downloaded files to make sure of it), Liquidsoap didn’t read it. I had to do everything all over again on my home PC using mp3tag and upload files – only then everything worked as expected. Perhaps this information will be useful to someone.

0 comments
Inline Feedbacks
View all comments