Что такое did камеры
Еще раз о видеонаблюдении, камерах, RTSP, onvif. И «велосипед»!
Non-Interleaved Mode.
RTSP устанавливает связь и передает в камеру информацию о том «куда слать» данные (UDP порты).
Пример общения RTSP
Запоминаем
Transport: RTP/AVP;unicast;destination=10.112.28.33;source=10.112.28.231;client_port=49501-49502;server_port=6970-6971
Interleaved Mode.
Разница с Non-Interleaved Mode в том что все пакеты будут сыпаться в этот же порт.
Пример:
Запоминаем
Transport: RTP/AVP/TCP;unicast;interleaved=0-1
Теперь смотрим что и как.
Камеры шлют видео и аудио в разные RTP потоки. 2n поток — данные, 2n+1 поток — RTCP.
На видео нам идет 0 и 1 канал, на аудио 2 и 3 канал.
Теперь смотрим
Transport: RTP/AVP;unicast;destination=10.112.28.33;source=10.112.28.231;client_port=49501-49502;server_port=6970-6971
Transport: RTP/AVP/TCP;unicast;interleaved=0-1
В первом случае указаны порты, во втором каналы.
С с Non-Interleaved Mode всё понятно. Просто RTP пакеты сыпятся в порты и их можно читать как то так:
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
s.receive(packet);
Проблемы начинаются с Interleaved mode.
По факту ни каких проблем быть не должно. По RFC мы ищем magic char «$», следующий байт — канал (он указывается в подключении 0-4 у нас) и 2 байта Length. Всего 4 байта.
Но есть не нормальные камеры. Например D-ling DCS-2103 «Досыпает» какие то данные после rtp пакета. frame дает размер 1448,
шлет 1448 фрейма, и после 827 байт какого то мусора. (Так делает Dlink DCS-2103 прошивка 1.00 и 1.20)
И такое у «них» происходит постоянно. Этим частенько страдают китайские камеры. Qihan (356) этим не страдали.
Кроме как пропускать этот мусор идей больше нет.
В RTP сыпятся полезные данные. При DESCRIBE RTSP возвращается SDP пакет
Примеры SDP (h264, mjpeg, mpeg4):
Прочитать про SDP
Так как мода была mjpeg и текущая на h264, то рассмотрим их.
С MJpeg всё предельно ясно. А вот с H264 начинаются различия в камерах.
Формат h264 состоит из блоков с NAL заголовками (7.4.1 NAL unit semantics).
Чтобы можно было декодировать h264 необходимо помимо данных самого h264 иметь данные SPS (Sequence parameter set) и PPS(Picture parameter set). Первый описывает последовательность, второй параметры картинки. Так как сам кодек h264 знаю очень плохо, то большего описания не будет. SPS имеет тип 7, PPS 8. Без них невозможно декодировать h264.
Самое интересное — Qihan шлет SPS и PPS прям в RTP пакетах, Dlink не шлет их в RTP пакетах. Но SPS и PPS шлется в SDP пакете в параметре sprop-parameter-sets в кодировке base64.
sprop-parameter-sets=Z2QAKK2EBUViuKxUdCAqKxXFYqOhAVFYrisVHQgKisVxWKjoQFRWK4rFR0ICorFcVio6ECSFITk8nyfk/k/J8nm5s00IEkKQnJ5Pk/J/J+T5PNzZprQCgDLSpAAAAwHgAAAu4YEAAPQkAABEqjve+F4RCNQ=,aO48sA==
Шлются они через запятую
Вариант декодирования.
Так как камеры 720p или 1080p, то в 1 RTP пакет ни jpeg фрейм, ни h264 фрейм не поместится, то они режутся на пакеты.
RTP Payload Format for JPEG-compressed Video
RTP Payload Format for H.264 Video
JPEG
RTP пакет содержит main JPEG header
а дальше может варьироваться от Type и Q
Для декодирования jpeg нужно знать или вычислить quantization tables.
В моих камерах quantization tables шли в стартовом пакете Jpeg, по этому они просто брались оттуда.
Все вычисления есть в RFC.
Последний пакет фрейма вычисляется по RTP header Marker bit. Если он 1, то это последний пакет фрейма.
Single NAL Unit Packet
Это как раз SPS и PPS. Type=7 или Type=8
Если фрейм h264 не влезает в RTP пакет (1448 байт), то фрейм режется на фрагменты. (5.8. Fragmentation Units (FUs))
Type = 28
Эти заголовки следуют сразу после RTP заголовка
Для декодера h264 NAL — нужная информация. Если идет фрагментация фрейма, то NAL нужно восстанавливать. (FU)
нужно взять первые 3 бита из FU indicator и слить их с 5 последними FU header.
Теперь самое главное — сохраняем поток.
Jpeg
NON_IDR_PICTURE — необходим для декодирования, «разделяем» фреймы. (h264) Тут нужно меня поправить, так как это просто «костыль» и обоснований пока нет. Просто работает.
Получается такой поток: 00000001 + SPS + 00000001 + PPS + 00000001 + NAL…
erlyvideo: 0,0,0,1 — это префикс AnnexB записи H264. Это не часть H264 NAL-юнита, а разделитель между юнитами.
ну и обработка «всего» этого
в 2х словах. Получаем RTSP Interleaved Frame (например Channel: 0x00, 1448 bytes), читаем 1448 байт, делаем writeRawToStream, полиморфизм делает свое дело.
Дальше это нужно обкатать.
Казалось бы что для поддержания потока RTSP нужно делать RTCP отчеты, но нет, всё оказалось проще
Dlink, Qihan, VLC просто «едят» GET_PARAMETER:
шлем его раз в 55 секунд и всё.
При простом просмотре генерируется m3u файл и кормится в VLC
4
При склеивании ffmpeg клеит, после запускается VLC
5
Программа нарезает поток на файлы, интервал задается в настройках
Что делает ffmpeg:
Клеит
«Нормализует» (просчитывает заголовки и т.д.)
На выходе куча файлов
6
По хорошему можно писать в любой OutputStream
Git hub
Дальнейшей жизни программы может и не быть. Возможно допишу когда нибудь RTP классы для звука. (так как увлекаюсь до сих пор SIP)
Ну и самое вкусное.
Есть стандарт видео наблюдения ONVIF
Есть профессиональные железки, которые с камерами работают только по нему.
Есть камеры, которые работают по нему (Qihan, он же Proline), а ссылки rtsp приходится гуглить.
Есть опенсорсный продукт Onvif device manager для управления подобными железяками.
Я же в программу добавил поддержку onvif без авторизации и с авторизацией.
7
Git hub
Если пройтись по ссылкам выше, то можно получить всю документацию по Onvif.
Ответ:
Дальнейшее общение по onvif без авторизации идет в этом же ключе.
А вот пример общения но уже с авторизацией
Т.е. нужно слать заголовок. (тестилось на D-link DCS-2103, остальные камеры без авторизации работали, китай).
и пароль (Password_Digest = Base64 ( SHA-1 ( nonce + created + password ) ))
Всё было сделано в образовательных целях. Если есть вопросы и вдруг понадобиться более подробное описание чего либо — пишите.
Надеюсь кому нибудь пригодится.
PS Не надо писать в комментариях про организацию на большую букву «I». Их Server использует SQLite, SSL, avcodec (ffmpeg), а в папке \Resources есть божественный файлик с названием camera_list.json, но моя наглость не позволила его прикрутить к своей программе 🙂 Но я не видел у них поддержку Onvif, видимо потому что они выпускают «свои» камеры. UPDATED: см комментарии от ivideon
Если прикрутить к программе OpenVPN и OpenCV, то будет забавное решение и «велосипед»
Ну и вот вам полезная ссылка на базу ссылок потоков камер
И ещё про «домашний» Asterisk
Прочитав этот пост, решил поделиться и своим опытом.
Выбираем DID number
Всё начинается с номера телефона, на который вам будут звонить, общепринятое название — Direct Inward Dialing (DID) number.
Самое дешёвое предложение с прямым московским номером — «Баzа» (предоставляется Центральным Телеграфом). На момент написания поста самый дешёвый тариф стоит 250 руб/мес, плюс разовая оплата за подключение номера в коде 499 или 495, на выбор. При подписании договора лучше сразу попросить, чтобы подключили переадресацию на SIP устройство (дополнительная услуга «Баzа-IP», подключение оплачивается разово). Переадресация на SIP бесплатная. Это мой выбор.
Если вам надо совсем дёшево и сердито, есть mango-office, московский номер с тоновым донабором за 30 руб/мес 🙂 Я этот вариант не пробовал.
У Localphone можно купить DID номер в 49 странах мира (России в списке нет) с оплатой от £0.75 (≈37 руб) в месяц. Этот вариант я тоже пока не пробовал, но планирую 🙂 Номер в Лондоне или Нью-Йорке может пригодиться.
Настраиваем «Баzу»
На этом минимально необходимые настройки закончены.
Сервер для VoIP
Для Asterisk был выбран дешёвый виртуальный сервер в Германии на технологии Xen за €3/мес: 128Mb RAM, 256Mb swap, 10Gb disk, ОС Debian stable. На данный момент этого более чем достаточно.
Соединяем «Баzу» и Asterisk
[baza]
secret = ***
defaultuser = 849********
trunkname = baza
callerid =
hasexten = no
hassip = yes
hasiax = no
host = qwerty.cnt.ru
context = from-baza
insecure = invite
fromuser = 849********
fromdomain = qwerty.cnt.ru
type = friend
callbackextension = 111
disallow = all
allow = alaw
allow = ulaw
allow = g729
nat = no
canreinvite = nonat
dtmfmode = rfc2833
И создаём контекст «from-baza» в плане нумерации с одним единственным номером, который был указан выше в параметре callbackextension. Самый простой вариант, в /etc/asterisk/extensions.conf:
[inc-redirect-to-me]
Exten => 111, 1, Dial(SIP/terrasip/79*********&SIP/112,60)
Exten => 111, n, Hangup()
Звоним одновременно на мобильный телефон через оператора TerraSIP и на стоящий на столе SIP телефон. Настройки последнего приводить не буду — всё стандартно.
Выбор оператора для терминации VoIP трафика
Тут не обошлось без приключений.
Вначале выбор казался очевидным — Betamax. Это немецкий VoIP оператор с очень вкусными тарифами и, вместе с этим, хорошим качеством связи. Он работает через несколько десятков своих реселлеров, поэтому вначале смотрим тарифы в сводной таблице, затем регистрируемся у реселлера с самыми выгодными расценками и наслаждаемся жизнью 🙂 Я так и сделал.
А вчера всё перестало работать. Сервера Betamax стабильно отдают моему астериску сообщение: «SIP/2.0 503 For wholesale traffic, check www.voicetrading.com».
Резюме: Betamax непригоден для моих целей, как это ни печально звучит.
Сейчас я использую оператора TerraSip. Тарифы тут немного выше, чем у Betamax и, главное, нет бесплатных минут, как у последнего. Настройки Asterisk для работы с TerraSip также приводить не буду — на их сайте всё подробно рассказано.
Изменение формата DIDа и CIDа
Часто бывает, что оператор присылает номер звонящего в неудобном формате, а так же не корректно указывает номер DID. Рассмотрим как поправить эту ситуацию.
Для начала разберемся с понятиями:
DID (Direct Inward Dialing) — возможность АТС использовать несколько городских номеров для маршрутизации входящих вызовов. Попросту говоря, это ваш внешний номер, на который вам звонят клиенты
CID (Caller ID) — номер вызывающего абонента.
И так, провайдер присылает CID в формате +7XXXXXXXXX или 7XXXXXXXXXX а мы хотим 8XXXXXXXXXX (Причин тому может быть много: например возможность перезвонить абоненту нажатием одной кнопки на телефоне, или специфика используемой crm системы и т.д.)
Для решения данной проблемы нам нужно взять последние десять символов из CIDа и добавить к ним 8. Делается это путем создания своего контекста, в котором мы первично изменяем необходимые нам данные а потом дальше направляем во from-trunk. Соответственно в настройках нужного транка контекст нужно указать наш собственный (context=from-operator)
[from-operator]
exten => _.,1,Set(CALLERID(all)=8$
exten => _.,2,Set(CALLERID(ANI-all)=$
exten => _.,3,Goto(from-trunk,$
Второй случай бывает гораздо реже, это когда оператор присылает DID в каком-нибудь коротком виде типа 687 который никак не связан с номером компании. На скриншоте ниже видно как астериск принимает от оператора DID с номером 687
Так же мы видим что астериск не получает CID звонящего, вернее получает (если просмотреть SIP дебаги то оператор присылает номер звонящего в графе CALLERID(name)), а это уже третий случай который встречается очень редко.
Для решения первой проблемы нам необходимо так же создать свой контекст в котором принудительно направить вызов на экстеншн (номер) которой будет равен вашему DID (внешнему номеру)
Для решения проблемы с CID нам нужно CallerID звонящего брать из CALLERID(name)
[from-operator]
exten => _.,1,Set(CALLERID(all)=8$
exten => _.,2,Set(CALLERID(ANI-all)=$
exten => _.,3,Goto(from-trunk,4952326666) ; направляем вызов дальше в обработку во from-trunk на экстеншн равный нужному номеру вашего DID
Если все правильно то видим и CallerID звонящего и нужный DID
Только не забываем настроить входящую маршрутизацию, как это сделать можно посмотреть тут
Как подключить IP камеру по Onvif или RTSP?
1. ONVIF 
Начнем с протокола ONVIF (Open Network Video Interface Forum).
ONVIF — это общепринятый протокол для совместной работы IP-камер, видеорегистраторов NVR, программного обеспечения, на случай, если все устройства разных производителей.
Убедитесь, что подключаемые устройства имеют поддержку ONVIF, на некоторых устройствах ONVIF может быть выключен по умолчанию.
Либо может быть отключена авторизация по ONVIF это значит, что логин/пароль будет всегда по умолчанию независимо от логина/пароля для WEB.
Также стоит отметить, что некоторые устройства используют отдельный порт для работы по протоколу ONVIF. В некоторых случаях ONVIF-пароль может отличаться от пароля для WEB-доступа.
Что доступно при подключении по ONVIF?
Эти параметры зависят от совместимости версий протокола ONVIF. В некоторых случаях часть параметров недоступна или работает некорректно.
Разберем пример подключения камеры к видеорегистратору OMNY с использованием ONVIF:
Камеры OMNY PRO и OMNY Base используют ONVIF—порт 80, в регистраторе он указывается как Порт устройства/HTTP-порт (На моделях OMNY PRO до 2017 года ONVIF-порт 8080).
TCP — устанавливает соединение между отправителем и получателем, следит за тем, чтобы все данные дошли до адресата без изменений и в нужной последовательности, также регулирует скорость передачи.
В отличие от TCP, UDP не устанавливает предварительного соединения, а вместо этого просто начинает передавать данные. UDP не следит чтобы данные были получены, и не дублирует их в случае потерь или ошибок.
UDP менее надежен, чем TCP. Но с другой стороны, он обеспечивает более быструю передачу потоков благодаря отсутствию повторения передачи потерянных пакетов.
Второй способ подключения — это RTSP (Real Time Streaming Protocol).
RTSP-потоковый протокол реального времени, в котором описаны команды для управления видеопотоком. С помощью этих команд происходит трансляция видеопотока от источника к получателю. Например, от IP-камеры к видеорегистратору или серверу.
Что доступно при подключении по RTSP?
Преимущество этого протокола передачи в том, что он не требует совместимости по версиям. На сегодняшний день RTSP поддерживают практически все IP-камеры и NVR.
Недостатки протокола в том, что кроме передачи видео- и аудиоданных больше ничего не доступно.
Разберем пример подключения камеры к видеорегистратору OMNY с использованием RTSP:
Пример запроса для OMNY BASE:
Зачем нужен дополнительный поток?
На локальном мониторе, подключенном к регистратору в мульти-картинке, регистратор использует дополнительный поток для экономии ресурсов. К примеру, в маленьких картинках по 16 окон совсем не обязательно декодировать Full HD разрешение, достаточно D1.
Ну а если Вы открыли 1/4/8 окон, то в этом случае декодируется основной поток с высоким разрешением.
3. Не получается подключить по ONVIF
Если не получается подключить IP камеру в ПО или NVR по ONVIF, нужно убедиться:
ONVIF Device Manager
Проверить работоспособность ONVIF в камере, вы можете через независимое ПО ONVIF Device Manager. Для проверки правильности параметров ONVIF необходимо использовать ODM в локальной сети, исключив другие ПО и NVR.
Что такое did камеры
Некоторые камеры могут работать в режиме точки доступа, создавая собственную SSID. Однако в тех камерах, которые побывали у меня, этот функционал выпилен.
Выложенные ниже прошивки точно работают с такими платами
про переходники UART
Простейший преобразователь СОМ-TTL
пример щупов для подключения. диаметр жала должен быть не более 0.5мм, иначе не будут держаться.
На данный момент известно как минимум три варианта прошивки. Две из них плохо совместимы между собой, хоть и имеют одинаковый U-boot. Третья (с датой kernel Jun 2 12:28:35 CST 2017) не совместима с U-boot от предыдущих и требует правки параметров запуска. По этой причине ранее опубликованная здесь информация стала неактуальна и может привести к результату, противоположному ожидаемому. особенности читаем выше и ниже поста с прошивкой. Для тех, кто сам с усам: распаковываем. Делаем железный ресет. В логе камеры обычно фиксируется: Для Android: DIGMA. Работает практически со всеми камерами. Может работать как локально, так и через китайские облака по Р2Р Клиент, позволяющий сохранять видео к себе на комп в формате avi не вынимая карточку из камеры. В теме нет куратора. По вопросам наполнения шапки обращайтесь к модераторам раздела через кнопку
|