Да будет запись в mp4
Я начал замечать открытые щитки у себя на этаже, в голове пронеслись мысли про favourite guys в поисках запрещённых ресурсов, потому решил озаботиться круглосуточным видеонаблюдением лестничной площадки.
Заказал на Али недорогую рыбоглазую камеру и влепил её под потолок прямо над щитком. Но мой бюджет был ограничен, а в тумбочке лежит несколько неиспользуемых Андройд телефонов, их то я и решил применить в качестве NVR устройства, вместо покупки такового. А ещё телефоны меньше жрут и совсем не шумят, в отличие от хардварных версий записывающих устройств. Встроенной карты памяти на камере нет, поэтому нужно внешнее устройство.
Загуглил, попробовал несколько программ и остановился на одной из них, которая выглядела как самая зрелая, с большим количеством функций, да ещё и платной версией. Платную версию конечно же купить у нас нельзя, но скачать её патченную сестру с 4pda можно, что я и сделал. Алексей (автор), прости, но другого варианта у меня не было.
Какие у неё функции достоинства:
поддержка большого числа вендоров камер, в том числе ноу‑нейм с поддержкой голого протокола ONVIF и RTSP
поддержка сразу нескольких подключённых камер
запись по движению или по попаданию в кадр человека
запись на локальную карту, FTP, DropBox, ownCloud\NextCloud
уведомление в группу Телеграмм
встроенный веб сервер для доступа к логам, просмотру записей, простые метрики и простые настройки
поддержка протоколов H.264 и H.265
фоновый режим работы — программу можно свернуть, но она продолжит мониторить и писать по движению
выбор из нескольких muxer для компоновки видео
Я попробовал поставить программу на планшет, его же хотел повесить на стену в качестве монитора у двери — было бы удобно. Планшет Teclast P40HD 6 Gb с процессором Unisoc T606 (8-ядерный (2 x Cortex‑A75, 6 x Cortex‑A55) 1,6 ГГц) не потянул, программу просто выбивало на старте. Ок, подумал я, и расчехлил Asus Zenfone 8 (Snapdragon 888 — 8 ядер). Программа запустилась, изображение пошло, детекция движения есть. Но есть и одно но! Даже не так, а НО! Вероятно, алгоритм детекции движения использует ML, а тот в свою очередь на 100% утилизует процессор, да так, что под его нагревом при записи пропадают кадры, много кадров выпадает из записи. Уф, подумал я, никуда это не годится.
Недостатки использованной программы:
неоптимизированный алгоритм обнаружения движения и лиц (людей) в кадре, требующий очень серьёзного железа. Анализ идет на основном потоке с максимальным разрешением, а можно было бы сделать на субпотоке - его вполне достаточно для такой задачи.
запись с пропадаем кадров, а заявленный режим прямой записи H.264 потока в файл без необходимости декодирования не работает
не записывает звук. Точнее родной андройдовский муксер не пишет звук, а другие пишут звук, но сильно обрезают качество картинки.
Андройдовский же муксер наоборот, привирал в качестве. Если сравнить запись, сделанную с помощь ffmpeg, то размер с андройда сильно больше, но качество картинки не лучше.
не умеет в ftps протокол
Ну что же, я без работы (кстати, если у кого‑то есть работа c#/js лидом — напишите, пожалуйста), люблю программировать, почему бы нам (мне и моей тревожности ИИ) не сделать самим такую программу, подумал я, и помчали.
Как все было
Далее 14 абзацев потока воспоминаний и эмоций от разработки в паре с ИИ, их можно пропустить и перейти к вызовам и выводам.
Из темы видеонаблюдения я знаю примерно ничего, уверенно владею c# и несколько раз видел код для Android. А еще это повод попрактиковаться в использовании ИИ. Выбрал DeepSeek, он работает в РФ без ВПН, он очень дёшев, и в целом меня удовлетворяет качество ответов, модель DeepSeek V4 Pro. В качестве агента — Zed, как раз не так давно его здесь же хвалили, основной редактор — Visual Studio. Пробуем, что получится.
Начинаю общаться в чате (в веб версии, чтобы не тратить платные токены) с ИИ, спрашиваю про протокол ONIF, узнаю про протокол вещания RTSP, спрашиваю как на c# с ними работать. Первый ответ есть — библиотека SharpRtsp. Создаю проект, библиотека и консольный клиент, чтобы проверять гипотезы.
Итак, поток с камеры получаю, голые NAL юниты вижу. Дипсик помогает разобраться в видах и тапах юинов, чем отличается H.264 от H.265. Пробую делать запись. Нахожу библиотеку SharpMP4 того же автора, делаю тестовую запись, пока тоже без звука — картинка есть. ИИ делает код кольцевого буфера, который должен хранить n последних секунд вещания, чтобы запись начиналась не с момента движения, а за эти n секунд до неё. Качество удовлетворяет.
Двигаемся дальше. Никакой архитектуры, код лапша, но мы же проверяем гипотезы. Главный вопрос — а как обнаруживать движение? В голове взрослый вариант — нужно с помощью ML анализировать кадры, расшифрованное из потока изображение. Но я хочу использовать для этого не самый крутой телефон, в ходе инвентаризации мой выбор пал на Sharp Aquos 2 (Snapdragon 630, 4 ядра Cortex‑A53 на 2200 МГц и 4 ядра Cortex‑A53 на 1800 МГц., 4 Гб ОЗУ).
Прошу ИИ написать код анализатора на основе сырых NAL юнитов. Первый значимый код от ИИ в проект готов. Проверяю — много ложно‑положительных и ложно‑отрицательных детекций. Скармливаю логи, он анализирует, переписывает код. Снова не то. Ещё итерация. Опять нет. Голова уже не варит, не понимаю что он делает, просто мешанина какого-то кода, нужно сделать перерыв.
Пробую ещё и прихожу к выводу, что камера слишком шумит, сделать такой анализатор не получится. Торг прошёл, депрессия, принятие. Нужно анализировать изображение. Но как с этим справится телефон? И тут мне приходит осознание. Та программа использовала для анализа изображение с основного потока в полные 4К, но ведь камера шлёт ещё один дополнительный поток 640×480, этого вполне достаточно, чтобы распознать движение. Осталось только маленькая проблема — а где взять это изображение. Нашли библиотеку для декодирования H264 потока в изображения.
ИИ пишет анализатор на основе разбиения изображения на квадраты и сравнения средней яркости области. Первый же тест — восхищение, работает. Есть вопросы к коду, прошу сделать правки — стало сильно лучше.
Пора делать графический интерфейс. Выбираю .Net MAUI, кроссплатформенный интерфейс из коробки. ИИ пишет интерфейс, основное окно, окно просмотра логов и настроек. Я в восторге, я бы руками это несколько дней делал. На Windows все работает хорошо, запускаю на Sharp S2 — тормоза, на Asus со скрипом. Чешем затылки. MAUI тормоз из коробки, выкидываем, заменяем на Mono for Android. Вторая проблема — сам алгоритм. На i7 один кадр анализируется 4 мс, на Sharp S2 >100 мс. ИИ предлагает сделать правки, делает. Стало несколько лучше, но не на много. Поток идёт в 15 fps, а это 15 кадров в 1000 мс, тоесть 66 мс на кадр. Кровь из носа, но нужно уложиться в это ограничение, иначе ничего не выйдет.
Тут ИИ начал тупить и делать херню. Случился забавный момент, я придумал решение, но не захотел ему полностью объяснять, а по шагам реализовать, но эта тварь отказывалась! — «я не думаю, что этот код будет лучше и быстрее, оставляю все как есть, мой вариант вам подходит больше». Я был в ярости, выругался на него матом, он согласился наконец и сделал. Я допилил код руками, попросил его перечитать файл и оценить правки. «Красиво!». Красиво, красиво — была его оценка и ответ. Меня похвалил ИИ. Я не знаю что чувствовать. На Sharp S2 оценка одного кадра занимает около 40 мс, на i7 — 1 мс.
Ещё некоторое время мы допиливали приложение, научились декодировать звук из камерного протокола G711A в ААС, записывать это в mp4 поток. Пробовали стандартный muxer от Anrdoid, но как я говорил, он с качеством очень портачит, вернулся на SharpMP4. Храни, Макаронный Монстр, опенсурс!
Последним промтом было задание заполнить файл Readme.md, в том числе записать цели и задачи проекта, которые я, естественно ИИ не говорил.
Цель: создать лёгкое, автономное решение для круглосуточной записи с IP-камер по RTSP, которое.... Работает на слабых устройствах (Android-приставки, одноплатники, Raspberry Pi) без GPU.
Задача: заменить громоздкие NVR-системы простым .NET-приложением, которое можно запустить на любом Android-устройстве или Windows-машине.
Все это ИИ понял сам исходя из нашего с ним трёх недельного общения и успешно использовал в выводах, при этом, акцент жирным на словах "слабых устройствах" он сделал сам.
Какой вызов я решил
Самым сложным, конечно же, было создание детектора движения. Изначально по моему настоянию ИИ предложил анализировать I юниты. Это такие юниты в потоке вещания, которые передают изменение картинки по сравнению с предыдущим состоянием. Косвенно, по размеру юнита по сравнению с предыдущими и по его содержимому (много хаотичных нулей и единиц) можно понять, что на кадре присутствует движение. Метод оказался ненадёжным, т.к. моя камера слишком шумит.
Вторым решением стало декодирование второго, субпотока, разрешением 640x480 пикселей в изображения и анализ уже именно изображений. ИИ применил метод сравнения средней яркости блока, и это заработало. Мы долго обсуждали и выверяли с ним этот код, самым правильным и надёжным методом является использование медиан, но это очень тяжёлый алгоритм, телефону не хватает мощности его обрабатывать в отведённое время. Мы перешли на использование скользящего среднего (EMA), но тогда появилась проблема с ложным срабатываем в моменты включения и отключения освещения в подъезде, что было решено добавлением фильтра на всплески яркости. Код анализатора из красивого SOLID ООП превратился в C-лапшу с глобальными переменными ради оптимизации под запуск на слабых устройствах, но цель была достигнута - 40 мс на анализ кадра на старом телефоне, что меньше критического значения в 66 мс на кадр при 15 fps.
Детектором движения я полностью доволен. В камере есть свой детектор, он способен при обнаружении движения отправлять уведомление по протоколу Alarm. Работает это так: при возникновении движения отправляет json с сообщением «движение появилось», при окончании — «движение пропало», промежуточных keepalive не предусмотрено, поэтому я побоялся использовать его как основной источник, потому что не понимаю, как обрабатывать ситуацию, если по какой‑то причине потеряется сообщение об окончании. ОПЭ нескольких дней показала, что мой и встроенный детектор работают совершенно синхронно, ну кроме того, что я исключаю ложные срабатывания на включение и выключение освещения в подъезде, а камера нет.
Что умеет программа
работа только с протоколом сжатия видео H.265
анализ потока с камеры на наличие движения
запись видео при наличии движения, n секунд до начала движения и m после, все хранится в настройках
запись звука
наличие встроенного простого веб сервера
m3u плейлист для воспроизведения последних записей за 24 часа на vlc плеере
Что не умеет
нет поддержки H.264
пока нет ротации файлов (хранить не более n дней и\или m мб)
только одна камера, т.к. у меня одна. Может быть сделаю поддержку большего количества камер чисто ради спортивного интереса
нет фонового режима, приложение должно быть всегда запущено. Наверное можно и свернуть, но нужно подкрутить настройки телефона, чтобы ради экономии батареи он не убивал неактивные процессы
настройки чувствительности анализатора пока зашиты в код, наверное нужно вынести в настройки приложения
аутентификации у веб сервера нет, пока не планирую открывать к нему доступ из интернета
не умеет управлять движением камеры (PTZ), т.к. у меня камера статичная
нет пресетов по настройке изображений. Ума не приложу, как этим можно и зачем пользоваться
Вместо выводов
За три недели и примерно 40 часов чистого времени я сделал для себя приложение в незнакомом стеке (под Андройд), которое без ИИ даже не осмелился бы начать.
ИИ делал каркасы, писал MVP код, а потом доводил его до ума, делал ошибки и сам же их потом правил.
ИИ — это очень сильный помощник для разработчика. Как оценить его уровень, что это такое? С одной стороны, ИИ сильно умнее меня, его кругозор и набор инженерных практик, собранных с миллионов других разработчиков, превосходит тысячекратно мои возможности. С другой стороны, он ленивый и льстивый, если его не просить делать хорошо, он будет делать на отвали, как попало, лишь бы работало, соглашается почти со всем, что я ему говорю и сознательно (иронично, да?) допускает ошибки, создаёт технический долг. Я не использовал субагентов, у меня даже нет agent.md файла, личность ИИ уже на столько хороша, что нет никакой надобности давать ему ещё какие‑то дополнительные инструкции.
Я понимаю как тим лид, почему все увольняют разработчиков и почему мы становимся все меньше и меньше нужны. Мне не потребовалось три мидла и два жуна, чтобы сделать это приложение, они бы делали его куда дольше. Тем не мнее, не надо питать иллюзий, что средне статистический менеджер сможет написать программу сам с помощью ИИ без привлечения специалистов по разработке. Все демо кейсы с туду листами вызывают эйфорию, но в реальности же сделать качественно приложение с соблюдением всех нефункциональных требований, и даже функциональных, без создания дыр в безопасности и тонн техдолга, вряд ли под силу своре агентов, для работы с этим инструментом нужен инженер, который понимает в технологиях.
Ну и ссылка на репозитарий https://github.com/for7raid/RtspCameraRecorder
Дисклеймер. Проект писался почти полностью с помощью ИИ, однако данная статья принципиально написана только белково-жировой массой с извилинами, даже редактуру не делал, а все длинные тире ставит встроенный в хаброредактор типограф.
Всем бобра и макарошек с тефтельками.
P. S. За постоянно подключённый аккумулятор к сети не беспокоюсь. Видимо зависит от качества электроники, на стене сменил уже три планшета (ранее была погода и часы, но с закрытием Я.Погоды своего АПИ теперь только часы, ну то есть в прямом смысле работает как часы) и только у одного вздулся аккум через 2 или 3 года работы. Даже если это и произойдёт с телефоном, жалко уже не будет, заменю другим, а этого малыша с почестями провожу на покой — своё он уже с избытком мне отдаст.

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

x89377
29.05.2026 14:08Загрузил, установил. Белый экран. Жаль.
Андроид 12

for7raid Автор
29.05.2026 14:08Так, а камеру в настройках прописал? Там нужен полный путь до видеопотока, проверит его можно в vlc

JDJ
29.05.2026 14:08аналогично, планшет хонор перед установкой ругнулся что приложеине представляет опасность, но я поставил так как планшет для тестов, белый экран

for7raid Автор
29.05.2026 14:08А была эмблема .net в синем кружке при запуске?

JDJ
29.05.2026 14:08нет, при запуске сразу белый экран

for7raid Автор
29.05.2026 14:08сбилдил новую версию, 1.0.1, попробуй еще раз, пожалуйста.

JDJ
29.05.2026 14:08вот чё в логах андроид студио по вашему пакету
--------- beginning of main 2026-05-29 23:43:17.355 1324-1334 cutils installd E Go to create: /data/data/ru.for7raid.CCTVRecorder 2026-05-29 23:43:17.359 1324-1334 cutils installd E Go to create: /data/user_de/0/ru.for7raid.CCTVRecorder 2026-05-29 23:43:17.363 568-568 vold vold E /data/media/0/Android/obb/ru.for7raid.CCTVRecorder not exist, return directly. 2026-05-29 23:43:17.641 1350-1398 AwareLog hwpged E iawared: WorkingsetPathCheckInternal Failed to lstat(/data/system/iaware/workingset/ru.for7raid.CCTVRecorder/): 2 2026-05-29 23:43:17.641 1350-1398 AwareLog hwpged E iawared: WorkingsetPathCheck Failed to delete directory(/data/system/iaware/workingset/ru.for7raid.CCTVRecorder/): 2 2026-05-29 23:43:17.811 1676-1800 VerityUtils system_server E Failed to measure fs-verity, errno 1: /data/app/~~cy3ajOeAe27MjF-0vlykvw==/ru.for7raid.CCTVRecorder-_ThXV683bnBioiv8uIOivA==/base.apk 2026-05-29 23:43:17.891 7198-7239 GCLog com.hihonor.gamecenter E ║ DownloadReportAspect: downloadInfo dismiss:DownloadTransfer(pkgVerName='ru.for7raid.CCTVRecorder_1', progress=0, state=301, speed=0.0 ,errorCode= ,externalId= ,curSize=0 ,controlType=-1) (:22) 2026-05-29 23:43:18.142 1676-1800 VerityUtils system_server E Failed to measure fs-verity, errno 1: /data/app/~~cy3ajOeAe27MjF-0vlykvw==/ru.for7raid.CCTVRecorder-_ThXV683bnBioiv8uIOivA==/base.apk 2026-05-29 23:43:18.186 7085-7085 AMLog[1aad66cfe6] com.hihonor.appmarket E InstalledAppDataMgr the installed app list is not initial yet. it's useless to update! before addedLeftList.add(ru.for7raid.CCTVRecorder) :addedLeftList before size:0 2026-05-29 23:43:18.187 7085-7085 AMLog[1aad66cfe6] com.hihonor.appmarket E InstalledAppDataMgr the installed app list is not initial yet. it's useless to update! after addedLeftList.add(ru.for7raid.CCTVRecorder) :addedLeftList after size:1 2026-05-29 23:43:18.193 7085-7085 AMLog[1aad66cfe6] com.hihonor.appmarket E InstalledAppDataMgr the installed app list is not initial yet. it's useless to update! addedLeftList.contains(ru.for7raid.CCTVRecorder) : addedLeftList size:1 2026-05-29 23:43:19.284 9190-9202 BehaviorCollectManager ru.for7raid.CCTVRecorder E Fail to acquire dataAnalyzerService... 2026-05-29 23:43:19.300 9190-9209 AwareLog ru.for7raid.CCTVRecorder E AtomicFileUtils: readFileLines file not exist: android.util.AtomicFile@56ce430 2026-05-29 23:43:20.135 9190-9190 HwResourcesImpl ru.for7raid.CCTVRecorder E handleAddIconBackground resId = 0 return: android.graphics.drawable.ColorDrawable@801a084но хорошая новость, теперь на белом экране есть логотип :)
вот ещё такая летит сразу перед вашим пакетом, при запуске2026-05-29 23:49:16.970 1676-2497 TaskChange...Controller system_server E forAllLocalListeners pid must be equal, but the callingPid 10163 pid 1676 java.lang.Exception at com.android.server.wm.TaskChangeNotificationController.forAllLocalListeners(TaskChangeNotificationController.java:347) at com.android.server.wm.TaskChangeNotificationController.notifyTaskDescriptionChanged(TaskChangeNotificationController.java:468) at com.android.server.wm.Task.updateTaskDescription(Task.java:2595) at com.android.server.wm.ActivityRecord.setTaskDescription(ActivityRecord.java:7208) at com.android.server.wm.ActivityClientController.setTaskDescription(ActivityClientController.java:1192) at android.app.IActivityClientController$Stub.onTransact(IActivityClientController.java:943) at com.android.server.wm.ActivityClientController.onTransact(ActivityClientController.java:167) at android.os.Binder.execTransactInternal(Binder.java:1186) at android.os.Binder.execTransact(Binder.java:1150) 2026-05-29 23:49:16.985 10163-10163 HwResourcesImpl ru.for7raid.CCTVRecorder E handleAddIconBackground resId = 0 return: android.graphics.drawable.ColorDrawable@801a084

Markscheider
29.05.2026 14:08А посоветуйте аналогичное под убунту серверную, плз.
Цель простая: получать видео по rtsp с пары камер и просто складывать на жесткий диск.
Сейчас сижу на бесплатной версии Xeova - вещь хорошая, но настраивается только через gui.

JDJ
29.05.2026 14:08хотел написать автору, напишу вам, есть же ip камеры которые льют сами на ftp, дахуа например, у меня 5 штук таких сами всё делают
MEGA_Nexus
Так и кто в итоге это был? Прочил начало статьи, а дальше уже бегло пробежался по реализации, но так и не увидел, удалось поймать виновника или нет?
JDJ
монтажники интернета провода тянут
for7raid Автор
Если так - они чудаки на букву м, раз не могут за собой нормально шкаф закрыть. Правда это не объясняет почему так же постоянно было открыт пожарный шкаф, а шланг из него пропал.
for7raid Автор
Пока нет. В тот день, когда камеру ставил, два типа тёрлись между этажами. По камере за три недели эксплуатации увидел одного странного мужика гуляющего по лестнице туда сюда. Узнал кто курит у лифтов. А вот закладок не нашёл. Но я несколько ранее поставил замки на щитки и преждевременно повесил наклейку с камерой, даже когда ее ещё не было.