◆ ForgeVis
Skip to content

Справочник по конфигурации ​

Минимальная рабочая конфигурация config.yaml:

yaml
record:
  format: fmp4
  buffer_size_mb: 4
  segmentDuration: 900

cameraDefaults:
  record_path: "./recordings/%path/%Y-%m-%d_%H-%M-%S_%f.mp4"
  record: true

rtsp:
  enabled: true
  port: 8554

cameras:
  camera_001:
    source: "rtsp://admin:password@192.168.1.100:554/stream1"

Конфигурационный файл ​

По умолчанию ForgeVis ищет config.yaml в текущей директории. Вы можете указать другой файл:

bash
./forgevis my-config.yaml

Настройки ​

cameraDefaults ​

Настройки по умолчанию для всех камер. Могут быть переопределены для конкретной камеры. Здесь можно задать любой параметр камеры из раздела cameras, кроме source, sub и snapshot.

record_path ​

Шаблон пути для записей с плейсхолдерами:

  • %path — идентификатор камеры (ключ из cameras map)
  • %Y, %m, %d, %H, %M, %S — момент начала сегмента: год (4 цифры), месяц, день, час, минута, секунда
  • %f — номер фрагмента внутри сегмента (6 цифр, с ведущими нулями)

Пример: ./recordings/%path/%Y-%m-%d_%H-%M-%S_%f.mp4 превратится в
./recordings/camera_001/2025-12-04_22-00-00_000000.mp4

Сменить путь: создайте каталог, отдайте его пользователю службы (chown forgevis:forgevis <каталог>), поменяйте record_path и перезапустите службу. Записи по старому пути в архиве не видны — архив ищется по новому шаблону; перенесите их в новый каталог с той же структурой или оставьте как есть.

retention_days ​

Сколько суток хранить записи:

yaml
cameraDefaults:
  retention_days: 30

Удаляет записи команда forgevis --retention, а не сервис — её ставят в крон. Без retention_days не удаляется ничего. Подробнее: Очистка архива.

record ​

Глобальное включение/выключение записи по умолчанию:

  • record (булево, опционально) — когда true, запись включена для камер, если не переопределено в камере

Чтобы отключить запись по умолчанию, установите record: false:

yaml
cameraDefaults:
  record: false  # отключить запись для всех камер

reconnect ​

Паузы между попытками подключиться к камере, которая не отвечает или оборвала поток. Расписание одно на узел — для записи, HLS, RTSP-рестрима и зрителей; неудачи считаются отдельно для основного потока и субпотока каждой камеры. Значения по умолчанию:

yaml
reconnect:
  healthy_reset_sec: 30
  jitter_percent: 20
  backoff:
    - { delay_sec: 0,  attempts: 1 }
    - { delay_sec: 5,  attempts: 5 }
    - { delay_sec: 10, attempts: 5 }
    - { delay_sec: 15, attempts: 5 }
    - { delay_sec: 30, attempts: 0 }
  • backoff — ступени по порядку: attempts попыток с паузой delay_sec секунд перед каждой. attempts: 0 у последней ступени значит «дальше всегда так»; пауза последней ступени должна быть больше нуля
  • jitter_percent (от 0 до 100) — каждая пауза случайно удлиняется или укорачивается на эту долю, чтобы камеры, пропавшие вместе, не подключались в одну секунду
  • healthy_reset_sec — сколько секунд поток должен проработать, чтобы счёт неудач обнулился

Пауза — время между попытками; сама попытка длится до 15 секунд. Пока идёт пауза, узел к камере не обращается, а запрос её потока сразу получает отказ с причиной и временем следующей попытки. Изменение настроек камеры начинает счёт заново. Расписание применяется без перезапуска сервиса.

record ​

Глобальные настройки записи:

yaml
record:
  format: fmp4
  buffer_size_mb: 4
  segmentDuration: 900
  runOnSegmentCreate: "./hooks/on-create.sh"
  runOnSegmentComplete: "./hooks/on-complete.sh"
  • format (строка, по умолчанию fmp4) — формат записи: fmp4 (фрагментированный MP4, можно смотреть во время записи) или mp4 (обычный MP4)
  • buffer_size_mb (число, по умолчанию 4) — размер буфера writer на камеру (МБ)
  • segmentDuration (число, по умолчанию 900) — длительность сегмента в секундах
  • runOnSegmentCreate (строка, опционально) — shell-команда при старте нового сегмента
  • runOnSegmentComplete (строка, опционально) — shell-команда после завершения сегмента
  • runPeriodically — периодический хук: command, intervalSec (по умолчанию 60), maxConcurrent (по умолчанию 50). Подробнее — Хуки событий

Переменные окружения для хуков:

  • SF_PATH — ID камеры
  • SF_SEGMENT_PATH — полный путь к файлу сегмента
  • SF_SEGMENT_DURATION — длительность сегмента в секундах (только для runOnSegmentComplete)

rtsp ​

Настройки RTSP сервера для рестриминга:

  • enabled (булево, по умолчанию true) — включить RTSP сервер
  • port (число, по умолчанию 8554) — TCP порт для RTSP сервера
  • udp_rtp_port (число, по умолчанию 8000) — UDP порт для RTP пакетов
  • udp_rtcp_port (число, по умолчанию 8001) — UDP порт для RTCP пакетов
  • idle_timeout_sec (число, по умолчанию 10) — отключение от камеры через N секунд после отключения последнего клиента

RTSP сервер поддерживает как TCP (interleaved), так и UDP транспорты. URL для рестрима: rtsp://localhost:8554/{camera_id}

Чтобы отключить RTSP сервер полностью:

yaml
rtsp:
  enabled: false

api ​

Настройки HTTP API управления:

yaml
api:
  enabled: true
  address: "0.0.0.0:9997"
  allowOrigin: "*"
  rateLimit:
    enabled: true
    perMinute: 600
    burst: 60
  archiveJobTimeoutSec: 3600
  archiveExportDir: "/var/lib/forgevis/exports"
  • enabled (булево, по умолчанию true) — включить Management API
  • address (строка, по умолчанию "0.0.0.0:9997") — адрес и порт для прослушивания
  • allowOrigin (строка, по умолчанию "*") — разрешенный источник для CORS. * — любой источник, иначе один или несколько через запятую (https://a.example, https://b.example); значение, не являющееся источником, пропускается с предупреждением в журнале
  • rateLimit.enabled (булево, по умолчанию true) — per-IP rate limit на API
  • rateLimit.perMinute (int, по умолчанию 600) — постоянная скорость запросов с одного IP
  • rateLimit.burst (int, по умолчанию 60) — ёмкость token bucket (стартовый бёрст)
  • archiveJobTimeoutSec (int, по умолчанию 3600) — сколько секунд может идти один запуск ffmpeg при экспорте или таймлапсе архива; дольше — процесс останавливается, задание завершается ошибкой
  • archiveExportDir (строка, по умолчанию /var/lib/forgevis/exports) — каталог готовых файлов экспорта и таймлапса, там же лежат части, которые узел-сборщик скачивает с других узлов. Создаётся при первом задании с доступом только для сервиса. Путь абсолютный: выгрузки занимают гигабайты, и относительный зависел бы от каталога, из которого запущена служба

При пустом bucket'е API возвращает 429 Too Many Requests. Дефолты подобраны щедро для внутренней сети; ужесточайте если API доступен из менее доверенных сегментов.

tls ​

TLS для всех HTTP-слушателей узла сразу: управляющего API, HLS, сигнализации WebRTC, воспроизведения архива и метрик.

yaml
tls:
  enabled: false
  cert: /etc/forgevis/tls/node.pem
  key:  /etc/forgevis/tls/node.key
  • enabled (булево, по умолчанию false) — отдавать все HTTP-слушатели по HTTPS
  • cert (строка) — PEM-цепочка сертификата
  • key (строка) — PEM приватный ключ, PKCS#8 или PKCS#1

Один сертификат на узел, а не по одному на подсистему: браузер, открывший интерфейс по https, не загрузит плейлист HLS или эндпоинт WHEP по http.

enabled: true без читаемых cert и key — отказ при запуске. Сертификат читается один раз при старте, поэтому его замена требует перезапуска.

Подробнее, включая выпуск самоподписанного сертификата и разницу с cluster.tls, — в разделе Безопасность.

Безопасность потоков (security) ​

Опциональный блок управления доступом к live‑потокам, API и метрикам. По умолчанию, если блок security отсутствует или список users пустой, все запросы разрешены (как в предыдущих версиях).

yaml
security:
  auth_method: internal

  users:
    # Локальный администратор: API и метрики с localhost без пароля
    - user: any
      pass:
      ips: ["127.0.0.1/32", "::1/128"]
      permissions:
        - action: api
        - action: metrics

    # Viewer для всех live‑стримов (RTSP / HLS / WebSocket)
    - user: viewer
      pass: "change-me"
      ips: []
      permissions:
        - action: read
  • auth_method (строка, по умолчанию internal) — backend аутентификации; сейчас реализован только internal.
  • users — список правил пользователей:
    • user — имя пользователя, специальное значение any означает любого (анонимного) пользователя.
    • pass — опциональный пароль. Поддерживается открытый вид или формат sha256:<base64_sha256> (игнорируется, если user: any).
    • ips — опциональный список IP или CIDR‑сетей, с которых разрешён доступ (пусто = любые IP).
    • permissions — список разрешений:
      • action — одно из publish, read, api, metrics.
      • path — опциональное ограничение по камере/пути (пусто или не указано = любые).
  • lockout — защита от подбора пароля:
    • attempts (число, по умолчанию 10) — сколько неудачных входов подряд; 0 выключает защиту.
    • duration_sec (число, по умолчанию 300) — на сколько секунд после этого пользователь блокируется с этого адреса.

SHA256 credentials ​

Если не хотите хранить логин/пароль в открытом виде, используйте SHA256 + Base64:

bash
echo -n "mypass" | openssl dgst -binary -sha256 | openssl base64

Далее укажите значение с префиксом sha256::

yaml
security:
  auth_method: internal
  users:
    - user: sha256:jGl25bVBBBW96Qi9Te4V37Fnqchz/Eu4qB9vKrRIqRg=
      pass: sha256:6nHCWnpgIka0w5gkuFVniJSpb0O7m3ExnDlwCh4EUiI=
      permissions:
        - action: read

Полные примеры и рекомендации по миграции: Безопасность и авторизация.

Когда в security.users определён хотя бы один пользователь:

  • все live‑эндпоинты (RTSP рестриминг, HLS, WebSocket /websocket/{camera_id}) требуют соответствующего разрешения с action: read (и опциональным path для ограничения по камере), и
  • endpoint /metrics требует разрешения с action: metrics.

Управляющий API при этом требует разрешения с action: api.

websocket ​

Настройки для низколатентного стриминга (MSE over WebSocket):

yaml
websocket:
  enabled: true
  allowOrigin: "*"
  • enabled (булево, по умолчанию true) — включить WebSocket стриминг
  • allowOrigin (строка, по умолчанию "*") — страницы, с которых можно открыть WebSocket. Браузер не применяет CORS к WebSocket, поэтому узел сам сверяет заголовок Origin и отвечает 403 странице не из списка; запрос без Origin (не из браузера) пропускается. * — любая страница, иначе один или несколько источников через запятую

webrtc ​

Настройки сигналинга и browser playback через WebRTC:

yaml
webrtc:
  enabled: true
  address: ":8889"
  allowOrigin: "*"
  localUdpAddress: ":8189"
  localTcpAddress: ""
  ipsFromInterfaces: true
  ipsFromInterfacesList: []
  additionalHosts: []
  iceServers2:
    - url: "stun:stun.l.google.com:19302"
      username: ""
      password: ""
      client_only: false
  handshakeTimeout: "10s"
  trackGatherTimeout: "2s"
  stunGatherTimeout: "5s"
  • enabled (булево, по умолчанию false) — включить WebRTC сервер
  • address (строка, по умолчанию :8889) — HTTP-адрес прослушивания WebRTC сигналинга
  • allowOrigin (строка, по умолчанию *) — разрешенный источник для CORS у эндпоинтов сигналинга. * — любой источник, иначе один или несколько через запятую (https://a.example, https://b.example); значение, не являющееся источником, пропускается с предупреждением в журнале
  • localUdpAddress (строка, по умолчанию :8189) — локальный адрес UDP-прослушивания для ICE
  • localTcpAddress (строка, по умолчанию пусто) — локальный адрес TCP-прослушивания для ICE TCP
  • ipsFromInterfaces (булево, по умолчанию true) — добавлять host-кандидаты из сетевых интерфейсов
  • ipsFromInterfacesList (список строк, по умолчанию []) — список интерфейсов для host-кандидатов
  • additionalHosts (список строк, по умолчанию []) — дополнительные публичные/приватные host-кандидаты
  • iceServers2 — список ICE-серверов (STUN/TURN):
    • url (строка, обязательно) — URL ICE сервера (stun:..., turn:...)
    • username (строка, опционально) — имя пользователя для TURN-аутентификации
    • password (строка, опционально) — пароль для TURN-аутентификации
    • client_only (булево, по умолчанию false) — показывать этот ICE сервер только клиентам
  • handshakeTimeout (строка, по умолчанию 10s) — максимальная длительность WebRTC-рукопожатия
  • trackGatherTimeout (строка, по умолчанию 2s) — максимальное ожидание готовности трека/медиа
  • stunGatherTimeout (строка, по умолчанию 5s) — максимальное ожидание сбора STUN-кандидатов

Практика использования эндпоинтов и браузерного воспроизведения: Руководство по WebRTC.

hls ​

Просмотр в браузере по HLS. Подробно, с выбором качества и ступенью 720p, — HLS-стриминг.

yaml
hls:
  enabled: true
  address: ":8888"
  variant: lowLatency
  segmentCount: 7
  segmentDuration: 1s
  partDuration: 200ms
  muxerCloseAfter: 60s
  transcodeMaxConcurrent: 2
  • enabled (булево, по умолчанию false) — включить HLS-сервер
  • address (строка, по умолчанию :8888) — адрес и порт
  • allowOrigin (строка, по умолчанию не задан) — значение заголовка Access-Control-Allow-Origin; без него заголовок не отдаётся. * — любой источник, иначе один или несколько через запятую (https://a.example, https://b.example); значение, не являющееся источником, пропускается с предупреждением в журнале
  • alwaysRemux (булево, по умолчанию false) — держать HLS всех камер готовым, а не поднимать по первому запросу
  • variant (строка, по умолчанию lowLatency) — lowLatency (Low-Latency HLS) или fmp4 (обычный HLS)
  • segmentCount (число, по умолчанию 7) — сколько сегментов держать в плейлисте, не меньше трёх целевых длительностей
  • segmentDuration (строка, по умолчанию 1s) — минимальная длительность сегмента; сегмент заканчивается на ключевом кадре, поэтому на практике он равен интервалу ключевых кадров камеры, если тот длиннее
  • partDuration (строка, по умолчанию 200ms) — длительность части Low-Latency HLS
  • muxerCloseAfter (строка, по умолчанию 60s) — через сколько без запросов остановить HLS камеры (и ступень 720p)
  • transcodeMaxConcurrent (число, по умолчанию 2) — сколько ступеней 720p может кодироваться на узле одновременно; 0 — не предлагать ступень

playback ​

Выдача записей архива по HTTP с перемоткой на любой момент. Подробно — Воспроизведение архива.

  • enabled (булево, по умолчанию false) — включить сервер воспроизведения
  • address (строка, по умолчанию :9996) — адрес и порт
  • allowOrigin (строка, по умолчанию не задан) — значение заголовка Access-Control-Allow-Origin. * — любой источник, иначе один или несколько через запятую (https://a.example, https://b.example); значение, не являющееся источником, пропускается с предупреждением в журнале

metrics ​

Метрики в формате Prometheus. Подробно — Мониторинг.

  • enabled (булево, по умолчанию false) — включить эндпоинт метрик
  • address (строка, по умолчанию :9998) — адрес и порт
  • allowOrigin (строка, по умолчанию не задан) — значение заголовка Access-Control-Allow-Origin. * — любой источник, иначе один или несколько через запятую (https://a.example, https://b.example); значение, не являющееся источником, пропускается с предупреждением в журнале

logging ​

Журнал службы. Подробно — Мониторинг.

  • directory (строка, по умолчанию /var/log/forgevis) — каталог файлов журнала
  • level (строка, по умолчанию info) — уровень: error, warn, info, debug, trace
  • maxSizeMb (число, по умолчанию 100) — размер файла журнала, после которого начинается новый
  • maxBackups (число, по умолчанию 10) — сколько старых файлов хранить
  • console (булево, по умолчанию true) — дублировать журнал в консоль

database ​

Камеры и метаданные записей из PostgreSQL. Подробно — Общая база данных.

  • enabled (булево, по умолчанию false) — подключаться к базе
  • url (строка) — строка подключения, postgres://user:pass@host:5432/db
  • watch (булево, по умолчанию true) — применять изменения камер в базе на лету

cluster ​

Несколько узлов с переносом камер при отказе. Подробно — Кластеризация и HA.

  • enabled (булево, по умолчанию false) — включить режим кластера
  • node_id (число) — идентификатор узла в кластере
  • rpc_addr (строка) — адрес для связи узлов между собой
  • dataDir (строка, по умолчанию /var/lib/forgevis/data) — где узел хранит состояние кластера; путь абсолютный
  • tls.caCert, tls.cert, tls.key (строки) — сертификаты для связи узлов

nodeName ​

Имя узла на верхнем уровне конфига (строка, по умолчанию — имя хоста системы). По нему узел выбирает из базы свои камеры (cameras.node_name), поэтому у двух узлов имена должны различаться.

cameras ​

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

  • source (строка, обязательно) — RTSP-адрес основного потока вместе с логином и паролем
  • sub (строка, опционально) — RTSP-адрес субпотока
  • snapshot (строка, опционально) — HTTP-адрес кадра с камеры, который отдаёт /api/cameras/{id}/snapshot; логин и пароль берутся из этого адреса, а если их там нет — из source
  • record (булево) — вести ли запись камеры
  • retention_days (число) — сколько суток хранить записи, см. Очистка архива
  • audio (булево, по умолчанию false) — записывать и отдавать звук
  • rtsp (булево, по умолчанию true) — отдавать камеру через RTSP-сервер
  • hls (булево, по умолчанию true) — отдавать камеру по HLS
  • alwaysRemux (булево) — держать HLS этой камеры готовым всегда (переопределяет hls.alwaysRemux)
  • ptz (булево, по умолчанию false) — у камеры есть управление PTZ
  • onvif.endpoint, onvif.username, onvif.password (строки) — адрес и учётные данные ONVIF для PTZ; по умолчанию адрес строится из хоста source, а логин и пароль берутся из source
  • connection_timeout_sec (число, по умолчанию 5, в кластере 30) — через сколько секунд без подписчиков отключаться от камеры
  • node_name (строка) — на каком узле кластера предпочтительно держать камеру

Любой из этих параметров, кроме source, sub и snapshot, можно задать для всех камер в cameraDefaults.

Формат адреса source ​

rtsp://[логин[:пароль]@]хост[:порт]/путь

Каждая камера должна указывать:

  • source (строка, обязательно) — RTSP URL с credentials
  • sub (строка, опционально) — RTSP URL субпотока
  • record (булево, опционально) — включить/выключить запись для этой камеры
  • retention_days (число, опционально) — сколько суток хранить записи этой камеры; см. Очистку архива
  • audio (булево, опционально) — включить запись и стриминг аудио (по умолчанию из cameraDefaults)
  • ptz (булево, опционально) — включить PTZ управление для этой камеры

Формат source URL ​

Поле source должно быть валидным RTSP URL. Credentials встроены в URL:

rtsp://[username[:password]@]host[:port]/path

Примеры:

yaml
# С аутентификацией
source: "rtsp://admin:password123@192.168.1.100:554/stream1"

# Без аутентификации
source: "rtsp://192.168.1.101:554/stream1"

# Кастомный порт
source: "rtsp://user:pass@camera.local:8554/live"

Субпотоки ​

Для камер с двумя потоками (основной + субпоток):

yaml
cameras:
  camera_001:
    source: "rtsp://admin:password@192.168.1.100:554/stream1"  # HD поток
    sub: "rtsp://admin:password@192.168.1.100:554/stream2"     # SD поток

Доступ к потокам:

  • Основной: rtsp://localhost:8554/camera_001
  • Субпоток: rtsp://localhost:8554/camera_001/sub

Переопределение записи ​

Отключить запись для конкретной камеры:

yaml
cameras:
  camera_001:
    source: "rtsp://..."
    record: false  # только рестриминг

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

yaml
# Настройки по умолчанию для всех камер
cameraDefaults:
  record_path: "./recordings/%path/%Y-%m-%d_%H-%M-%S_%f.mp4"
  record: true
  audio: true  # Включить аудио по умолчанию

# Глобальные настройки записи
record:
  format: fmp4
  buffer_size_mb: 4
  segmentDuration: 900

# RTSP сервер для рестриминга
rtsp:
  enabled: true
  port: 8554
  idle_timeout_sec: 300        # 5 минут без клиентов

# Камеры
cameras:
  # HD камера с субпотоком и аудио
  camera_001:
    source: "rtsp://admin:password@192.168.1.100:554/stream1"
    sub: "rtsp://admin:password@192.168.1.100:554/stream2"
    audio: true  # Запись с аудио
  
  # Камера только для рестриминга (без записи)
  camera_002:
    source: "rtsp://admin:password@192.168.1.101:554/stream1"
    record: false
  
  # Камера с записью и звуком
  important_camera:
    source: "rtsp://admin:password@192.168.1.102:554/stream1"
    record: true
    audio: true
  
  # Камера без аутентификации, только видео
  public_camera:
    source: "rtsp://192.168.1.103:554/stream"
    audio: false  # Только видео, без аудио

Режимы работы ​

Режим 1: Только запись (нет RTSP сервера) ​

yaml
record:
  format: fmp4
  buffer_size_mb: 4
  segmentDuration: 900

cameraDefaults:
  record: true

rtsp:
  enabled: false  # отключить рестриминг

cameras:
  camera_001:
    source: "rtsp://..."

Режим 2: Только рестриминг (нет записи) ​

yaml
cameraDefaults:
  record: false  # отключить запись для всех

record:
  format: fmp4
  buffer_size_mb: 4
  segmentDuration: 900

rtsp:
  enabled: true
  port: 8554

cameras:
  camera_001:
    source: "rtsp://..."

Режим 3: Запись + рестриминг ​

yaml
record:
  format: fmp4
  buffer_size_mb: 4
  segmentDuration: 900

cameraDefaults:
  record: true

rtsp:
  enabled: true
  port: 8554

cameras:
  camera_001:
    source: "rtsp://..."

Модульная конфигурация (conf.d) ​

Для больших развёртываний с множеством камер можно разделить конфигурации на отдельные файлы в директории conf.d/:

yaml
# conf.d/warehouse.yaml
warehouse_cam_01:
  source: "rtsp://user:pass@192.168.1.200:554/stream1"
  
warehouse_cam_02:
  source: "rtsp://user:pass@192.168.1.201:554/stream1"
yaml
# conf.d/parking.yaml
parking_entrance:
  source: "rtsp://user:pass@192.168.1.210:554/stream1"
  sub: "rtsp://user:pass@192.168.1.210:554/stream2"

Преимущества:

  • Модульность: Один файл на камеру или локацию
  • Организация: Группировка камер по зданию, этажу или зоне
  • Масштабируемость: Легко добавлять/удалять камеры без редактирования основного конфига
  • Командная работа: Разные люди могут управлять разными конфигами камер
  • Безопасность: Credentials в отдельных файлах (опционально .gitignore)

Порядок загрузки:

  1. Сначала загружаются камеры из config.yaml
  2. Затем камеры из conf.d/*.yaml в алфавитном порядке
  3. Если ID камеры есть в обоих местах, версия из conf.d имеет приоритет (с предупреждением)

Лучшие практики ​

Хранилище ​

  • Формат fmp4 предпочтителен (поддерживает воспроизведение во время записи)
  • Используйте иерархическую структуру пути: /rpool/%path/%Y/%m/%d/stream-%path_%Y-%m-%d_%H-%M-%S.mp4
  • Подбирайте длительность сегмента под сценарий:
    • 60 с для оперативного мониторинга
    • 300–900 с для архивного хранения

Камеры ​

  • Используйте говорящие идентификаторы (например, front_door, parking_north)
  • Отключайте запись отдельной камеры через record: false
  • Проверяйте RTSP URL утилитой ffprobe перед добавлением в конфиг

RTSP-сервер ​

  • Порт 8554 — стандартный для RTSP
  • Меняйте порт при конфликтах
  • Откройте TCP-порт RTSP-сервера в firewall

Горячая перезагрузка ​

ForgeVis автоматически отслеживает изменения конфигурации и применяет их без перезапуска.

Отслеживаемые файлы ​

  • config.yaml - Основной файл конфигурации
  • conf.d/*.yaml - Индивидуальные файлы камер

Что можно изменять ​

  • Добавлять камеры - Создавать новые YAML файлы в conf.d/ или добавлять в config.yaml
  • Удалять камеры - Удалять файлы камер или убирать из конфига
  • Обновлять источники - Менять RTSP URL для существующих камер
  • Включать/отключать запись - Переключать опцию record для отдельных камер

Как это работает ​

  1. Файлы конфигурации мониторятся на изменения
  2. Изменения группируются с задержкой (500ms) для обработки быстрых правок
  3. Новая конфигурация загружается и валидируется
  4. Запущенные камеры сравниваются с новой конфигурацией:
    • Удалённые камеры останавливаются и очищаются
    • Изменённые источники запускают перезапуск камеры
    • Новые камеры запускаются автоматически
  5. RTSP/HLS стримы обновляются немедленно

Пример использования ​

bash
# 1. Добавить новую камеру
echo "camera_003:
  source: rtsp://admin:password@192.168.1.103:554/stream
  sub: rtsp://admin:password@192.168.1.103:554/substream
" > conf.d/camera_003.yaml

# Конфигурация перезагружается автоматически, camera_003 начинает запись

# 2. Обновить источник камеры
# Редактируем conf.d/camera_002.yaml и сохраняем
# Камера автоматически перезапускается с новым источником

# 3. Удалить камеру
rm conf.d/camera_001.yaml
# Камера останавливается, стримы очищаются, больше не доступна

Управление стримами ​

При удалении камеры:

  • Запись останавливается корректно
  • RTSP клиенты отключаются
  • HLS мюксеры очищаются
  • Стрим становится недоступен (возвращает 404)
  • Перезапуск не требуется

Рестриминг ​

Подключение к камере через встроенный RTSP-сервер:

bash
# Формат
rtsp://localhost:{port}/{camera_id}

# Примеры
ffplay -rtsp_transport tcp rtsp://localhost:8554/front_door
vlc rtsp://localhost:8554/parking

Проверка конфигурации ​

ForgeVis валидирует конфигурацию при запуске:

bash
./forgevis config.yaml

Проверьте логи на ошибки:

  • Некорректный RTSP URL
  • Недоступные пути записи
  • Дублирующиеся camera_id
  • Некорректный формат YAML

Следующие шаги ​

Proprietary software.