Архитектура
Что происходит между приёмом кадра и его отправкой зрителю: один разбор, одна упаковка, много протоколов.
Понимание внутреннего устройства нужно не из любопытства: оно объясняет, почему одни настройки применяются мгновенно, а другие требуют перезапуска, почему добавление второго протокола раздачи почти ничего не стоит, и почему тысяча зрителей одного потока нагружает сервер слабее, чем сто зрителей десяти разных потоков.
Путь кадра#
источник → приём → разбор → ЕДИНАЯ УПАКОВКА → раздача → зрители
камера RTSP кадры фрагменты в HLS/DASH/
кодировщик RTMP кольцевом буфере MSE-WS/RTSP/
файл HLS WebRTC/RTMP
↓
архив (DVR)
Ключевая идея — упаковать один раз, раздать многим. Принятый поток разбирается на кадры и складывается в кольцевой буфер фрагментов. Все протоколы раздачи читают один и тот же буфер: HLS отдаёт фрагменты как сегменты плейлиста, MSE-WS шлёт их в браузер по вебсокету, RTSP распаковывает их обратно в пакеты. Второй, третий и десятый протокол не добавляют работы по переупаковке — только отправку.
Отсюда практическое следствие: включать «лишние» протоколы раздачи не вредно. Стоимость несёт не протокол, а поток и число отправляемых байт.
Кадр, принятый от камеры, доходит до зрителя байт в байт. Меняется только контейнер — оболочка, в которую кадр завёрнут. Поэтому кодек и разрешение выбираются на камере, а не на сервере.
Поток и его жизненный цикл#
Поток (stream) — именованная единица конфигурации: у неё есть источник, необязательный архив
и имя, по которому её запрашивают зрители. Имя потока — это путь в URL:
поток cam1 → http://media.example.com:8080/cam1/index.m3u8
rtsp://media.example.com:8554/cam1
Поток может быть в трёх состояниях:
| Состояние | Что значит |
|---|---|
| Активен | источник подключён, кадры идут, буфер наполняется |
| Припаркован | зрителей нет, источник отключён намеренно (режим по требованию) |
| Ошибка | источник недоступен, идут попытки переподключения |
Режим по требованию#
Поток можно не держать подключённым постоянно, а поднимать при первом зрителе и отпускать через заданное время после последнего. Это экономит и трафик до камеры, и ресурсы сервера, но добавляет задержку на первое подключение. См. Приём видео: обзор.
Один процесс, много ядер#
Сервер — один процесс, который распределяет работу по ядрам по принципу «ничего общего»: каждое ядро владеет своими соединениями и своими потоками и не берёт блокировок на горячем пути.
- Приём и упаковка конкретного потока закреплены за одним ядром — так кадры не путешествуют между ядрами при обработке.
- Зритель, попавший на другое ядро, получает ссылку на готовый фрагмент, а не его копию. Поэтому тысяча зрителей одного потока дешевле, чем кажется.
Число рабочих ядер задаётся директивой cores. Значение 0 означает «все производительные ядра
хоста» и подходит почти всегда.
cores 1 — это не «поменьше нагрузки»Директива не ограничивает потребление, а сводит всю работу на одно ядро. На загруженном сервере это приводит к тому, что одно ядро занято на 100%, а остальные простаивают.
Что применяется сразу, а что требует перезапуска#
Конфигурация делится на три класса:
| Класс | Примеры | Как применить |
|---|---|---|
| Горячее | добавление и удаление потоков, изменение источника, параметры архива, авторизация | systemctl reload hastreamer |
| Рестарт | номера портов, cores, TLS-слушатели |
systemctl restart hastreamer |
| Рабочая нагрузка | директивы внутри потока, влияющие на приём | перезапускается только затронутый поток |
Перезагрузка по reload не разрывает существующие сессии зрителей потоков, которых изменения не
коснулись. Подробности и точная таблица — Применение изменений.
Архив#
Запись ведётся из того же кольцевого буфера, что и раздача: отдельного разбора для архива нет. Фрагменты складываются в хранилище — локальный каталог или бакет S3, — и индексируются по времени. Глубина архива ограничивается временем, объёмом или обоими сразу; при исчерпании места старые записи вытесняются.
Просмотр архива идёт теми же протоколами, что и живое видео: плеер запрашивает интервал времени и получает обычный плейлист. См. Архив: принципы.
Что снаружи#
| Слушатель | Директива | Назначение |
|---|---|---|
| HTTP | http <порт>; |
панель, API, HLS/DASH/MSE-WS/HTTP-TS, плеер, метрики |
| HTTPS | https <порт>; |
то же самое поверх TLS |
| RTSP | rtsp <порт>; |
приём и раздача по RTSP |
| RTMP | rtmp <порт>; |
приём публикации и раздача по RTMP |
| RTMPS | rtmps <порт>; |
то же поверх TLS |
| WebRTC | webrtc <порт>; |
медиа-порт UDP для WHEP и WHIP |
Отдельного веб-сервера не требуется: HTTP-слушатель сам отдаёт и панель, и API, и медиа.
Сервер умеет получать сертификаты ACME самостоятельно — см. TLS и сертификаты. Если вы всё же ставите прокси, пробрасывайте заголовки о клиентском адресе, иначе привязка токенов к IP и учёт сессий будут видеть адрес прокси вместо адреса зрителя.
Кластер#
Несколько серверов можно объединить: они обмениваются состоянием, знают о потоках друг друга и умеют проксировать запросы к соседу, у которого поток размещён. Для одного сервера ничего включать не нужно — кластер выключен по умолчанию.