«Может в следующей версии, как будет время. Это интересная задача сама по себе» – @tictac17.

Ранее в статье "Самый простой (для знающих Linux) и дешевый способ разместить IP-камеру на сайте для небольшой аудитории" я уже делился с сообществом своим видением, как быстро и просто разместить видео с камеры на своем сайте. Минусов у того подхода, к сожалению, было много. Это и запуск исключительно под Linux, и отсутствие полноценной поддержки Safari и Яндекс.Браузера для MacOSX, и необходимость проделать дополнительную работу, чтобы привести скрипт в боевое состояние. Установить Apache, PHP, FFMpeg. Сгенерировать вручную ссылки (немного не актуально – я недавно выложил генератор ссылок для того скрипта). В общем, в новом году хочется чего-то совсем простого, что настраивается в пару кликов и работает почти везде. Плюс в комментариях к статье были справедливые упоминания о технологии HLS. Вот такую программу я и написал, чем с вами сегодня и поделюсь.

Ключевые особенности и преимущества данной программы:

  1. Ориентированность на бесперебойность работы. Если процесс трансляции (FFMpeg) неожиданно завершается, то программа это обнаружит и попытается его перезапустить. Плеер на стороне клиента также периодически проверяет, не остановилось ли видео, и если да – попытается это исправить.

  2. Максимальная экономия трафика, подходит для 3G/4G. Когда нет активных зрителей, все процессы FFMpeg будут остановлены автоматически – т.е. программа не будет забирать видеопоток с камер. Также предусмотрено кэширование захваченных статических снимков, по умолчанию время хранения в кэше равно одной минуте. В случае одновременных запросов снимка с одной камеры с разных клиентских устройств будет запущен только один процесс FFMpeg.

  3. Нетребовательность к «железу». 20-30 камер вполне будут работать на компьютере с 4 ГБ оперативки и средним двухъядерным процессором. Никакого перекодирования видеопотока не происходит.

  4. В отличии от моего предыдущего проекта, эта программа способна транслировать видео большему количеству зрителей. Точное число зависит от ширины исходящего интернет-канала сервера.

  5. Максимально возможная простота. Один мой друг любит говорить, что «простота хуже воровства». Но только не в сфере ИТ! В современном мире мало у кого есть лишнее время, чтобы разобраться с той или иной программой, а особенно, с «полуфабрикатами». То, что предлагаю я вам – полностью готовое решение с минимумом настроек. Просто пропишите RTSP-ссылки к вашим камерам, задайте пару общих параметров и получите веб-ссылки на камеры! Разве что сертификат SSL вам придется получить самостоятельно (была мысль встроить Let’s Encrypt в программу, но не было времени – может это сделает кто-нибудь из вас).

  6. Кроссплатформенность. Благодаря среде .NET Core я смог скомпилировать программу-сервер под две 64-битные платформы: Windows и Linux. Что касается Linux, я ориентировался на Debian и Ubuntu, работу на других дистрибутивах не могу гарантировать. Конфигуратор, к сожалению, написан на обычном .NET Framework, и будет доступен только под Windows. Надеюсь, это не доставит вам заметных неудобств.

Слабые стороны:

  1. Видео воспроизводится с ощутимой задержкой. Это особенность технологии HTTP Live Streaming (HLS). Так, если интервал I-кадров равен четырехкратной частоте кадров, а количество сегментов в плейлисте равно трем, то задержка (расхождение с реальным временем) составит около 12 секунд. Применить технологию Low Latency HLS мне не удалось.

  2. Под Linux в консоль запущенной программы попадают строки от FFMpeg, этот вопрос я не смог решить. Знаю, что можно как-то через xterm сделать, но нет гарантии, что на вашем компьютере он будет присутствовать.

  3. Программой используется FFMpeg со статически слинкованными библиотеками. Это негативно сказывается на расходе оперативной памяти, если камер много (и соответственно, много одновременно работающих процессов FFMpeg). Но вы всегда можете заменить FFMpeg на нужный вам билд со всеми оптимизациями. А пользователи Linux могут заменить файл "ffmpeg-linux64" на символическую ссылку на системный FFMpeg. У меня же в приоритете была надежность запуска, да и времени на такого рода оптимизации нет — этим мой выбор и обусловлен.

Поддерживаемые камеры – практически любые, способные выдавать H.264 поток по протоколу RTSP. Если ваша камера умеет H.265, то вам нужно переключить ее в H.264, так как сервер не осуществляет перекодирование, а большинство браузеров пока «не умеют» новый формат. Надеюсь, это временно, и когда-нибудь можно будет вернуть обратно. Также можно оставить основной поток в H.265, а дополнительный сделать в H.264 и тогда в Конфигураторе указывать ссылку на него. Сохранится и возможность воспроизведения браузерами, и хорошее качество записи на диск (если требуется).

Установка и настройка:

  1. Распаковываем программу в нужное вам место. Программа после запуска должна иметь возможность писать в свою вложенную папку data (да, не самое лучшее решение, я знаю), поэтому проверьте права на запись в нее.

  2. Определитесь, будете ли вы использовать SSL-сертификат. Если да (строго рекомендую), то получаете сертификат на свое доменное имя и устанавливаете:

    a) Для формата PEM: разместите файлы сертификата под именами cert.pem и privkey.pem в подпапке data.

    b) Для формата PFX: разместите сертификат под именем cert.pfx в подпапке data (в случае использования обоих форматов приоритет отдается PEM).

    c) Иные форматы: не поддерживаются, требуется конвертация (например, через программу OpenSSL).

  3. Запускаем Конфигуратор файлом "Configurator.exe". Если сервер не на Windows, то вам придется скопировать Конфигуратор на соответствующий компьютер, там настроить и скопировать конфиг "data/config.xml" на сервер. Также можно расшарить папку с файлами программы по сети и запускать Конфигуратор из нее – этот способ использую я сам.

  4. Добавляем камеры, прописываем RTSP-ссылки. Придумываем секретный общий ключ из латинских букв и цифр, указываем адрес сервера (необязательно в случае «просто посмотреть, протестировать»). Если используется SSL сертификат – включите защищенное соединение галочкой. Если вы используете сертификат формата PFX, то укажите пароль на него.

  5. Копируем себе ссылки на камеры из поля в нижней части окна Конфигуратора.

  6. Запускаем серверную часть файлом RTSP2HLS.exe (Windows) или RTSP2HLS (Linux). Оба варианта являются консольной программой.

  7. Если целью установки программы не было тестирование, то скорее всего вам придется пробросить порты на роутере, чтобы сервер был виден из интернета (по умолчанию используется порт tcp/8000, его лучше изменить в Конфигураторе). А также добавить сервер в автозагрузку. Здесь вам придется действовать самим.

  8. Готово – теперь вы можете смотреть камеры в браузере по тем ссылкам, которые вы скопировали в п.5.

Важное замечание – внесенные в Конфигураторе изменения вступают в силу только после перезапуска программы-сервера. Кстати, сам Конфигуратор требует для своего запуска платформу .NET Framework 4.0 или выше.

В случае, если видео воспроизводится некорректно – прерывается, сбрасывается на начало или сильно расходится с реальным временем, попробуйте следующее:

  • Увеличьте число сегментов в плейлисте в Конфигураторе. Внимание – это увеличит задержку воспроизведения, видео будет отставать от реального времени сильнее.

  • Проверьте настройки своей камеры – интервал ключевого кадра (интервал I-кадра) рекомендуется выставить равным N помноженное на частоту кадров, где N – число от 2 до 6. Если снимаемая сцена в основном статична (т.е. в кадре мало движения), то большие значения N заодно повысят ее качество. Параметр также влияет на задержку видео, плюс увеличивает время захвата снимка.

  • Отключите функцию поддержки перемотки видео (в Конфигураторе).

Также программа-сервер умеет выдавать снимки с видеокамер. Для этого в ссылках, полученных из Конфигуратора, замените слово player на image. Открыв такую ссылку в браузере, вы увидите снимок в формате JPEG, его можно использовать в качестве превью на вашем сайте.

Ну а дальше все зависит только от ваших желаний.

Дистрибутив программы

Исходники программы

Страничка автора (меня)

Комментарии (15)


  1. cololoster
    27.12.2021 23:20
    +1

    а почему не WebRTC? задержки бы не было как минимум.
    вроде не сложно, как минимум на golang с использованием https://github.com/deepch/vdk и https://github.com/pion/webrtc ;)


    1. tictac17 Автор
      28.12.2021 00:06

      Да как-то само собой получилось на HLS, заинтересовал он меня, ну и пошло-поехало :) Возможно сделаю WebRTC в следующей версии


  1. Alexufo
    28.12.2021 02:32

    Самый простой способ это ip камера, комп, obs и ютуб))

    Посмотрите еще мою статью по теме
    habr.com/ru/post/532424

    (была мысль встроить Let’s Encrypt в программу, но не было времени – может это сделает кто-нибудь из вас).

    Вот в этом вся проблема)) Сертификат заставляет пересматривать всю простоту по другому. То есть надо велосипедить))


    1. iliar
      28.12.2021 04:54
      +2

      А что сложного в получении сертификата?


      1. Alexufo
        28.12.2021 04:57

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


        1. tictac17 Автор
          28.12.2021 09:46
          +1

          Можно привязать сертбот к любому поддерживаемому веб-серверу, а полученные сертификаты копировать потом в нужное место. Я так делаю, чтобы получить сертификат на основной сайт на Apache, а после копирую его в cron'e (просто командой cp) на видеосервер и остальное, что висит на том же домене (на разных портах).

          И получение сертификата по проверке через HTTP не единственная опция, сертбот также поддерживает проверку, например, по DNS-записям.

          В конце концов, можно заказать платный сертификат у регистратора домена, если не хочется этим заниматься самостоятельно.


          1. Stam_emg
            28.12.2021 22:27
            +1

            сертбот умеет просто получать серты без интеграции с апачем\нгинксом и тд.

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

            потенциальная проблема - наличие домена. но бесплатный в .tk\.cf взять не проблема.

            о, вспомнил, с недавнего времени можно и на внешний ip сертефикат физлицу получить. у меня это заняло около 2х часов ночью, когда спонтанно этим загорелся.


  1. sirocco
    28.12.2021 08:19
    +1

    А ещё есть проект OpenIPC. Можно купить одну из дешманских камер на Ali, прошить этой прошивкой. После этого камера сможет сразу транслировать в ютуб, а также её поток можно сразу отправлять на веб, он тоже, вроде, в HLS самой камерой отдаётся.


    1. Alexufo
      29.12.2021 01:35

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


    1. PendalFF
      29.12.2021 15:08

      Насколько я знаю чтобы была возможность трансляции на YouTube нужен канал с не менее чем каким-то количеством подписечников и ещё какими-то условиями, нельзя просто взять и начать стримить, так что способ весьма ограниченно полезен для не-видеоблогеров.


  1. sirocco
    28.12.2021 08:37

    Также предусмотрено кэширование захваченных статических снимков, по умолчанию время хранения в кэше равно одной минуте

    Как это выглядит? Кэш в озу или на диске? Это когда камера делает снапшоты с интервалом?

    У меня вот какая проблема, есть Synology Surveillance Station, и всё прекрасно, кроме одного, нельзя прямо сразу вытащить архив видео за последние 10 сек. У меня когда камера обнаруживает движение, скрипт запускает ffmpeg, он делает пятисекундное GIF из потока видео и отправляет в мессенжер. Но что было до наступления события не увидеть. Можно ли ffmpeg'ом постоянно циклически делать снапшоты, или писать видео, чтобы это хранилось в оперативке, а при наступлении события делать из сохранённого короткий кусок видео, с записью до события взятой из кэша?


    1. tictac17 Автор
      28.12.2021 09:22

      Кэш на диске и там интервала нет. При запросе снапшота, сервер смотрит свою папку data/capture. Если он не нашел там картинки, то делает захват с камеры. Если нашел, но судя по дате изменения файла она устарела (т.е. разница с текущим временем была более минуты, по умолчанию), то также сделает захват. Иначе просто отдаст имеющееся, как обычный ресурс. Поиск идет по GUID камеры, им именуются файлы снапшотов.

      Касательно вашей проблемы, циклические снапшоты с помощью ffmpeg можно делать так (в этом примере делается снапшот каждую секунду, принимая fps потока равным 12 — настройте под себя):

      ffmpeg -rtsp_transport tcp -i "rtsp://адрес" -f image2 -vf fps=fps=1/12 img%03d.jpg

      Но храниться это будет не в оперативке, конечно же (как вариант RAM-диск?). Касательно "видео из снапшотов", то можно тем же ffmpeg превратить картинки в GIF, например так:

      ffmpeg -f image2 -i img%03d.jpg out.gif

      Правда эта команда склеит в GIF вообще все картинки из папки, поэтому придется отбирать последние 10 картинок скриптом на bash, и передавать список как аргумент в ffmpeg. Здесь не подскажу, плохо разбираюсь в bash.


  1. longtolik
    28.12.2021 09:04

    "Простота хуже воровства" - это про другое, это когда некий простак, вроде Джека-простака может столько дров наломать, такой ущерб нанести, что вор столько и не натаскает. Хотя....


  1. karzina_vazelina
    28.12.2021 09:23
    +1

    Способ не простой. Проще установить motion, который умеет и писать и детектить движение, и устанавливать триггеры на события, а главное, стримить в mjpg, который является поистине кроссбраузерным, и на любой сайт добавляется с помощью обычного img src:
    image


    1. tictac17 Автор
      28.12.2021 09:29

      А motion умеет уходить "в сон", когда нет зрителей, прерывая захват потока с камеры? А если нужна поддержка аудио (в mjpeg ее нет)? Да и не проще он, строго говоря)