README.md
May 31, 2026 · View on GitHub
Cams PWA

Простое веб приложение для непрерывной записи (видеорегистрации) и воспроизведения RTSP потоков с IP камер в реальном времени.
Работает на любых современных устройствах (компьютеры, смартфоны, планшеты) под управлением любой операционной системы (Windows, macOS, Linux, Android) с поддержкой Media Source Extensions.
Приложение позволяет подключить к каждой камере неограниченное количество клиентов с использованием единственного мультиплексора (ffmpeg), создающего крайне низкую нагрузку на сервер, и "нативное" воспроизведение видеопотока средствами HTML5.
При наличии аппаратного ускорения видео приложение поддерживает протокол H.265 (HEVC), который воспроизводится в браузерах на основе Chrome/Chromium не ниже 108 версии и в браузере Firefox не ниже 137 версии. Протокол H.264 воспроизводится во всех браузерах.
Возможности:
- Запись и воспроизведение изображения c любых IP камер, включая H.265+.
- Одновременный просмотр нескольких камер.
- Увеличение изображения.
- Ускоренное воспроизведение.
- Динамический детектор движения при воспроизведении записи или прямой трансляции с камеры для H.265+.
- Поддержка детектора движения средствами камеры.
- Оповещение о срабатывании детектора движения.
- Максимальная скорость подключения (на современных настольных компьютерах воспроизведение начинается мгновенно).
- Предельная простота навигации и управления.
- Полноценная работа с видеоархивами.
- Ярлык приложения можно создать для любой камеры или группы камер.
- Низкая нагрузка на сервер и клиентское устройство (транскодирование отсутствует).
- Автоматическое восстановление подключения к камерам после потери сигнала.
- Проксирование потоков с каждой камеры неограниченному количеству клиентов.
- Одно подключение к каждой камере независимо от числа клиентов.
Требования:
Серверная часть работает на Linux с установленными ffmpeg и python 3.9+ (без зависимостей).
Установка
Скопируйте файл конфигурации server/config-example.py в "приватный" файл server/_config.py и отредактируйте его, следуя комментариям.
После этого можно запустить скрипт
python3 server/main.py
и в браузере зайти на указанный адрес, например http://localhost:8000 (по умолчанию).
Автоматический запуск во время загрузки
Создайте юнит /etc/systemd/system/cams-pwa.service, например:
[Unit]
Description=CAMS video monitoring
After=network.target
[Service]
ExecStart=/usr/bin/python3 /<path-to-cams-pwa>/server/main.py
User=<www_user>
Group=<www_group>
[Install]
WantedBy=multi-user.target
Примечание: в этом примере служба запускается после того, как сетевому интерфейсу будет назначен IP адрес. Если в вашей системе работа сети контролируется иначе, измените значения параметров After и WantedBy.
Затем запустите службу:
sudo systemctl daemon-reload
sudo systemctl enable cams-pwa
sudo systemctl start cams-pwa
Доступ к камерам
Камеры и группы можно добавить в приложении с помощью соответствующих пунктов главного меню. Для доступа к каждой камере пользователю нужно указать её "ключ" (т.е. ключ словаря Config.cameras, заданный в файле конфигурации). Ключи защищены от случайной утечки через адресную строку браузера или ссылки Deep Link.
Такого ограничения вполне достаточно для работы в локальной сети. Но если вы хотите опубликовать приложение в интернете, в качестве меры усиления безопасности рекомендуется добавить дополнительную авторизацию, например базовую аутентификацию (Basic Auth) с помощью nginx.
SSL сертификат (необязательно)
Для работы PWA (прогрессивного веб приложения) требуется валидный SSL сертификат, который обеспечивает соединение по защищённому протоколу HTTPS.
Но в некоторых конфигурациях системы, например при проксировании через фронтенд-сервер nginx, приложение может работать по протоколу HTTP. В таком случае просто пропустите этот раздел и оставьте поля ssl в конфигурации пустыми.
Получить бесплатный сертификат можно в центре сертификации Let's Encrypt. Если вы не используете доменное имя или работаете в локальной сети, можно создать самозаверенный сертификат для IP-адресов, например так:
openssl req -x509 -nodes \
-newkey RSA:2048 \
-keyout .ca.key \
-days 3650 \
-out client.crt \
-subj '/CN=myCA'
openssl req -nodes \
-newkey RSA:2048 \
-keyout server.key \
-out .ca.csr \
-subj '/CN=camsPWA'
openssl x509 -req \
-CA client.crt \
-CAkey .ca.key \
-in .ca.csr \
-out server.crt \
-set_serial "0x$(openssl rand -hex 8)" \
-days 3650 \
-extfile <(printf "subjectAltName=DNS:localhost,IP:127.0.0.1,IP:ваш.ip.адрес\nauthorityKeyIdentifier=keyid,issuer\nbasicConstraints=CA:FALSE\nkeyUsage=digitalSignature, keyEncipherment\nextendedKeyUsage=serverAuth")
В этом случае корневой сертификат центра сертификации client.crt следует импортировать в браузер в разделе Менеджер сертификатов, а файлы server.crt и server.key скопировать в папку server и указать полные пути к ним в переменных ssl_certificate и ssl_private_key в файле server/_config.py.
На мобильных устройствах корневой сертификат импортируется в настройках безопасности системы.
Интерфейс

Экран просмотра камеры. Содержит следующие элементы управления:
- Кнопка "Назад".
- Кнопка "События" (опционально). Включает просмотр изображений, записанных детектором движения камеры.
- Кнопки "Перемотка назад".
- Кнопка "Пуск/Стоп".
- Кнопка "Ускоренное воспроизведение".
- Кнопка "Динамический детектор движения". Работает для протоколов с высокой степеню сжатия, например, H.265+.
- Кнопки "Перемотка вперед".
- Кнопка "Оповещение о движении" (опционально). Включает уведомления о срабатывании любого из настроенных детекторов движения.
- Ползунок шкалы времени. Точки на шкале соответствуют числу дней записи.
При прямой трансляции кнопки 5...7 неактивны.
Экран "События" дополнительно содержит диаграмму числа событий по дням, помогающую ориентироваться на шкале времени.
Детектор движения средствами камеры
Приложение поддерживает возможность записи событий, обнаруженных камерой. Ниже приведены настройки детектора движения на примере камеры Hikvision. Интерфейс и параметры настроек могут сильно отличаться в зависимости от производителя, но общая последовательность действий такова:
-
Включите детектор движения и настройте охранные зоны:

-
Выберите сохранение результатов на собственный сервер:

-
Включите "активацию захвата изображения по событию" (Event-Triggered Snapshot):

-
Настройте доступ к серверу:

В приведенном примере использован FTP сервер. Родительская папка camera_folder должна соответствовать настройке cameras[key][folder] в файле server/_config.py приложения, имя дочерней папки должно начинаться с любой буквы. Приложение обеспечивает ежедневную ротацию сохраненных камерой изображений. Доступ к этому архиву предоставляется на экране "События".
Внимание! При настройке FTP сервера настоятельно рекомендуется ограничить доступ пользователя ftp_user (режим chroot) одной папкой events_path (см. server/_config.py).
Пример использования

В этом примере служба cams-pwa установлена на локальном сервере с "серым" IP адресом. Для доступа к серверу через интернет может использоваться сервер с "белым" IP или "облако" KeenDNS. Для обслуживания внешних запросов на локальном сервере установлен туннель ssh -R. Использование фронтенд-сервера nginx не обязательно, но полезно для обслуживания статических файлов и для проксирования дополнительных заголовков, таких как запрашиваемое имя хоста или IP клиента.
Chromium в Linux
В зависимости от дистрибутива Linux, для включения аппаратного декодирования в Chromium и браузерах на его основе может потребоваться установка флага
--enable-features=AcceleratedVideoDecodeLinuxGL
или
--enable-features=VaapiVideoDecodeLinuxGL
Для постоянного включения флага можно, например, добавить этот аргумент в строку Exec в файле chromium.desktop.
Возможные проблемы
Если видео не воспроизводится на вашем компьютере, запишите короткий образец видео в файл и откройте его в браузере напрямую. Пример команды записи файла test.mp4 с оригинальным видеокодеком (-c:v copy) и отключённым звуком (-an) длительностью 4 секунды (-t 4):
ffmpeg -i rtsp://<адрес_камеры> -c:v copy -an -t 4 test.mp4
-
Если тестовый файл не воспроизводится, проблема на стороне браузера. В этом случае проверьте, включено ли в настройках браузера аппаратное ускорение графики и поддерживает ли его ваш компьютер. Убедитесь, что по адресу chrome://gpu/ в разделе "Video Acceleration Information" присутствуют строки вида "Decode hevc main". Если никакие действия не помогают, простым решением может быть переключение кодировки видеопотока на H.264 в настройках камеры.
-
Если файл воспроизводится в браузере, проверьте следующее:
- Верно ли указаны кодеки в поле "codecs" в файле конфигурации _config.py. Видео/аудио кодеки указываются в формате RFC 6381. Например, для видеокамер с поддержкой H.265 может сработать видеокодек "hev1.1.6.L120.0", для H.264 - "avc1.42001a". Для камер со звуком кодеки перечисляются через запятую, например "avc1.42001а, mp4a.40.2". Точное значение кодеков для записанного файла можно получить, например, командой MP4Box (входящей в пакет gpac):
MP4Box -info test.mp4 2>&1 | grep RFC6381 | awk '{print \$4}' | paste -sd , -
- Проверьте, совместимы ли указанные кодеки с вашим браузером. Поскольку приложение не декодирует изображение, а только передаёт данные в GPU, в качестве видеокодека можно указать любое совместимое значение (avc1.*, hev1.*). Проверить совместимость ваших кодеков можно, набрав во вкладке "консоль" в "инструментах разработчика" браузера команду MediaSource.isTypeSupported(), например:
MediaSource.isTypeSupported('video/mp4; codecs="avc1.42001а, mp4a.40.2"')
- Для камер со звуком проверьте, не блокируется ли воспроизведение звуковым каналом. В случае проблем с аудиопотоком можно либо записывать звук в кодировке AAC (параметр -c:a aac), либо отключить звук (параметр -an).
Подробнее о кодеках можно узнать, например, тут, а о работе Media Source Extensions — тут.
Дополнительные сведения
Подробное описание и обсуждение приложения: habr.com/ru/post/715016
Copyright (c) 2023-2025 vladpen under MIT license. Use it with absolutely no warranty.