Pull to refresh

Cтрим с несколькими камерами из подручных материалов

Reading time6 min
Views40K

Всё началось с того, как при мне с помощью OBS Studio и какой-то программки для анимации обоев рабочего стола сделали из логотипа видеологотип (который еще и под текущую играющую музыку анимировался). В тот момент я понял что OBS Studio может НАМНОГО больше, чем просто стримить игры. После более близкого знакомства с OBS Studio, она претендует на место самой крутой программы, которую я когда-либо встречал.


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



Что?


Идея заключается в том, чтобы найти 2-3 беспроводных оператора, которые ходят по разным площадкам мероприятия, общаются с людьми, снимают движуху, и т.д. (ну, как у серьезных ребят, короче). А кто-то сидит, коммуницирует с ними по рации, и формирует из всего этого (и еще чего-нибудь, например, сдержимого всякого рода окошек/мониторов/проекторов) интересный видеоконтент, который не скучно смотреть.


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


Зачем?


Потому что это позволяет делать очень круто и сильно сместить технологический потолок качества стрима практически задаром.


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


Чем?


  1. Ноут
    1.1. OBS Studio
    1.2. nginx с модулем RTMP
  2. Операторы со своими смартфонами
    2.1. Какая-нибудь приложуха из выдачи по запросу "stream rtmp", например Larix Broadcaster, или (если есть немного лишних денег) Ace Live Streaming или BitStream
  3. Стабильный вайфай, желательно 5GHz
  4. Стабильный аплинк

При наличии еще чего-нибудь, можно сделать хороший звук, хотя бы на стационарных камерах (которые могут быть любыми относительно качественными вэбками).


А при наличии еще одной ЭВМ на линуксе (говорят, даже Raspberry Pi ок для ≤3 потоков), можно немного разгрузить основной комп и его сеть для обработки и отправки стрима.


Как?


Общепризнанный протокол для видеостриминга — RTMP. Попытки юзать что-то еще ведут к диким лагам, это была моя главная ошибка.


Справедливости ради, стоит отметить проприетарную технологию NewTek NDI (спасибо, Alexsey), которая вроде как круче, чем RTMP. Однако, для нашего юз-кейса, использование NDI потребует немало лишних денег.

Оказывается, принять RTMP-стрим и перенаправить его в OBS Studio — проще простого. Надо всего-то скомпилировать nginx с кастомным модулем и написать конфиг. Но об этом позже.


По-хорошему, надо делать как-то так:



То-есть не давать мобилкам Интернет, чтобы они не тратили ресурсы ни на что кроме стрима.
Но ежели хороший вайфай с Интернетом уже есть (а лишней точки доступа на 5GHz нет), то можно не брезговать и юзать существующие соединения. Однако, отправлять конечный стрим всё-таки желательно с другого соединения, или, в крайнем случае, с того же, но через провод.


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


Как поднять RTMP-сервер?


Лучше делать это на линуксе, чтобы не испытывать проблем со всякими MINGW/MSYS. И на отдельном железе (не обязательно мощном). Либо в докере, тогда можно скипнуть этот раздел, ибо докерфайл уже есть. Через WSL тоже можно, но надо будет вручную пробросить TCP-порт 1935 в файрволе.


Вот отличный мэнуал How to set up your own private RTMP server using nginx, и в доке тоже годно написано. Краткий пересказ в вольном стиле:


  1. Ставим зависимости:


    sudo apt install build-essential libpcre3 libpcre3-dev libssl-dev

  2. Качаем последнюю Mainline версию исходников отсюда:


    wget http://nginx.org/download/nginx-1.15.2.tar.gz  # Check for newer versions
    tar xzf nginx-* && cd !$

  3. Качаем последнюю версию RTMP-модуля:


    wget https://github.com/arut/nginx-rtmp-module/archive/master.zip -O rtmp-module.zip
    unzip !$ -d .

  4. Создаём Makefile:


    ./configure --with-http_ssl_module --add-module=./nginx-rtmp-module-master

    Если свалится не дойдя до Configuration summary, исправляем проблемы.
    Эта команда настроит Ваш стримерский nginx жить в /usr/local/nginx/ и запускаться по команде sudo /usr/local/nginx/sbin/nginx. Таким образом nginx из репозитория ничего не почувствует. Это можно поменять, изучив ./configure --help.


  5. Компилируем:


    make -j4

  6. Устанавливаем:


    echo "nginx with RTMP module" > description-pak
    sudo checkinstall --pkgname nginx-rtmp --provides nginx --nodoc --deldesc -y
    sudo mkdir /usr/local/nginx/logs/  # Doesn't start without it

    В принципе через make install в данном случае безопасно, но всё-таки не надо так.


  7. Проверяем


    $ /usr/local/nginx/sbin/nginx -v
    nginx version: nginx/1.15.2

  8. Настраиваем


    sudo vim /usr/local/nginx/conf/nginx.conf

    В конец добавляем конфиг RTMP-сервера:


    rtmp {
        server {
            listen 1935;
            application live {
                live on;
                record off;
            }
        }
    }

    При желании, можно настроить HTTP-сервер на отображение статистики.
    В доке описано что еще можно настроить, там действительно очень много всего. Если Вы знаете как сделать лучше, буду рад добавить раздел про конфигурацию сервера с материалом из комментариев.


  9. Делаем удобно


    alias rtmp-start="sudo /usr/local/nginx/sbin/nginx"
    alias rtmp-stop="sudo /usr/local/nginx/sbin/nginx -s stop"
    alias rtmp-status="cat /usr/local/nginx/logs/nginx.pid"


Что делать с RTMP-сервером?


  1. Отправить на него стрим с мобильной приложухи по адресу rtmp://[ваш локальный IP]:1935/live/habr где live — это имя RTMP-приложения в конфиге nginx, а habr — это Stream Key, который надо менять для разных камер.


  2. Если Вы настроили показ статистики (и не забыли поменять путь к файлу stat.xsl), проверить что стрим пришёл (по адресу http://localhost:8080/stat).


  3. Подключить ко всем стримам OBS Studio.




  4. PROFIT!!!



Очевидно, что сервер может быть не только локальным, но и доступным из внешки, что позволит делать всё то же самое, но не через вайфай, а через Интернет. Можно сделать свой аналог инстаграмовских групповых стримов, ну и вообще, безграничные возможности ))


Всё?


Есть еще пара вещей, которые я познал на ошибках и хотел бы поделиться:


  1. Можно и нужно менять целевой битрэйт конечного стрима по ходу трансляции, и подстраиваться под возможности соединения. Restream, например, рисует крутые графики, по которым понятно на сколько надо понижать. Есть Pull Request на автоподбор битрэйта, но он заглох ((
  2. Существует такой параметр Keyframe Interval, и он должен быть больше секунды (это надо вручную задавать в Advanced-версии настроек Output). Restream об этом рассказывает только после окончания стрима, UX на высоте! ))
  3. Есть еще один крайне полезный Pull Request, в котором я поучаствовал, и за который активно топлю, но он тоже выглядит заглохшим, хотя мэйнтейнер про него недавно вспомнил и переосмыслил. Лайкните, плиз, если Вам тоже кажется, что отсутствие кнопки Monitor на аудио-каналах — это ужасно.

Вот теперь точно всё, спасибо за внимание ^_^


P.S.


Для тех кто попытается всё-таки сбилдить nginx для вездесущей венды, вот грабли по которым я прошелся, тот еще квест оказался, я не зря этого процесса так опасался:


  • Необходимо брать исходники ИМЕННО из Mercurial (хорошо что там есть кнопка "скачать zip"), в архивах с сайта нет папки src\os\win32. Если у Вас исходники с сайта, будет ошибка don't know how to make 'src/os/win32/ngx_win32_config.h'.
  • Нужен древний MinGW отсюда а не чуть менее древний MSYS2.
  • При установке mingw-developer-toolkit нужно снять чекбокс с Perl. Perl должен быть виндовым.
  • Вот этот ответ хорошо помог.
  • При компиляции используется rc.exe из %ProgramFiles(x86)%\Windows Kits\10\bin\10.0.16299.0\x64, надо эту папку вручную в PATH добавить
  • Надо убрать флаг -WX из CFLAGS в Makefile, чтобы ворнинги не прерывали компиляцию, там в 1.15.3 есть ворнинги...

Итого, у меня получилось как-то так:


#cmd: "%ProgramFiles(x86)%\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"
#cmd: set PATH=%PATH%;%ProgramFiles(x86)%\Windows Kits\10\bin\10.0.16299.0\x64
#cmd: C:\MinGW\msys\1.0\msys.bat
#bash: cd nginx-1.15.3

./auto/configure \
    --with-cc=cl \
    --with-debug \
    --prefix= \
    --conf-path=conf/nginx.conf \
    --pid-path=logs/nginx.pid \
    --http-log-path=logs/access.log \
    --error-log-path=logs/error.log \
    --sbin-path=nginx.exe \
    --http-client-body-temp-path=temp/client_body_temp \
    --http-proxy-temp-path=temp/proxy_temp \
    --http-fastcgi-temp-path=temp/fastcgi_temp \
    --http-scgi-temp-path=temp/scgi_temp \
    --http-uwsgi-temp-path=temp/uwsgi_temp \
    --with-cc-opt=-DFD_SETSIZE=1024 \
    --with-pcre=objs/lib/pcre-8.42 \
    --with-zlib=objs/lib/zlib-1.2.11 \
    --with-openssl=objs/lib/openssl-1.1.1 \
    --with-openssl-opt=no-asm \
    --with-select_module \
    --with-http_ssl_module \
    --add-module=nginx-rtmp-module-master

nmake

Tags:
Hubs:
+6
Comments31

Articles

Change theme settings