LINUX.ORG.RU

Наложение бегущей строки на потоковое видео

 , ,


1

2

Ситуация такая: есть один телеканал, на который по расписанию надо накладывать бегущую строку, которая в течение дня может меняться. Очень не хочется покупать Форвард-ТС для этих целей, но и жить на старой АльфаПро уже невозможно - оно под виндовс, не скриптуется, формат файлов с бегущей строкой закрыт, ничего нельзя изменить.

Идеальным решением были бы SSA-субтитры, но их невозможно изменить, не прерывая захват и трансляцию видео, что для телевещания неприемлемо. Захват видео идёт через тв-тюнер по низкочастотному входу, вывод - MPEG-2 TS через мультикаст.

OBS Studio не умеет субтитры, mpeg2 и мультикасты. Shotcut, основанный на MLT, умеет накладывать HTML5 оверлей, и я надеялся уже сделать проект в нём и зарядить в melt для работы в безголовом режиме, но увы, не получилось - melt html5-оверлей не умеет. Экспериментировал с v4l2loopback, но при наложении двух видео друг на друга они начинают дико мерцать, и это побороть никак не получилось.

Есть ли ещё какие-либо способы? Мне вообще посоветовали выводить видео на экран в фуллскрине через браузер, браузером накладывать бегучку (да и вообще любые объекты) и захватывать видео с экрана, но это костыль просто эпических масштабов. Да и не хотелось бы терять качество видео - оно и так не фонтан.

★★

выводить видео на экран в фуллскрине через браузер, браузером накладывать бегучку (да и вообще любые объекты) и захватывать видео с экрана

Вантузятники-джависты с радмином наперевес 😬

mos ★★☆☆☆ ()

Возможно это то для чего как раз бы пригодился gstreamer. Его конвеерная природа по идее то что надо.

mos ★★☆☆☆ ()
Ответ на: комментарий от mos

Точно, про gstreamer совсем забыл, надо бы потыкать.

Ещё есть параметр reload у ffmpeg-овского drawtext, но поверх него 1) надо городить сложную логику обновления файлов, учитывающую длительность текстов бегущей строки 2) не получается сделать fade in/out для текста.

lizard ★★ ()
Ответ на: комментарий от anonymous

Проблема не в том, как наложить бегущую строку на видео:

ffmpeg -i /dev/video0 -vf "ass=ticker.ass" -b:v 3.2M -minrate:v 3.2M -maxrate:v 3.2M -bufsize:v 2.2M -pix_fmt yuv420p -f mpegts "udp://127.0.0.1:1234?pkt_size=1316&ttl=0"
Такая конструкция вполне работает (пример для веб-камеры, но с платой захвата тоже годится).

Проблема в том, чтобы иметь возможность изменять субтитры на лету. Если бы бегущая строка формировалась заранее, хотя бы на день вперёд, то никаких проблем не было бы - можно было бы сформировать файл субтитров заранее и часа в три ночи перезапустить процесс оцифровки. Но передёргивать канал в прайм-тайм, когда идёт основной поток объявлений, нельзя - буфер не спасает, плата захвата долго инициализируется.

lizard ★★ ()
Ответ на: комментарий от lizard

Наговнякал скрипт на питоне https://bpaste.net/show/1dcde93311ca в качестве концепта.

Запускать примерно так

$ python3 ticker.py \
    | ffmpeg \
        -framerate 60 -i image.jpg \
        -f rawvideo -video_size 1100x60 -pixel_format bgra -framerate 60 -i pipe:0 \
        -filter_complex '[1]unpremultiply=inplace=1[up]; [0][up]overlay=y=670' \
        -c:v yuv4 -f avi pipe:1 \
    | ffplay pipe:0

image.jpg - картинка для теста, 1100x60 - разрешение бегущей строки (задаётся также и в скрипте).

Смысл такой, что скрипт, используя cairo, отрисовывает текст на прозрачном фоне и выдаёт несжатые пикселы в stdout. Из своего stdin ffmpeg читает эти пикселы, интерпретируя согласно указанному формату, демултиплаит их, накладывает на картинку или видео и выдаёт в несжатом формате в пайп, откуда ffplay уже читает результат и выводит на экран.

Имя файла, из которого берётся текст, указано в скрипте. Чтобы поменять текст бегущей строки, нужно поменять текст в файле и отправить процессу скрипта сигнал SIGUSR1 или SIGUSR2

$ pgrep -f ticker
20734
$ kill -USR1 20734
# текст бегущей строки поменялся

Бегущая строка длиной в 15КБ рендерится без тормозов. Хотя вся конструкция отъедает немного CPU при любой длине строки. Пакет python-cairo нужно установить, если ещё не. Чем новее, тем лучше, так как получить пикселы изображения из питона стало возможным не так давно.

Всякие красивые шрифты, переходы и незаметную смену текста уже сами сделаете, если надо :) Пока что либо резкая смена текста (SIGUSR2), либо после окончания прокрутки текущей строки (SIGUSR1, 11-ю строку только надо раскомментировать, а 12-ю удалить).

anonymous ()
Ответ на: комментарий от anonymous

О, спасибо, а то я уже начал сорцы ffmpeg ковырять в надежде прикрутить ему SIGHUP куда-нибудь.

lizard ★★ ()
Ответ на: комментарий от lizard

Можно ещё вот это при желании прикрутить https://github.com/rfw/python-ass

Там в описании есть пример с рендерингом. Тип Image, который возвращает итератор из imgs (imgs = r.render_frame(t, timedelta(0))) имеет атрибут bitmap, который, судя по всему, представляет собой пикселы сгенерированной картинки. Так что PIL не нужен и можно просто отправить несжатую картинку на вход ffmpeg.

anonymous ()
Ответ на: комментарий от anonymous

По-быстрому не захотело работать, сперва cairo не нравился, потом ffmpeg ругался на пайпы/форматы. Пока не разбирался, попробую сначала всё-таки пропатчить ffmpeg, мне это видится более изящным решением. Там, по сути, надо отловить SIGHUP где-нибудь в главном цикле и вызвать init_ass() или init_subtitles().

Но идея понятна - генерировать один из видеопотоков самому, чтобы у ffmpeg был непрерывный поток на входе.

lizard ★★ ()
Ответ на: комментарий от lizard

У меня такие вот версии программ: ffmpeg 3.4.1, python 3.6.4, cairo 1.15.10, python-cairo 1.15.4-1.

anonymous ()
Ответ на: комментарий от anonymous

Traceback (most recent call last): File «ticker.py», line 68, in <module> cc = init(w, h, file_name, speed) File «ticker.py», line 36, in init read_file(cc) File «ticker.py», line 13, in read_file cc.y = -cc.te.y_bearing; AttributeError: 'tuple' object has no attribute 'y_bearing'

prozak ()
Ответ на: комментарий от prozak

поставил из сорсов последний cairo и всё пошло. Теперь не могу понять,как в input воткнуть http поток.

prozak ()
Ответ на: комментарий от prozak

Нужен еще libav помимо ffmpeg

что бы принимать потоковое видео:

python3 ticker.py \ | ffmpeg -rtsp_transport tcp -i «rtsp://ip» \ -f rawvideo -video_size 1280x60 -pixel_format bgra -framerate 60 -i pipe:0 \ -filter_complex '[1]unpremultiply=inplace=1[up]; [0][up]overlay=y=670' \ -c:v yuv4 -f avi pipe:1 \ | ffplay pipe:0

prozak ()

По итогу купили Форвард-ТС (не только ради бегучки, заменили старый, ещё аналоговый монтажный пульт). Увы, но в линуксах и близко нет ничего похожего.

lizard ★★ ()
Ответ на: комментарий от lizard

у нас стоит форворд. 5 штук. когда столкнётесь с расширением и захотите выдавать HD сигнал и прочую кучу титровалок - поймёте,что такое форвард )))) цены адовые.

prozak ()
Ответ на: комментарий от anonymous

Милчлвек,мож ты еще научишь это всё на лету менять источник? ))

Помимо бегушки еще нужно вместо картинки в нужный момент подкидывать видеоролик ( рекламу ). В идеале - по DTMF коду :)

Не знаю,можно ли тут предлагать деньги,но я готов предложить за это даже денег,ибо я на питоне ни бум бум. :)

prozak ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.