Как мы наступили на те же грабли
Как мы наступили на те же грабли

Пять лет назад на Хабре мы писали о Web Camera Pro — и казалось, что впереди только апдейты, оптимизации и новые функции. За это время изменилось многое — и не только в технологиях, но и в законодательстве.

Как мы наступили на те же грабли

Когда в 2015 году мы начинали разработку Web Camera Pro, Qt 5 казался идеальным решением. На первый взгляд всё выглядело просто: берём готовые библиотеки, оборачиваем в красивый интерфейс, добавляем AI-аналитику — и готово.

На Qt было создано множество известных программ для видеонаблюдения, и мы — как и десятки команд по всему миру, поверили в его универсальность.
“Один фреймворк, любая платформа” — звучало как музыка.

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

Qt позволял быстро собрать прототип, но, когда речь заходила о стабильности, о 24/7-нагрузке, о реальной работе с потоками и камерами, его недостатки становились критичны.

Многие баги жили глубоко внутри системных библиотек и DLL-модулей Qt.
Исправить их было невозможно, а обойти — сложно. Мы столкнулись с тем же, что и сотни других разработчиков: вроде всё работает, но постепенно — вытекает память, камера “отваливается”.  Всё, что для VMS является “повседневной рутиной”, превращалось в лабиринт из костылей и багов. Сначала мы латали, потом переписывали, потом переписывали то, что переписали.

Qt изначально разрабатывался как GUI-фреймворк: окна, кнопки, виджеты, сигналы/слоты, кроссплатформенность. Модуль Qt Multimedia добавился позже, с целью “поддержать аудио/видео” (например, QMediaPlayer, QVideoWidget, VideoOutput). Но факт в том, что мультимедиа-часть — не ядро Qt, а скорее “дополнение”. 

У Qt Multimedia есть одно удивительно постоянное качество: она всегда делает что-то не так, как ты ожидал.

На Windows под капотом — WMF, на Linux — GStreamer, на macOS — AVFoundation. Звучит как кроссплатформенность, но на деле это три разных вселенные, три набора глюков и три способа всё сломать.

QMediaPlayer не дружит с RTSP. Поток может и запустится, но после обрыва шанс на реконнект — как в лотерее. Если поток повредился — всё, до перезапуска процесса он превращается в “зомби”. GPU-ускорение тоже ведёт себя по принципу “угадай карту”: на одной видеокарте — идеально, на другой — зелёный экран, на третьей — краш драйвера.

Синхронизация звука и видео между Qt и FFmpeg живёт своей жизнью: минут через двадцать воспроизведения они могут окончательно рассориться. А если попадётся поток с нестандартными H.264 NAL-структурами — Qt Multimedia просто падает, молча, без stacktrace, без шанса на объяснение.

И всё это — глубоко спрятано в DLL-файлах, закрытых от разработчика. Никакой отладки, никаких патчей. Просто смирись и живи с этим.

Qt гордится своим signal/slot-механизмом — и действительно, для GUI это удобно. Пока ты не решишь синхронно декодировать 30 видеопотоков. Тогда внезапно выясняется, что сигналы между потоками теряются, QTimer не срабатывает, если объект живёт не в “главном” QThread, а QObject вообще не переносится между потоками без приключений.

И вот ты стоишь перед фактом: в мире, где у тебя сотня камер и круглосуточная обработка, Qt требует, чтобы всё вертелось в одном потоке. Или — чтобы ты сам заново изобрёл синхронизацию сигналов, таймеров и очередей сообщений. Потому что Qt никогда не задумывался как основа для систем, где десятки видеопотоков работают параллельно, без сна и без пощады.

Поэтому пришлось почти сразу отказаться от QMediaPlayer, внедрить libVLC-обёртку и использовать Qt только как UI-рамку.

“Латать Qt” бессмысленно

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

Если смотреть вперёд, становится очевидно: медиа потоки утяжеляются - 4K, 8K, кодеки H.265 и H.266, десятки камер, интеграция с AI и распознаванием лиц, низкая задержка, аппаратное ускорение — всё это уже давно не про “графический интерфейс”. Здесь речь идёт об архитектуре, которая должна быть гибкой, модульной и масштабируемой, иначе система просто не выдержит темпа, с которым развивается видеотехнологический мир.

Как только в игру вступают много поточность, длительный аптайм, реконнекты, запись на диск и сетевые сбои — Qt Multimedia начинает сдавать позиции. Утечки памяти, рассинхрон звука и видео, внезапные подвисания интерфейса, “зелёный экран” — классика жанра. Особенно ярко это проявляется после реконнектов: компонент VideoOutput течёт как решето.  Проблема в том, что UI и видео в Qt связаны слишком тесно. Стоит обработчику чуть замедлиться — и весь интерфейс замирает. А когда система одновременно держит десятки потоков по 5 Мбит/с, Qt превращается в котёл с утечками памяти.

Какие подходы остаются для VMS (если Qt остаётся как UI)

  • libVLC: зрелый медиадвижок с кучей фильтров, быстрыми стартапами и нормальным hwdec. Минусы: своя экосистема плагинов и деплоя. Зато как проигрыватель — “тянет”.

  • libmpv: отличная картинка, гибкие графические фильтры, предсказуемое hwdec, зрелая интеграция в виджет. Придётся делать биндинги и думать про лицензии.

  • FFmpeg + собственный рендер — полный контроль над буферами, таймингами, реконнектами, zero-copy. Минус: вся ответственность на вас.

  • GStreamer-пайплайны — идеально для Linux и embedded, где важен детерминизм и минимальная задержка. Цена — сложность пайплайнов и чувствительность к версиям.

Во всех этих схемах Qt выполняет роль «оболочки»: QML, таймлайны, окна, оверлеи. Всё остальное — вне Qt.  В итоге мы переписывали обёртки для VLC и FFMPEG, внедряли watchdog для потоков, чистили буферы вручную.

VLC и FFmpeg в Qt: “нативности” нет — только костыли

Qt сам по себе не знает, что такое libVLC. Никаких “родных” виджетов не предусмотрено. Чтобы встроить VLC, нужно тянуть сторонние обёртки вроде VLC-Qt, прописывать пути к плагинам, следить за версиями или писать биндинги вручную. Дальше начинается цирк: несовпадения версий библиотек, проблемы с написанными много лет назад обертками.

QtAV, некогда популярная обёртка над FFmpeg, давно устарела. Её исключают из репозиториев, а проекты уходят на форки. Делать на ней новую систему — значит, закладывать техдолг уже на старте.

Qt5 никогда не использовал “родной” FFmpeg. Он взаимодействовал через адаптеры, а это значит: несовпадения версий, отсутствие поддержки современных кодеков вроде HEVC и VP9, и неожиданные баги в неожиданных местах.

Системные минусы Qt, о которых говорят шёпотом

QML (Scene Graph) — визуально красиво, особенно для анимированных интерфейсов. Но за каждую тень и градиент вы платите дополнительной загрузкой GPU и CPU. При решётке из 16 видеоокон сцена QML превращается в прожорливого монстра, который съедает ресурсы, предназначенные для декодера.

Многопоточность и синхронизация: Выносить видеопотоки из GUI-потока приходится всегда. Но из-за слоёв QML (Image, VideoOutput, текстуры, сцена) появляются дополнительные точки отказа при переключении источников на лету.

Деплой и размер: Qt обожает плагины и динамические библиотеки, тонкие настройки путей к плагинам и зависимостям. Добавьте мультимедиа, кодеки, QML — и вот уже дистрибутив весит больше чем Chrome.

Лицензирование: Qt (LGPL/GPL/коммерческая) + кодеки (патенты H.264/HEVC). Для коммерческого VMS это отдельный юридический трек. Запрет на использование Qt в России.  Как интересно продукты, написанные на Qt попадают в реестр отечественного софта в России?

Изменчивость API: переход Qt5→Qt6 сломал старые наработки, всегда танцы с бубнами и высокие трудозатраты при обновлении версии Qt.

Платформенные сюрпризы (Windows / Linux / macOS / ARM)

  • Windows: при WMF/DirectShow неодинаковая поддержка кодеков, нюансы с HDR, нестабильности с hwdec после спячки/смены GPU

  • Linux: GStreamer-бэкенд — отдельный мир плагинов и версий; FFmpeg-бэкенд сглаживает, но на ARM аппаратное ускорение — всё ещё поле экспериментов.

  • macOS: AVFoundation любит “своё”, экзотические контейнеры/кодеки — через FFmpeg; при этом вопросы с подписанием и деплоем сторонних библиотек добавляют рутину.

  • Сборки: чтобы “получить всё”, Qt Multimedia часто приходится пересобирать с нужным FFmpeg и опциями. Иначе — урезанный функционал или странные падения в бою.

Хотя история про VMS, полезно отметить один “похожий” кейс: редактор видео CapCut. Он сделан на Qt (QML + мультимедиа) и прекрасно работает для небольших таймлайнов. Но если нагрузки становятся серьёзными — длинные таймлайны, множество видеодорожек, декодирование H.265, эффектов — то начинают проявляться те же симптомы и ограничения: мультимедиа-подсистема не справляется с нагрузкой, GPU/CPU перегружаются, UI начинает “подтормаживать”.

Это показывает: даже не VMS, просто “видео + UI” — и уже Qt начинает буксовать. А в VMS такие нагрузки ещё масштабнее.

А теперь сравним CapCut с Adobe Premiere Pro:  Adobe Premiere Pro не трясётся над кроссплатформенностью — он пишет под Windows/macOS нативно, на низком уровне, через DirectX/Metal. В итоге аппаратное ускорение работает стабильно (NVDEC, QuickSync, CUDA), таймлайн не тормозит, потому что рендеринг UI и видео — разные потоки с отдельными GPU-контекстами, Поддержка кодеков и контейнеров — напрямую через встроенные движки Adobe Media Core, а не через случайный бэкенд Qt Multimedia.

Почему всё же Qt

Да, у Qt есть свои плюсы. Быстрая разработка интерфейсов, единый стек, готовые виджеты, мощный QML для кастомных UI. Это идеальный инструмент, если вы делаете кроссплатформенное приложение, где медиа не играет ключевую роль.

Стабильность важнее всего

После выхода Web Camera Pro мы провели опрос среди новых пользователей, которые хотели установить программу. Один из вопросов был «Какая основная проблема у существующих программ для видеонаблюдения?»

Мы ожидали услышать о сложных вещах — точности детекции движения, распознавании лиц и номеров, скорости интерфейса, нехватке аналитики, отсутствии облака или модных функций вроде трекинга объектов и анализа эмоций. Всё, как в фильмах про AI.

Но реальность оказалась куда прозаичнее. Более 50% респондентов ответили: «нестабильность», «камеры периодически отваливаются», «запись внезапно обрывается», «программа зависает или теряет архив» и т.п..

То есть большинство пользователей вовсе не требовали новых фич — они просто хотели, чтобы система работала стабильно. Чтобы камеры не исчезали, запись не прерывалась, а после перезагрузки всё продолжало работать.

В опросе приняли участие более тридцати тысяч человек, скачавших программу, и этот результат стал самым наглядным подтверждением: прежде чем делать «умнее», нужно сделать надёжнее.

Frankenstein под капотом

В ходе анализа мы обнаружили, что жалобы встречаются у пользователей многих популярных решений: камеры теряются, архив повреждается, поток “зависает”, аналитика перестаёт работать. Когда мы начали смотреть, как устроены другие продукты, стали видны одни и те же грабли: чужие библиотеки, устаревшие обёртки, патчи на патчи.

Корень проблемы — в самой архитектуре. Основа нестабильна, потому что собрана из сторонних библиотек, плагинов и обёрток. Фреймворки вроде Qt или GStreamer отлично подходят для демо и лабораторных экспериментов, но не для систем, которые должны круглосуточно переваривать десятки видеопотоков без перерыва.

VMS Системы видеонаблюдения
VMS Системы видеонаблюдения

Большинство open-source проектов, на которых строятся коммерческие VMS, сами по себе не отличаются надёжностью. Почему? Потому что они рождались стихийно: один энтузиаст написал обёртку, выложил исходники, другой что-то подправил, третий добавил свой код — и исчез. Кто-то зафиксировал баг, кто-то добавил фичу, никто не провёл ревизию. Так, из десятков кусочков, вырос код-Франкенштейн. На вид — живая система, внутри — набор заплаток. В итоге большинство VMS представляют собой красивые оболочки, скрывающие под капотом хаос из несовместимых модулей. И ломается всё, как назло, именно там, где пользователь этого меньше всего ожидает — в фундаменте.

Вывод, который перевернул подход к разработке

Индустрия VMS слишком увлеклась “интеллектом”, забыв про базовую надёжность.

Пока конкуренты добавляют нейросети и маркетинговые слоганы “AI inside”, пользователь сталкивается с простыми проблемами — зависания, потеря архива, фризы при потоках, утечки памяти. Именно после этого опроса мы окончательно решили отказаться от Qt и всего “наследия” старого движка. Если стабильность — главная боль рынка, значит, всё внимание нужно сосредоточить на архитектуре, управлении памятью, обработке потоков и реконнектах. Не “новые фичи ради рекламы”, а устойчивость 24/7.

Новые вызовы: не только код, но и закон

За эти годы правила игры изменились не только технически, но и юридически.
Появились законы 152-ФЗ и 572-ФЗ, которые чётко определили, что можно, а что нельзя при обработке персональных и биометрических данных. Использование облачных сервисов, особенно зарубежных, стало юридически рискованным.

572-ФЗ
572-ФЗ

Теперь недостаточно просто “записывать видео” — нужно строго соблюдать требования к хранению, обработке и локализации данных. Qt, как коммерческий зарубежный стек, внёс дополнительную неопределённость.

И, пожалуй, самое честное, что можно сказать: нам пришлось выбросить весь код в корзину и начать писать всё заново. Так мы с нуля начали разработку программы SmartVision.

Сайт программы для видеонаблюдения SmartVision

Продолжение следует ….

Комментарии (5)


  1. rukhi7
    06.11.2025 13:30

    Если стабильность — главная боль рынка, значит, всё внимание нужно сосредоточить на архитектуре, управлении памятью, обработке потоков и реконнектах. Не “новые фичи ради рекламы”, а устойчивость 24/7.

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


  1. udattsk
    06.11.2025 13:30

    Посмотрите мое libwui.org возможно то что вам нужно. По крайней мере, у меня 30+ потоков видео плиткой воспроизводятся без проблем на i5-3550, каждый декодер в отдельном треде, рендеринг однопоточный по таймеру. Для ресайза без фризов есть фликер буфер.
    Если интересно, попробую сделать демо приложение (native win / lin x64) для проигрывания видео файлов плиткой до 10x10. Изначально заточено под прием RTP стримов как раз.


    1. palexab
      06.11.2025 13:30

      Интересно!


    1. webcameracloud Автор
      06.11.2025 13:30

      Очень круто!


  1. Siemargl
    06.11.2025 13:30

    Интересно, зачем вам мультиплатформа?

    Ведь если продукт специфический или профессиональный, то платформа выбирается под продукт. Соответственно, лучше заточка и меньше проблем.