Обложки из метаданных в Liquidsoap – Mikulski
Наложение сайта

Обложки из метаданных в Liquidsoap

ДИСКЛЕЙМЕР:
Я не программист и не линуксоид, а лишь энтузиаст-копипастер, который делится тем, в чем смог разобраться. Поэтому, не исключено, что знающие специалисты некоторые моменты или формулировки могут счесть неправильными или нелепыми.

Подача данного материала предполагает, что вы обладаете базовым уровнем знаний Liquidsoap. Версия Liquidsoap в этом примере 2.2.1!
Как бы то ни было, следующие статьи и туториалы помогут вам разобраться:
Создание 24/7 радио-стрима (Liquidsoap)
Создание 24/7 радио-стрима ч.2 (Liquidsoap)

mp3

Liquidsoap умеет извлекать изображения обложек из метаданных mp3-файлов при помощи оператора metadata.cover. Которые, естественно, можно выводить на экран через video.add_image. Самая простая демонстрация этого приема будет выглядеть так (за основу взят пример отсюда):

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)

Можно убедиться, что при смене трека, обложка (если она есть) будет экспортироваться в заданный файл.
Проблем возникает несколько: video.add_image, почему-то, не прочитывает путь заново, даже если использовать ref и обернуть повторное чтение в функцию:

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)

Допускаю, что я делаю что-то неправильно, но я пробовал разные подходы и всегда был одинаковый результат: изображение устанавливается лишь единожды на старте и больше не меняется.

Вторая проблема заключается в том, что если у файла отсутствует обложка в метаданных (или файл другого формата, который не поддерживается metadata.cover), то это приводит к ошибкам в Liquidsoap. Следовательно, на этот случай, желательно иметь какой-то способ, чтобы решать этот конфликт.

Не буду ходить вокруг да около: полноценное готовое решение есть все в той же дискуссии на Github, откуда и был взят пример выше: https://github.com/savonet/liquidsoap/discussions/3402

Огромное спасибо пользователю vitoyucepi за то, что поделился кодом!

Не пугайтесь объема: по сути, там достаточно лишь отредактировать путь к изображению по умолчанию в строчке
cover_files = cover_files_manager(default_cover_file="default.png"
настроить параметры video.add_image так как вам нужно, и не забыть привязать коллбэк функции к источнику-плейлисту
music.on_track(cover_files.extract_from_metadata)
Просто раскройте full_script, почитайте как это работает и все станет ясным.

Мой кейс

В моем случае, выше описанный сценарий не подходит, так как для своей трансляции я использую видеофайлы в формате mp4. Извлечение обложки из mp4-метаданных приводит к экспорту нечитаемых файлов.
Но исполнитель музыки всего лишь один (я:)), а для треков всегда фиксировался год создания/монтажа, то это существенно облегчило задачу.
Появилась следующая идея: все обложки положить в директорию covers и прописывать путь к каждой из них для video.add_image, в соответствии с годом, обозначенным в метаданных.

К своему же удивлению я достаточно быстро сумел соорудить простую работоспособную функцию:

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)

В общем, все элементарно: функция сверяется с годом в метаданных и в соответствии с этим выставляет заранее определенное изображение.
Важный момент: для оператора list.assoc нужно обязательно указать аргумент default="", иначе Liquidsoap вылетит, как только в очередь попадет файл, у которого в метаданных будет пусто в тэге “Год”. Для таких случаев (для джинглов в частности), я добавил изображение по умолчанию, которое будет выставляться каждый раз, когда “Год” окажется пустым, что предотвратит вылеты Liquidsoap.

Оффтоп

Но без мороки, конечно же, не обошлось. Так как для видеофайлов я прописывал метаданные только Artist – Title, то надо было внести графу Year во все имеющиеся 185 файлов. На домашнем ПК для редактирования тэгов я пользуюсь программой mp3tag, но я решил попробовать отредактировать файлы с помощью утилиты exiftool прямо на сервере.
Добавил год к одному файлу, скачал, убедился, что тэг корректно распознается разными плеерами. И быстренько, благодаря авто-вставке (клавиша “Tab”) внес все необходимые правки. Не знаю, что я упустил из виду, но несмотря на то, что тэг везде был проставлен (скачивал файлы, чтобы убедиться в этом), Liquidsoap не считывал его. Пришлось все по новой делать на домашнем ПК с помощью mp3tag и закачивать файлы – только тогда все сработало как и предполагалось. Возможно, кому-то эта инфомация пригодится.

0 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии