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 linecover_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.