Задержка RTSP 5-30 секунд: 7 причин и как сократить лаг до 1 сек
Видео с IP-камеры идёт с отставанием от реального времени на 5, 10, иногда 30 секунд. Разбираем семь источников задержки в цепочке «камера → сеть → плеер» и даём точные настройки для low-latency трансляции.
TL;DR — за 60 секунд
Нормальная задержка RTSP: 100-500 мс при прямом просмотре в VLC из локалки. 3-10 секунд при ретрансляции через HLS (что и происходит в браузере). Всё что больше 10 сек — лечится настройками.
Топ-3 причины «долгого» лага: большой GOP в камере (I-frame раз в 4-10 сек), H.265 без аппаратной поддержки у зрителя, агрессивный буфер плеера. Сократить до 1-2 сек можно только через WebRTC или LL-HLS — обычный HLS ниже 3 сек не опустится.
Какая задержка «нормальная» — сравнение протоколов
Прежде чем чинить — поймите, что лаг 5-10 секунд при HLS-просмотре в браузере это физическая особенность протокола, а не баг. Физика HLS: плеер нарезает поток на сегменты и буферизует их для защиты от дропов. Чем меньше сегмент — тем меньше задержка, но тем выше риск разрывов.
| Протокол | Задержка | Работает в браузере | Сложность настройки |
|---|---|---|---|
| RTSP (прямой в VLC) | 100-500 мс | Нет | ★☆☆ |
| WebRTC | 300 мс - 1 сек | Да (везде) | ★★★ |
| LL-HLS (Low-Latency HLS) | 2-3 сек | iOS 14+, Safari, hls.js | ★★☆ |
| HLS (стандартный) | 5-10 сек | Да (везде) | ★☆☆ |
| DASH (MPEG-DASH) | 6-12 сек | Да (через Shaka Player) | ★★☆ |
| RTMP (старый) | 1-3 сек | Нет (Flash умер) | ★☆☆ |
Вывод. Если вам нужна задержка меньше 3 сек в браузере — только WebRTC или LL-HLS. Стандартный HLS физически ограничен 5-10 секундами. Если лаг у вас больше 10 сек при HLS — это уже проблема в настройках, разбираемся ниже.
7 причин задержки и как их исправить
1Большой GOP (key frame interval) в камере
Симптом: видео начинается с задержкой 3-8 сек после открытия ссылки, потом идёт нормально.
GOP — интервал между I-frame (полный кадр, который можно декодировать самостоятельно). P-frame и B-frame между ними хранят только разницу. Плеер не может стартовать с середины GOP — ждёт ближайший I-frame. При GOP=120 на 30fps камера выдаёт I-frame раз в 4 секунды — плеер может прождать до 4 сек прежде чем начать показ.
2H.265 без аппаратного декодера у зрителя
Симптом: на одном устройстве задержка 1 сек, на другом (Android/старый ПК) — 5-10 сек.
H.265 (HEVC) в 2 раза компактнее H.264 при том же качестве, но его аппаратное декодирование появилось только в процессорах Intel с 7-го поколения (2017), AMD с Ryzen, Apple A10+. Старые чипы декодируют программно — с задержкой 1-3 сек на каждый кадр.
3Агрессивный network caching в плеере
Симптом: VLC показывает стабильное видео, но всегда на 1-2 сек позади ping.
VLC по умолчанию кеширует 1000 мс RTP-пакетов перед показом — это защита от jitter в сети. Но если сеть стабильная, кеш избыточен.
--network-caching=100 или через GUI: Инструменты → Настройки → Ввод/кодеки → Сетевое кэширование (мс) = 100-200. Осторожно: на нестабильном канале (Wi-Fi, 4G) это даст подрывы. Для LAN — работает идеально.4UDP с потерями → плеер ждёт ретрансмиссию
Симптом: задержка скачет от 0.5 до 5 секунд, иногда с мозаикой.
RTSP по умолчанию гоняет видео через RTP/UDP. UDP не гарантирует доставку, но и не ждёт подтверждений — это быстро в идеальной сети. Но если 3-5% пакетов теряется, плеер либо показывает мозаику, либо тормозит в попытке собрать целый I-frame.
5HLS-сегменты слишком длинные
Симптом: через MediaMTX или RTSP.KZ задержка стабильно 6-10 сек, не зависит от настроек камеры.
Стандартный HLS режет поток на сегменты. При длине сегмента 2 сек плеер буферизует 3 сегмента = 6 сек. При длине 4 сек — уже 12 сек. И это не считая времени нарезки и upload'а на CDN.
mediamtx.yml:
# low-latency HLS hlsSegmentDuration: 1s hlsPartDuration: 200ms hlsSegmentCount: 3 hlsVariant: lowLatency # убираем overhead на транскодинг rtspTransport: tcpЭто включает LL-HLS. Работает в Safari iOS 14+, через hls.js — в Chrome/Firefox. Типичная задержка — 2-3 секунды.
6Плеер в браузере накапливает буфер
Симптом: первые 30 секунд всё ок, потом задержка растёт до 15-20 сек.
Это классический bufferbloat на стороне плеера. Если плеер загружает сегменты быстрее чем проигрывает (из-за burst-канала), буфер растёт. Через час задержка может дойти до минут.
liveSyncDurationCount: 1 и maxLiveSyncPlaybackRate: 1.5 — плеер будет ускоряться на 50% при отклонении от live. В video-элементе: <video autoplay muted playsinline>. Без muted Chrome не даст autoplay — и буфер начнёт накапливаться без воспроизведения.7Недостаточный CPU на ретрансляторе
Симптом: у одной камеры лаг 2 сек, у пяти — 15 сек.
Если MediaMTX крутится на домашнем ПК или слабом VPS (1 vCPU), транскодирование 5 FHD-потоков съедает 100% CPU. Каждый кадр задерживается в очереди планировщика.
rtspSource: passThrough — HLS-нарезка работает на «сыром» потоке без перекодирования. При transcode: 1 vCPU = 1-2 FHD потока. Для 10+ камер нужен 4-8 vCPU сервер. У RTSP.KZ эта проблема решена в архитектуре — поток идёт через выделенный ретранслятор с горизонтальным масштабированием.Low-latency конфигурация — пример mediamtx.yml
Рабочий конфиг для MediaMTX, задержка ~2 сек от камеры до браузера:
### mediamtx.yml — конфиг для low-latency HLS ### logLevel: info rtspTransport: tcp # HLS с LL-HLS (iOS 14+, hls.js в Chrome/Firefox) hlsVariant: lowLatency hlsSegmentDuration: 1s hlsPartDuration: 200ms hlsSegmentCount: 3 hlsAllowOrigin: '*' # WebRTC — для ультра-низкой задержки (0.3-1 сек) webrtc: yes webrtcICEServers2: - url: stun:stun.l.google.com:19302 # сам источник — без транскодинга paths: cam1: source: rtsp://admin:pass@192.168.1.64:554/Streaming/Channels/101 sourceOnDemand: no runOnReady: '' # НЕ делать transcode, просто проксируем
Проверка задержки в браузере:
# открываем http://SERVER:8888/cam1/index.m3u8 в браузере # смотрим задержку относительно камеры (стоп-кадр с часами) # для WebRTC: # http://SERVER:8889/cam1 — встроенный WebRTC-плеер MediaMTX
Автосалон в Астане: снизили задержку с 12 до 2 секунд
Ситуация. Автосалон премиум-марки в Астане, ТРЦ Mega Silk Way. Установлены 4 камеры Dahua IPC-HFW2431S в шоуруме для трансляции онлайн-показов клиентам. Использовали собственный MediaMTX на Windows-ПК с дефолтным конфигом. Задержка до браузера посетителя на сайте — 12-15 секунд. Менеджер показывает машину клиенту по видеосвязи, клиент говорит «откройте капот» — через 15 сек менеджер видит команду, ещё 15 — клиент видит реакцию. 30 секунд на каждое действие — неприемлемо.
Диагностика. Открыли mediamtx.yml — стандартные настройки: сегменты 2 сек, buffer count 7, без LL-HLS. В камерах GOP=150 (I-frame раз в 5 сек при 30fps). HLS → Chrome через hls.js с дефолтным live sync.
Решение. Три шага:
- В камерах Dahua сменили I Frame Interval = 30 (битрейт вырос с 2 до 2.5 Мбит/с — некритично).
- В MediaMTX перешли на LL-HLS: сегменты 1 сек, parts 200 мс, count 3.
- В hls.js:
liveSyncDurationCount: 1, maxLiveSyncPlaybackRate: 1.5.
Результат. Задержка упала с 12-15 до 2-3 секунд. Для 4 камер этого хватает. CPU нагрузка на MediaMTX — 8%. Вариант с WebRTC давал бы 0.5 сек, но салон не хотел возиться с TURN-серверами. Стоимость изменений — 2 часа работы специалиста, 0 ₸ инфраструктуры.
4 ошибки которые НЕ уменьшат задержку
RTSP.KZ — готовый ретранслятор с LL-HLS
Задержка 2-4 секунды в браузере из коробки. Поддержка RTSP, WebRTC, LL-HLS. Не нужно поднимать MediaMTX — всё работает из облака. 1 час бесплатно без регистрации.
Попробовать →FAQ — 7 вопросов о задержке RTSP
При прямом просмотре в VLC из локалки — 100-500 мс. Через HLS в браузере — 5-10 секунд (физика протокола). LL-HLS снижает до 2-3 сек, WebRTC — до 0.3-1 сек. Для онлайн-наблюдения комфортна задержка до 5 сек, для охраны с реагированием — до 2.
HLS-плеер буферизует 2-3 сегмента перед воспроизведением. При сегментах по 2 секунды буфер = 6 сек. Плюс задержка нарезки и загрузки. Итого 6-10 сек. LL-HLS (iOS 14+) снижает до 2-3 за счёт Part-запросов (HTTP chunks вместо полных сегментов).
В mediamtx.yml: hlsVariant: lowLatency, hlsSegmentDuration: 1s, hlsPartDuration: 200ms, hlsSegmentCount: 3. В камере — GOP = FPS (I-frame каждую секунду), H.264 baseline. Ретранслятор не должен транскодить (используйте sourceOnDemand: no с копированием потока).
Android 6-10 часто не имеет аппаратного H.265-декодера на SoC MediaTek/Spreadtrum. Программное декодирование работает с задержкой 1-3 секунды. Решение: переключите камеру на H.264 baseline, используйте sub-stream (меньше разрешение = меньше работа). На Android 11+ с чипами Snapdragon 8xx, Exynos 2xxx проблем нет.
UDP быстрее в идеальной сети — нет подтверждений. Но при потере пакетов кадр ломается, плеер ждёт следующий I-frame. TCP медленнее на 50-100 мс, но гарантирует доставку. Правило: LAN/стабильный Wi-Fi = UDP, мобильный 4G/слабый Wi-Fi = TCP. В VLC переключается в Настройки → Ввод/кодеки → RTP → RTP поверх RTSP.
GOP (Group of Pictures) — интервал между I-frame. Плеер не стартует с P-кадра, ждёт ближайший I-frame. При GOP=60 на 30fps I-frame раз в 2 сек → плеер может прождать до 2 сек перед показом. Для low-latency GOP = FPS (I-frame каждую секунду). Плата — битрейт растёт на 15-25%.
Плеер буферизует пакеты быстрее чем воспроизводит (burst-канал). Через 30 мин задержка может дойти до 10-20 сек. Решение: в hls.js установите maxLiveSyncPlaybackRate: 1.5 — плеер будет ускоряться при отклонении от live. В VLC: --network-caching=100. В MediaMTX — меньший hlsSegmentMaxSize.