Буфер для оверлеев в Liquidsoap – Mikulski
Наложение сайта

Буфер для оверлеев в Liquidsoap

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

Добавляя все больше изображений и текста на сцену своего 24/7 стрима, в какой-то момент я столкнулся с тем, что Liquidsoap перестал справляться с синхронизацией всех источников, выдавая в логе “We must catchup n seconds”.
Особенно критично это стало проявляться в моменты переключения с лайвстрима (где отсутствуют добавленные через Liquidsoap оверлеи) обратно на плейлист (input.rtmp -> playlist): в некоторых случаях “We must catchup” начинал происходить бесконечно, что приводило к сильным лагам и, как следствие, перезапуску скрипта.
Вполне вероятно, что данная проблема касается случаев, когда в качестве плейлиста используются видеофайлы – где аудио и видео единый источник. Либо в виду особенностей конкретной сборки системы. По крайней мере, когда я пытался вызвать эту ситуацию, где используется зацикленная анимация и mp3-плейлист на другом VPS, то сколько бы слоев текста я не добавлял, ничего подобного не происходило.

Вспомогательный Буфер

Я сразу подумал, что было бы неплохо сгруппировать часть графических элементов и обсчитывать их отдельно. Спустя какое-то время безуспешных попыток построить костыли или вынести группу в отдельный clock, я все-таки решил подойти к вопросу с другой стороны:

  • создать пустой источник – blank()
  • наложить на него все нужные графические элементы – video.add_image() / video.add_text()
  • создать буфер для этого источника – buffer(), чтобы разрядить нагрузку на Liquidsoap
  • наложить этот источник на основной видео-источник через оператор add()

Я не сразу пришел к этой идее, так как не был уверен в том, что blank() создает прозрачный видео-источник, а оператор add корректно сработает при наложении буферного и основного источников. Но, как вы понимаете, все получилось и проблема с “We must catchup” была решена!

В скрипте это выглядит примерно так:

#плейлист с видео:
videos = playlist('/path/to/mp4/')
#"пустой" источник:
overlay = blank()
#графические элементы, крепящиеся к overlay
overlay = video.add_image(..., overlay)
overlay = video.add_rectangle(..., overlay)
overlay = video.add_text(..., overlay)
#назначение буфера
overlay = buffer(max=2., overlay)
#наложение overlay поверх плейлиста с видео
videos = add([videos, overlay])

Задержка

Буфер, в зависимости от его максимального размера, создаст задержку при отображении элементов, равную параметру max, задаваемого в секундах (число с точкой). Минимальное значение, которое я испытывал это 2 секунды. Но, вполне возможно, что его можно сделать еще меньше. Например, 1.5 секунд или 0.75.
Исходя из этого, следует все чувствительные к таймингу элементы накладывать на основной видео-источник. Такие как метаданные (текущий/следующий треки/обложки), отсчет времени и так далее.

videos = playlist('/path/to/mp4/')
videos = video.add_text(..., current_song, videos)
videos = video.add_image(..., cover, videos)

overlay = blank()
overlay = video.add_image(..., overlay)
overlay = video.add_text(..., overlay)
overlay = buffer(max=2., overlay)

videos = add([videos, overlay])
0 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии