- NGINX: Установка rtmp модуля для организации потокового вещания видео на сайте
- Подготовка системы к установке компонентов
- Установка nginx
- Сборка nginx из исходников с модулем nginx-rtmp-module
- Возможные ошибки в процессе установки и компиляции
- Nginx rtmp module для windows
- Онлайн вещание через Nginx-RTMP: несколько готовых рецептов
- Коротко об RTMP
- Публикация видеозаписи
- Онлайн-трансляция
- Веб-камера
- Аналоговая камера
- Захват экрана
- Ретрансляция
- Тюнинг, решение проблем
- Плеер на сайте
- Что дальше?
- Запускаем свой RTMP сервер для стриминга
- Структура
- Установка
- Заключение
- На правах рекламы
- Видео вещание с OvenMediaEngine, до свидания nginx rtmp module
- Медиасервер OvenMediaEngine.
- Установка. Быстрый старт
- Подписывание ссылок
- Кодировщик
- Еще немного о корейской морковке
- Пожелания
NGINX: Установка rtmp модуля для организации потокового вещания видео на сайте
В этой заметке пойдет речь о том, как настроить nginx-rtmp-module на сервере, чтобы в итоге использовать его для того, чтобы организовать вещание потокового видео на любом ресурсе или сайте.
В процессе установки я натыкался на различные подводные камни, поэтому попробую все нюансы описать детально.
Вводные данные: VDS на Ubuntu 16.04 LTS (на 18.04 тоже работает)
Подготовка системы к установке компонентов
Для начала обновим систему и возможные модули:
После этого, можно проверить, установлен ли у вас nginx (на некоторых VDS он уже предустановлен) командой
Установка nginx
Если же после этого вы увидели информацию о версии, то идем дальше, иначе устанавливаем его со всемы дополнительными пакетами:
Командой nginx -v проверяем текущую версию nginx и запонимаем ее. У меня это версия 1.10.3.
Сборка nginx из исходников с модулем nginx-rtmp-module
Далее будем собирать nginx из исходников с модулем nginx-rtmp-module. Скачиваем nginx необходимой версии
Теперь распакуем оба архива:
Отлично! Можно приступать к сборку nginx из исходников. Переходим в папку с nginx 1.10.3 и выполняем следующее:
Только что мы запросиили установочную конфигурацию nginx, который будем компилировать. Вывод может быть примерно такой:
Далее нам нужно в конец строки добавить путь до нашего nginx-rtmp-module:
Итог (нужно убрать переносы, чтобы была строка, либо добавить обратный слеш как символ переноса, я просто отформатировал для наглядности). Запускаем ./connfigure
Возможные ошибки в процессе установки и компиляции
Вот как раз на этом этапе может возникнуть ошибка потипу:
Чтобы это исправить, достаточно убрать из параметра —with-cc-opt опцию -Wdate-time. Однако, правильнее всего быдет почистить скомпилированное:
Затем заново запустить ./configure, make (должно скомпилироваться без ошибок) и make install.
Ну и на последок, если не завелось — скопируйте это
Nginx rtmp module для windows
NGINX-based Media Streaming Server
Donation page (Paypal etc)
RTMP/HLS/MPEG-DASH live streaming
RTMP Video on demand FLV/MP4, playing from local filesystem or HTTP
Stream relay support for distributed streaming: push & pull models
Recording streams in multiple FLVs
Online transcoding with FFmpeg
HTTP callbacks (publish/play/record/update etc)
Running external programs on certain events (exec)
HTTP control module for recording audio/video and dropping clients
Advanced buffering techniques to keep memory allocations at a minimum level for faster streaming and low memory footprint
Proved to work with Wirecast, FMS, Wowza, JWPlayer, FlowPlayer, StrobeMediaPlayback, ffmpeg, avconv, rtmpdump, flvstreamer and many more
Statistics in XML/XSL in machine- & human- readable form
cd to NGINX source directory & run this:
Several versions of nginx (1.3.14 — 1.5.0) require http_ssl_module to be added as well:
For building debug version of nginx add —with-debug
Windows support is limited. These features are not supported
RTMP URL format
app — should match one of application <> blocks in config
name — interpreted by each application can be empty
Multi-worker live streaming
Module supports multi-worker live streaming through automatic stream pushing to nginx workers. This option is toggled with rtmp_auto_push directive.
Онлайн вещание через Nginx-RTMP: несколько готовых рецептов
Недавно я наткнулся на топик «Сервер онлайн-вещаний на базе nginx» о замечательном модуле Романа Арутюняна (@rarutyunyan) для nginx: nginx-rtmp-module. Модуль очень прост в настройке и позволяет на основе nginx создать сервер публикации видеозаписей и живого вещания.
Про сам модуль можно прочитать на его странице на GitHub, я же хочу привести несколько простых примеров использования. Надеюсь, топик поможет новичкам в видеоделах (таким как я).
Коротко об RTMP
RTMP (Real Time Messaging Protocol) — проприетарный протокол вещания от Adobe. В качестве транспорта по умолчанию используется TCP (порт 1935). Также можно инкапсулировать RTMP в HTTP (RTMPT). Клиент RTMP — это в первую очередь Adobe Flash Player.
Кодек видео — H.264, кодек аудио AAC, nellymoser или MP3, контейнеры MP4 или FLV.
Публикация видеозаписи
Иначе говоря, видео по запросу (VOD). Просто добавьте в nginx.conf в секцию rtmp < server <… >>.
(Прим.: конечно, секцию не обязательно называть vod)
Теперь можно положить в папку /var/videos видеофайл в правильном формате и «скормить» плееру источник, например rtmp://server/vod/file.flv. Насколько я понял, MP4 нативно поддерживает перемотку видео, а FLV придется индексировать отдельно.
Все приведенные далее примеры будут уже про «живую» трансляцию с помощью ffmpeg под Windows. Впрочем, эта информация будет полезна и для пользователей Linux.
Онлайн-трансляция
Мы можем отправить поток видео и аудио на сервер используя все тот же протокол RTMP для публикации. А наши клиенты смогут трансляцию смотреть. Для этого на сервере надо добавить секцию:
Рекомендую сразу закрыть доступ на публикацию всем, кроме доверенных IP, как показано в примере.
На машине, с которой мы будем вещать, для начала надо получить список устройств DirectShow. Пуск — Выполнить — cmd, переходим в папку ffmpeg/bin и запускаем:
Если в названии вашего источника есть русские буквы, то они могут отобразиться кракозябрами. ТруЪ админы заюзают iconv, а простые парни вроде меня раскодируют бяку на сайте Лебедева. FFmpeg’у нужно скормить читабельную надпись.
Теперь, зная имя видео и аудио источника, можно захватить его при помощи ffmpeg и отправить на сервер.
Веб-камера
Как минимум нужно указать источник видео, кодек и сервер:
Вместо «Webcam C170» нужно подставить название вашей камеры из списка.
Ключ -an говорит о том, что мы не передаем аудио поток. Если аудио поток нужен, то строка запуска будет выглядеть примерно так:
Здесь мы использует кодек libfaac, частота дискретизации 44100, 2 канала (стерео). Можно вместо AAC использовать MP3 (кодек libmp3lame).
Аналоговая камера
Если у вашей камеры аналоговый выход, то ее можно подключить к компьютеру с помощью устройства захвата. Я использую дешевую PAL камеру и USB плату захвата с Dealextreme.
Захват экрана
Тут есть два варианта: установить FFSplit или использовать screen-capture-recorder с FFmpeg.
FFSplit использовать проще, т.к. у него есть удобный GUI, но он не работает под XP/2003.
Если вы решили выбрать второй способ, то строка запуска FFmpeg будет выглядеть примерно так:
Аудио-поток можно захватить с virtual-audio-capturer.
Пример захвата экрана в приложении
Ретрансляция
Естественно, вы можете ретранслировать видео или аудио файл (или поток) FFmpeg на сервер. В примере ниже мы передаем MJPEG видео с удаленной камеры:
Но для таких целей более разумно использовать опцию push на самом RTMP-сервере, чтобы исключить промежуточное звено и вытягивать поток на самом сервере.
Какая-то веб-камера в Японии
Тюнинг, решение проблем
-preset имя У H.264 есть несколько наборов настроек соотношения компрессия/скорость: ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow. Поэтому если вы хотите повысить производительность, стоит использовать:
-crf число непосредственно влияет на битрейт и качество. Принимает значения от 0 до 51 — чем больше, тем ниже качество картинки. По умолчанию 23, 18 — losless качество. Битрейт примерно удваивается при уменьшении CRF на 6.
-r число задает входной и выходной FPS. Для источников, с которых вы захватываете картинку, можно установить вместо -r -re, чтобы использовать «родной» FPS.
-rtbufsize число размер буфера реального времени. Если у вас постоянно появляются сообщения о переполнении буфера и отбрасывании кадров, вы можете поставить большой буфер (например, 100000k), однако это может увеличить задержку передачи.
-pix_fmt задает цветовую модель. Если у вас вместо картинки показывается черный квадрат, а звук работает, попробуйте поставить yuv420p или yuv422p.
-s ширинаxвысота входной и выходной размер картинки.
-g число насколько я понял, это максимальное число кадров между ключевыми. Если у вас FPS очень маленький, то можно поставить это значение поменьше, чтобы уменьшить задержку начала трансляции.
-keyint_min число минимальное число кадров между ключевыми.
-vf «crop=w:h:x:y» обрезать видео
-tune zerolatency «волшебная» опция уменьшения задержки трансляции. Что она конкретно делает я так и не нашел (-:
-analyzeduration 0 отключает анализ длительности, что помогает снизить задержку трансляции
Помимо рассмотренных выше параметров аудио вам может понадобиться -acodec copy в том случае, если ваш аудио поток не требует дополнительной перекодировки в MP3/AAC.
Пример: вещаем с веб-камеры с низкой задержкой без звука, рисуем в верхней части картинки текущее время
Плеер на сайте
Тут все просто. Поставьте на свой сайт один из популярных плееров, например Flowplayer или JW Player.
Пример подключения JW Player вы можете посмотреть на странице демо трансляции.
Что дальше?
С помощью модуля rtmp можно создать не только видеотрансляцию, но и видеочат, интернет-радио, простую платформу для вебинаров. Дерзайте!
Я рассмотрел лишь базовую функциональность nginx-rtmp-module и ffmpeg. Возможности у них гораздо шире, поэтому обратите внимание на документацию:
Блог nginx-rtmp-module
Wiki nginx-rtmp-module
Документация FFmpeg
Streaming Guide
x264 Encoding Guide
Filtering Guide
Запускаем свой RTMP сервер для стриминга
Иногда YouTube или Twitch не подходят как стриминговая платформа — скажем, если вы пилите портал с вебинарами или контентом 18+, нарушаете авторские права или хотите максимально отгородить свою трансляцию от остального интернета. У них есть много альтернатив как в виде сервисов (те же минусы, недостаток контроля и непредсказуемая политика), так и в виде self-hosted решений. Проблема опенсорсных стриминговых проектов в том, что все они начинаются с крохотной связки из пары технологий, а затем отчаянно пытаются вырасти в сервис, добавляя сложные веб-интерфейсы, чаты, библиотеки стримов и в конечном счёте отдаляясь от исходной цели: дать миру инструмент, который по понятному мануалу позволит запустить свой сервер трансляций. Что с ним будет дальше, в какие системы будет встроена эта картинка — это только ваше личное дело, а самописный аналог твича с лагающими и отваливающимися сервисами и периодически валящимся билдом не нужен никому, кроме его разработчиков. Поэтому в этой статье мы разберём минимальную цепочку действий для запуска своего RTMP-сервера с плеером.
Структура
Здесь всё просто: за приём и кодировку потока из OBS отвечает RTMP модуль Nginx’a. Сконвертированный поток он выставляет наружу, где его подбирает HLS (HTTP Live Streaming) клиент в браузере и выдаёт уже готовую картинку в плеере.
Установка
При выборе сервера упор стоит обратить внимание на процессор. Я взял эпичный сервер с двумя ядрами и пробовал наращивать битрейт, чтобы определить граничные условия — на 11-12k нагрузка стала болтаться в районе 96-100%, так что для обработки действительно тяжёлого потока лучше взять мощности с запасом:
Нам понадобится Docker для установки контейнеризованного nginx-rtmp с FFmpeg и любой веб-сервер (включая тот же Nginx) для раздачи страницы с плеером. Я ставил на Ubuntu 20.04:
Запускаем контейнер c проброшенными портами:
Затем в OBS на клиенте указываем наш сервер с произвольным ключом потока (ключ = индентификатор стрима):
Теперь можно запустить трансляцию и удостовериться что поток пошёл, например, в демке hls.js или в любом другом плеере HLS.
Осталось настроить сервер. В nginx.conf укажите путь до вашей страницы:
В index.html просто скопипастим код из примера hls.js:
Теперь на 8080 порту нашего сервера раздаётся жутковатый мультик про зайца:
Остаётся только изменить путь на http://server_ip:8080/live/stream-key.m3u8 и идти смотреть трансляцию!
Нагрузку в реальном времени можно проверять командой docker stats:
Заключение
Размещая стриминговый клиент на своём сервере важно помнить, что весь трафик со всех зрителей будет проходить прямо через него — значит, если одновременный онлайн у вас будет больше 1-2 человек, стоит изучать способы распределения нагрузки (ведь транскодирвоание ощутимо давит и на CPU). Для запуска полноценного кластера есть энтерпрайзное (но опенсорсное) решение — SRS aka Simple Realtime Server (GitHub, 10k звёзд, огромная вики, сложная архитектура). В него стоит вникать, если вам стримы нужны для решения настоящих задач, а не чтобы поиграться с приватным видеопотоком.
На правах рекламы
Серверы в аренду для любых задач — это про наши эпичные! Все серверы защищены от DDoS-атак, автоматическая установка множества ОС или использование своего образа ISO. Лучше один раз попробовать!
Видео вещание с OvenMediaEngine, до свидания nginx rtmp module
Когда Роман Арутюнян (rarutyunyan) выпустил модуль nginx-rtmp-module, это сильно перевернуло взгляд на доступность организации видеовещания. До этого, это казалось каким-то дорогим и сложным делом.
31 декабря Adobe официально хоронит флешплеер и убирает ссылки на скачивание с сайта. Это, конечно, не может не радовать. Эти засранцы то и дело подсовывали включенные по умолчанию галочки, так что даже продвинутому пользователю прилетал вместе с флешплеером еще и какой-то антивирус в лучшем случае. То, что это чудовище бесконечно просило обновлений ручками через браузер, знают все. Ходил даже анекдот, предлагающий создателям флешплеера законодательно ограничить паспорта сроком на 1 неделю с возможностью бесконечной перевыдачи.
Кому сдался флешплеер в конце 2020-го, вы хотите сказать? Да дело в том, что флеш плеер единственный поддерживал воспроизведение протокола rtmp в браузере с относительно низкой задержкой. Да и он не так уж и плох, учитывая, что по умолчанию все стриминговые сервисы, youtube или twitch из кодировщика просят передавать им видео по протоколу rtmp. Конечно, приходит более свежий SRT но разговор не об этом.
Вы убрали возможность играть видео в браузере по rtmp, а где альтернативы-то?
Форматы, работающие по http требуют хорошей буферизации. Задержка выливается в 15 секунд. Если вы общаетесь со своей аудиторией онлайн, это неприемлемо. WebRTC решения плохо дружат с реализацией один ко многим. Ну как плохо, плати, и будет хорошо. Cофт есть на рынке. Только беда еще с покрытием, по моим ощущениям, WebRTC только только нащупал какую-то стабильную фазу, при которой его можно использовать. Но все равно есть небольшие проблемы с форматами видео на разных платформах. Раньше все это выглядело так ужасно, что проще было просить ставить флешплеер только ради малой задержки.
В issue к nginx-rtmp-module не я один [1] [2] оставлял вопросы о поддержке форматов передачи видео по http с низкой задержкой (2-3 секунды). Ведь если бы можно было вещать в формате dash и hls до 3 секунд на nginx-rtmp-module, меня бы это полностью устроило. Но ответов на эти вопросы нет. Низкая задержка нужна в 2020 году и без нее ну никак. К сожалению, проект c 2017 года не развивается.
Медиасервер OvenMediaEngine.
Прекрасной альтернативой, отвечающей порывам всех моих желаний, является корейская морковка опенсорсный проект OvenMediaEngine, предлагающий не только средства кодирования и кластеризации (как у nginx-rtmp-module) но и средства воспроизведения т.е. свой html5 плеер OvenPlayer. Именно то, чего я так искал, зарелизили наши южнокорейские братья. С большим интересом я крутил его неделю и полностью перебрался на него.
- Задержка по WebRTC полсекунды.
- Задержка по dash low latency 2 секунды.
- HLS low latency скоро обещают.
Возможности:
- RTMP Push, MPEG2-TS Push, RTSP Pull Input
- WebRTC sub-second streaming
- Embedded WebRTC Signalling Server (WebSocket based)
- ICE (Interactive Connectivity Establishment)
- DTLS (Datagram Transport Layer Security)
- SRTP (Secure Real-time Transport Protocol)
- ULPFEC (Forward Error Correction) with VP8, H.264
- In-band FEC (Forward Error Correction) with Opus
- Low-Latency MPEG-DASH streaming (Chunked CMAF)
- Legacy HLS/MPEG-DASH streaming
- Embedded Live Transcoder (VP8, H.264, Opus, AAC, Bypass)
- Origin-Edge structure
- Monitoring
- Experiment
- P2P Traffic Distribution
- RTSP Pull, MPEG-TS Push Input
Так как команда активно развивает медиасервер, для быстрых апгрейдов я решил использовать предложенную ими установку через докер, накатывая внутрь контейнера всего две вещи: сертификаты от Lets Encrypt и файл настройки сервера.
С моей точки зрения из-за свежести проекта, документация OvenMediaEngine хоть и включает страницу с быстрым стартом, но не рассказывает о best default practice. Вникая во все это самостоятельно, выделил две проблемы с подачей материала и почувствовал что нужна статья.
- Показывают, как работают примеры по http и ws протоколу, хотя, очевидно, показывать нужно сразу, как работать на https и wss, все равно же придется заново все перенастраивать. К тому же, о прикреплении бесплатных сертификатов от Lets Encrypt в документации ни слова, хотя официально полностью поддерживают.
- Аналогично, после настройки и запуска сервера точка входа публично доступна для всех.(как и у nginx-rtmp-module) Нужно сразу показывать, как защищать точку входа.
Это все мелочи. Похвалю за очень удобные средства отладки. Они предлагают две страницы
http и https для отладки сервера. Более того, внесенные настройки сразу же отражаются как GET параметры в адресной строке — это чертовски удобно тестировать между браузерами. Поверьте, путаница в протоколах, портах, описках в урлах при первой подготовке сервера то еще занятие! А так, сохранил ссылку в браузере в закладках да и возвращайся когда нужно к настройке!
Установка. Быстрый старт
Итак, я возьму 20-ую Убунту.
После ставим certbot. Привязывайте ip к домену, получайте сертификаты.
Далее, получаем имя контейнера докера, например, 87b8610034bc
Вытащим конфиг из контейнера для редактирования. (Мне удобнее в момент изучения конфига видеть его где-то с подсветкой синтаксиса, поэтому вытаскиваю файл)
Старый добрый xml.
Раздел VirtualHost. Нам нужно задать имя сервера и указать пути к сертификатам внутри контейнера.
Имя сервера в виде звездочки «*» или еще дополнительные имена в конфиге не позволят запуститься OME корректно при использовании TLS.
Затем, нужно оставить только TLSPort порты.
Почему я рекомендую указывать те же порты, что и использовались для http? Сервер иначе не стартанет на одинаковых портах (не умеет), а выдумывать новые порты, когда при установке докера разработчики уже сделали в примере биндинги для контейнера, лишнее.
Заливаем конфиг обратно
И, соответственно, по заданным путям мы кидаем наши ключи
Урл вещания в obs
Линки для паблика
Если после запуска трансляции в OBS все хорошо и по линкам отдается манифест, можете проверить видео на странице с плеером.
Подписывание ссылок
OME так устроен, что позволяет создать публичные линки с разными правами. Например, одну и туже ссылку можно ограничить ip диапазоном или временем работы по разному для разных людей. Изменения в настройки сервера при этом вносить не нужно. Они используют схожую логику как у гугла Sign Policy.
1. Добавить блок SignedPolicy в секцию VirtualHost в Server.xml
После этого, вы не сможете ни посылать поток по старой ссылке в OBS ни принимать трафик по публичным ссылкам без подписей.
2. Запускаем signed_policy_url_generator.sh с параметрами, описанными внутри.
url_expire — обязательный параметр, который просит в миллисекундах (это не unix timestamp, а currentmillis.com ) указать, когда истечет ссылка.
rtmp://stream.***.ru:1935/app — идет в OBS в Server, остальная часть — в «Stream key».
3. Если OBS стартанул трансляцию, теперь нужно обязательно подписать необходимые публичные ссылки. Например для WebRTC.
Таким образом, не имея доступа к секрету, получить какой либо доступ к OME из дефолтных настроек больше нельзя.
Из настроек остается только прописать докер на автозапуск контейнера с системой. Ну и установить обновление сертификатов на крон, со скриптом, копирующим в контейнер ключи и рестартующим его. Ну или каким-то другим способом, как вы это делаете.
Кодировщик
Ребята считают OBS самым популярным кодировщиком для своего сервера. Поэтому как и в документации, так и более подробно в блоге можно найти подходящие настройки, максимально снижающие задержку в трансляции.
Настройки кодировщика для OBS студии для задержки в половину секунды следующие
Столь малая задержка конечно обходится более низким качеством изображения на пресете zero-latency. Другие пресеты хоть и добавляют задержку около 1.5 секунды, но картинку делают лучше.
Так же у них есть универсальный энкодер для андройда.
Еще немного о корейской морковке
Пожелания
- Система логов — это обычные txt файлики. Было бы очень круто иметь чуть более продвинутую визуальную аналитику. Например, знать сколько зрителей онлайн и какой траффик
- Я пробовал новый nginx-unit с его модным json-api в качестве команд управления/конфига. Суть в чем, обновляешь вебсервер, а он продолжает работать, заливаешь сертификаты, а ему не надо перезагружаться, домен, поддомен, добавить заголовки, убрать — все налету без перезагрузки. А поверх json-api появляется миллион офигенно удобных админок с UI. Хотя в OME и вроде бы и нет нужды в таком API, но наверняка кто-то что-то потом обязательно придумает)
Немного о ребятах. Они себя позиционируют как группа экспертов по медиа технологиям, ведут блог с любопытным контентом.
Судя по тому, что они плотно сотрудничают с местными телекомами, чувствуется очень хороший бекграунд для поддержки опенсорса в области стриминга. Это замечательно. Я прикреплю пару фоток из их нового офиса.
Ребята передают всем привет, статью заметили.