SIRINVIDEO Документация администратора и интегратора На сайт 2026.08

Приём публикации: RTMP и WHIP

Как принять поток, который кодировщик или браузер публикует на сервер: адрес публикации, RTMPS, WHIP и авторизация в строке запроса.

Иногда к источнику нельзя подключиться снаружи: он за NAT, за мобильным оператором или это вкладка браузера. Тогда роли меняются — сервер ждёт, а источник приходит сам. Такой поток объявляется источником publish://:

rtmp 1935;

stream studio { input publish://; }

Суффикс после схемы игнорируется: publish://, publish://rtmp и publish://whip — одно и то же. Сервер решает не по суффиксу, а по пути потока, на который пришёл публикатор.

Поток должен быть заранее объявлен в конфигурации

Публикация не создаёт потоки. Публикатор, пришедший на путь, для которого нет блока stream с источником publish://, отвергается. Это относится и к блокам template с директивой prefix — они не материализуют потоки по факту публикации.

Что нужно включить#

Поток publish:// требует хотя бы одного слушателя, через который публикация возможна:

rtmp  1935;      # приём RTMP
rtmps 1936;      # то же поверх TLS, общая с сервером TLS-идентичность
webrtc 40000;    # медиа-порт UDP для WHIP и WHEP
Параметр Тип и допустимые значения По умолчанию Применение
rtmp номер порта; 0 — выключено 0 рестарт
rtmps номер порта; 0 — выключено 0 рестарт
webrtc номер UDP-порта; 0 — выключено 0 рестарт
У RTMP нет порта по умолчанию

Приём и раздача по RTMP выключены, пока вы не напишете rtmp <порт>;. Обычно это 1935.

Если ни одного подходящего слушателя нет, конфигурация отвергается:

stream "studio": a publish:// source needs an `rtmp`/`rtmps` listener (RTMP publish) or a `webrtc_udp_port` (WHIP)

Публикация по RTMP#

Адрес публикации собирается так:

rtmp://media.example.com:1935/<приложение>/<поток>

Сервер сначала пробует найти поток с путём <приложение>/<поток>, затем — с голым <поток>. Поэтому плоское имя в конфигурации принимает публикатора, отправляющего в любое приложение:

stream cam1 { input publish://; }
Адрес, куда публикует кодировщик Какой поток будет найден
rtmp://media.example.com/live/cam1 cam1 (по голому имени)
rtmp://media.example.com/cam1 cam1
rtmp://media.example.com/live/cam1 при stream live/cam1 { … } live/cam1 (совпадение полного пути)

Многие кодировщики просят «адрес сервера» и «ключ потока» отдельно. Разложите адрес так:

Поле в кодировщике Значение
адрес (URL) rtmp://media.example.com:1935/live
ключ потока cam1

Для TLS замените схему и порт: rtmps://media.example.com:1936/live.

RTMPS шифрует канал, но сам по себе никого не проверяет

Шифрование и авторизация — разные вещи. Права на публикацию проверяются отдельно, как описано ниже.

Авторизация публикации#

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

У RTMP нет заголовков, поэтому учётные данные едут в строке запроса адреса. Хвост ?… отрезается и от имени приложения, и от ключа потока, ещё до поиска потока, — так что имя находится независимо от того, к какой части кодировщик прицепил запрос:

rtmp://media.example.com:1935/live/cam1?token=$TOKEN

Если кодировщик позволяет добавить запрос только к ключу потока, работает и такая форма:

Поле в кодировщике Значение
адрес (URL) rtmp://media.example.com:1935/live
ключ потока cam1?token=$TOKEN

При отказе кодировщик получает статус NetStream.Publish.Denied с причиной отказа, а в журнале сервера появляется строка вида [cam1] rtmp publish denied — <причина>.

Как выпустить учётные данные для публикации

Поля токена, права на публикацию и режимы проверки описаны в Авторизации публикации. Если авторизация медиа не настроена, публикация принимается без учётных данных — это осознанное «шлюза нет, значит открыто», а не сбой.

Открытый порт RTMP без настроенной авторизации — открытая публикация

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

Публикация из браузера: WHIP#

WHIP — публикация по WebRTC поверх обычного HTTP-запроса.

Метод и путь Назначение
POST /s/<поток>/whip тело — SDP-предложение, не более 64 КиБ; ответ 201, application/sdp, заголовок Location: /s/<поток>/whip/<идентификатор сессии>
DELETE /s/<поток>/whip/<идентификатор сессии> завершение сессии

Учётные данные передаются заголовком Authorization или параметром ?token=. Проверка выполняется до чтения тела SDP и до захвата места публикатора.

webrtc 40000;

stream studio { input publish://; }

Готовая страница публикации есть во встроенном плеере:

https://media.example.com/studio/embed.html?proto=whip

Она запрашивает камеру и микрофон у браузера и публикует поток на сервер. Отдельная вкладка для публикации в списке протоколов не показывается — открывайте её параметром ?proto=whip. См. Встраиваемый плеер.

Что можно опубликовать по WHIP

Видео — только H.264. Звук — Opus или G.711 (µ-law и A-law); AAC по WebRTC не согласуется.

Один публикатор на поток#

Место публикатора занимает тот, кто пришёл первым. Второй публикатор на том же пути отвергается, а не перехватывает поток:

NetStream.Publish.BadName — already publishing

Публикатор, пришедший на путь, для которого публикация не настроена, получает подсказку:

NetStream.Publish.BadName — no publish gate on this node — a publisher must target the stream's host node

Это означает: на этом сервере нет потока с источником publish:// для такого пути. Проверьте написание пути и имя приложения.

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

Что происходит с кадрами на приёме#

Очередь приёма ограничена 512 единицами доступа. При переполнении отбрасывается самый старый кадр — так удерживается живой край; параметры кодека (Setup) не отбрасываются никогда. Число отброшенных кадров видно в API как потери на входе (input_loss).

Сторож замершего медиа на публикации не взводится

Директива media_timeout не применяется к потоку, в цепочке источников которого есть publish://: живой, но временно молчащий публикатор не должен отключаться. По той же причине флаг on_demand на таком потоке игнорируется.

Что принимается по RTMP#

Тип Кодеки
Видео H.264, H.265
Звук AAC, G.711 (µ-law и A-law)

Перекодирования нет: что опубликовали, то и раздаётся. Какие кодеки дойдут до какого зрителя — см. Протоколы раздачи.

Полный пример#

http  8080;
https 8443;
rtmp  1935;
rtmps 1936;
webrtc 40000;

auth { admin_password "смените-этот-пароль"; }

storage archive /var/lib/hastreamer/dvr;

# Кодировщик публикует на rtmp://media.example.com:1935/live/studio
stream studio {
  input publish://;
  dvr archive 7d;
}

# Публикация из браузера по WHIP на тот же сервер
stream talk {
  input publish://;
}
Убедитесь, что публикация принята
curl -sS "https://media.example.com/api/v1/streams/studio" \
  -H "Authorization: Bearer $TOKEN" \
  | python3 -c 'import sys, json
s = json.load(sys.stdin)
print("alive =", s["alive"], "| health =", s["health"])
print("tracks:", [(t["kind"], t["codec"]) for t in s["tracks"]])'
alive = True | health = ok
tracks: [('video', 'H.264'), ('audio', 'AAC')]

Пока публикатора нет, поток отвечает alive = False, и это нормальное состояние ожидания.

Куда двигаться дальше#