LINUX.ORG.RU

Помогите с Gstreamer + nginx-rtmp

 


0

2

Всем привет!

Стоит такая задача: транслировать с максимальной стабильностью около 100-150 ip-камер с помощью сервера на основе nginx-rtmp и gstreamer.

----------------

Предыстория, или почему gstreamer, а не ffmpeg:

1. Сейчас это все реализовано с помощью связки momentvideo + все тот же nginx-rtmp (у самого момента кривой hls). Но разраб забил на momentvideo и укатил в далекие США, поэтому сборка только 2014-го года со старой и сравнительно неудачной версией gstreamer.

2. ffmpeg по моим наблюдениям гораздо менее стабилен с теми камерами, которые уже стоят.

3. Пайплайны таки нужны для некоторых задач, и я уже к ним привык благодаря моменту.

4. текущая связка работает, но не так стабильно, как хотелось бы (старый gstreamer часто теряет поток, nginx пришлось криво патчить, чтобы он понял кривой размер чанка, указанный разрабом momentvideo и т.д.)

----------------

Сейчас есть мысль сделать что-то по типу:

#!/bin/sh

while true; do

gst-launch-1.0 \
        rtspsrc location=rtsp://my.ip.cam/ protocols=tcp ! rtph264depay \
            ! h264parse \
            ! queue \
            ! flvmux \
! rtmpsink location="rtmp://my.server.ip/live/test"

done

-----------------

Проблемы/вопроса два:

1. как-то страшновато запускать в таком режиме 150 процессов. В моменте сейчас это реализовано потоками, и все работает даже при большом количестве камер. Возможно как-то можно с минимумом программирования на Си++ сделать эти 150 пайплайнов одним процессом? (Я очень давно ничего не писал на нем - последний опыт общения с языками со строгой типизацией был в 2010 году, и это была джава).

2. Если входящий поток падает по той или иной причине, gstreamer довольно долго (до минуты) думает, прежде, чем завершиться (между сообщением PAUSED и READY):

Got EOS from element "pipeline0".
Execution ended after 0:01:20.895625106
Setting pipeline to PAUSED ...
Setting pipeline to READY ...
Setting pipeline to NULL ...

Freeing pipeline ...

Можно ли как-то указать, что нужно завершаться немедленно, если в пайплайне произошел EOS?

Ну и для страховки от зависания:

1. как можно указать, что нужно завершиться, если в течение N секунд поток не получил никаких данных?

2. как можно ограничить время жизни потока (к примеру, 1 часом), чтобы исключить подтекание gstreamer'а (моментвидео, к примеру ну очень хорошо течет при большом количестве потоков)?

Заранее всем признателен за ответы/советы.

PS: поставить flussonic/wowza/nimble и не парится - не предлагать

примерно подобные посты я себе и представлял, когда мне говорили, что momentvideo всех задавит и будет лучшим сервером. Такие же посты я себе представлял, когда мне говорили, что сейчас nginx-rtmp бла-бла.

Сейчас подобное я слышу про srs.

А реальность с такими серверами на C как была, так и осталась:

моментвидео, к примеру ну очень хорошо течет при большом количестве потоков

Ещё я хорошо помню комментарии вида: код на C любой админ пофиксит, а на Erlang/Java/Whateverelse ни за что.

Неужели такая проблема пофиксить опенсорсный momentvideo и обновить до свежего gstreamer?

max_lapshin ★★ ()

Как сказали ранее, чтобы исключить подтекание GStreamer наиболее простой и правильный путь - обновить GStreamer. Этот pipeline в новом будет работать стабильно. А если уж хочется подстраховаться и не хочется программировать - то ничто не мешает по расписанию вырубать и запускать задачу. Объединить все в одну утилиту можно: в туториалах GStreamer есть прекрасные примеры как это сделать без ручной сборки pipeline. Точно также укажете строкой и все заработает. Здесь же в коде сможете по таймеру перезапускать pipeline.

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

Максим, если бы были исходники последней (+- стабильной) версии Момента, то не было бы проблемы пересобрать с новым gstreamer'ом.

Но Дмитрий в конце 13-го года очистил git и все публичные источники сырцов.

ЗЫ: к слову, статусом на 13-й год момент был постабильнее эрли в плане ретрансляции камер с фиговыми каналами. Но соглашусь с вами, Дмитрий на него забил и уехал, а Вы не забили :))

ЗЫ/2: конкретно в моей ситуации был бы ваш Флассоник хотя бы 30-40$/мес за инстанс, для меня лично было бы еще приемлемо (если он действительно сейчас такой безглючный, как это заявлено)... Но 75$/мес - дорого :)

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

Как сказали ранее, чтобы исключить подтекание GStreamer наиболее простой и правильный путь - обновить GStreamer. Этот pipeline в новом будет работать стабильно.

Сейчас тестирую в режиме 24/7 штатный не первой свежести gstreamer 1.2.4 из комплекта убунту 14.04.

Глючный радиоканал к камере он пока обрабатывает хуже, чем штатный у последней версии момента.

В ближайшие время хочу развернуть виртуалку и на ней поднять gstreamer поновее + сравнить его с флассоником.

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

Ну мысль такая: если исчез m3u8 в папке nginx'а, убить процесс pkill'ом по имени потока. Ну и можно для подстраховки 1 раз в 3 часа перезапускать принудительно.

Или имеется в виду что-то иное?

Объединить все в одну утилиту можно: в туториалах GStreamer есть прекрасные примеры как это сделать без ручной сборки pipeline. Точно также укажете строкой и все заработает. Здесь же в коде сможете по таймеру перезапускать pipeline.

А можно ссыль на конкретную страницу мана? (для особо тупых)

ЗЫ: уже начинаю смотреть в сторону соорудить что-то на пайтоне. Все-таки скриптовые языки без строгой типизации убивают мышление 120%.

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

А можно ссыль на конкретную страницу мана? (для особо тупых)

Можно. Этого туториала должно быть достаточно. Здесь как раз идет парсинг строки, аналогичной gst-launch и есть цикл обработки сообщений. В крайнем случае можно посмотреть первые, они достаточно короткие.

В ближайшие время хочу развернуть виртуалку и на ней поднять gstreamer поновее + сравнить его с флассоником.

Правильное решение, поскольку после 1.2.4 было много фиксов по парсерам h264. Самый свежий - 1.12.3. Что используется в качестве транспорта для rtsp? В gstreamer по-дефолту udp. Можете поэкспериментировать с транспортом. Подробнее через команду: gst-inspect-1.0 rtspsrc

Ну мысль такая: если исчез m3u8 в папке nginx'а, убить процесс pkill'ом по имени потока. Ну и можно для подстраховки 1 раз в 3 часа перезапускать принудительно.

Да, это и имелось ввиду.

ЗЫ: уже начинаю смотреть в сторону соорудить что-то на пайтоне.

Питон возможен, но с примерами не подскажу. Принцип мышления будет тот же, что и в туториалах для Си.

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

Что используется в качестве транспорта для rtsp? В gstreamer по-дефолту udp. Можете поэкспериментировать с транспортом.

Принудительно tcp. Т.к. большая часть камер за NAT'ом.

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

Столкнулся с проблемой по теме.

C новым Джистримером (Убунту 16) pipeline из стартпоста не работает с nginx. Видео зависает на первом кадре, хотя gstreamer делает вид, что работает. С GST_DEBUG=4 - ничего подозрительного.

rtspsrc ... ! decodebin ! autovideosink показывает нормальное видео

gst-launch-1.0 -v videotestsrc ! queue ! x264enc ! flvmux ! rtmpsink вполне работает

Такая ситуация с 1.8.3 и 1.10.4. В старом 1.2.4 все нормально стримится.

publish_time_fix off - пробовал. Не помогает.

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

для тех, кто говорит по-русски, у нас не 75$ =)

ну а с momentvideo — да, вполне ожидаемо. Дима с самого начала сконцентрировался на глубоких технических деталях и в итоге и с сиграндом тоже неловко вышло.

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

Да, посмотрел - чуть дешевле, 53$... Но курс рубля сейчас в свободном полете, а курс гривны - в свободном падении :(.

Под историей с Сиграндом имеется в виду проект OpenNVR? Который так же отправился в /dev/null вслед за Димой?

-----------

Собственно о gstreamer споткнулся на следующем (пока экспериментирую на впске):

1. В версии 1.2.4 (убунту 14) - все работает.

2. В версии 1.8.3 (убунту 16) - без каких-либо сообщений об ошибках со стороны обоих: - по rtmp - 1 кадр и вечная буферизация. После перезапуска плеера - снова 1 кадр и вечная буферизация - по hls - первый сегмент появляется и растет в размерах до сотен мегабайт, m3u8 не создается. - народ пытался лечить проблему с помощью h264parse config-interval=2, но у меня это не помогло.

3. Обновить на основе собранных пакетов не получилось. - После 100500-й зависимости я переустановил впску.

4. При попытке собрать из сырцов: https://developer.ridgerun.com/wiki/index.php?title=Setting_a_GStreamer_Alter... - получаем рабочую сборку, но без rtmpsink. Захожу в директорию ext/rtmp - качаю ему librtmp, делаю make - все вроде бы хорошо, но gst-inspect-1.0 все равно не видит rtmpsink.

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

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

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

Не так все просто для людей, которые не занимаются этим на постоянной основе, но уже собрал.

Помогло это: https://gist.github.com/sphaero/02717b0b35501ad94863

Таки при версии gstreamer >= 1.6 получаем вечную буферизацию в nginx.

Старые работают, но не так ровно, как хотелось бы. 1.4.5 периодами вылетает с: (gst-launch-1.0:29465): GStreamer-CRITICAL **: gst_mini_object_unref: assertion 'mini_object->refcount > 0' failed

evgenios ()