Comments 11
Я одобряю этот пост.
+1
Кстати, как у вас обстоят дела с собственной системой видео наблюдения? Текущие реалии позволяют брать h264 камеры со стоп кадром (почти все камеры с onvif имеют его, либо собственный датчик движения, можно подписаться на эвенты onvif). И по схеме 10 минут записи в ram диск и миграция через ffmpeg на любой NAS на core i5 дает возможность держать больше 30ти камер. У меня 20-25 потоков h264 грузят одно ядро процессора на 80-180% (ядер 4 — 400%) с детектором движения на motion.
0
Не надо писать в комментариях про организацию на большую букву «I». Их Server использует SQLite, SSL, avcodec (ffmpeg)… но я не видел у них поддержку Onvif, видимо потому что они выпускают «свои» камеры.
Не стал бы писать, если бы вы не вводили в заблуждение читателей Хабра.
1. Организация на большую букву «I» прекрасно использует ONVIF для обнаружения камер в сети. Делается это в момент запуска мастера установки.
2. У нас нет «своих» камер. Есть производители, вроде Philips, Samsung, Hikvision, Microdigital, D-Link и некоторые другие, которые поддержали работу с облачным сервисом Ivideon прямо в своей прошивке. Для таких камер вообще не требуется такое архаичное решение как видеосервер на компьютере. Они работают из коробки. За этим будущее. Никто из наших клиентов не хочет держать какой-то все время включенный компьютер у себя в офисе, только для того, чтобы вывести, например, трансляцию на своем сайте из кухни, где готовят пиццу:
А вообще спасибо за статью. Я очень рад, что на Хабре появляются посты, посвященные видеонаблюдению. К сожалению, эта тема все еще очень обособлена от IT и очень мало информации по этому поводу.
+2
Спасибо, поправил. Видимо у вас идет поиск по камерам для которых включено обнаружение по onvif, но если я хочу добавить свою, у которой выключено обнаружение, то не могу найти в вашем сервере подобную настройку (3.4.5 build 78).
Архаичное решение как «сервер» нужен для архаичных камер, которые имеют совершенно разный h264 кодек с совершенно разными звуковыми дорожками и хочешь-не хочешь для вещания в web нужно всё декодировать.
А статьи про видео наблюдение обычно заканчиваются комментариями «Откройте для себя Ivideon».
Тема от IT обособлена по одной причине. Проще поставить коробку (DVR) и воткнуть туда камеры. Это обкатанный вариант, но не совсем бюджетный. Рынок довольно насыщенный и забит системами безопасности. И «пока оно работает» люди не особо хотят что то трогать.
А статей мало потому что есть либо zoneminder, либо скриптовый монстр на VLC (У меня такой есть), либо вы :)
Пока все производители камер не перейдут на «православный» web h264 ситуация особо не изменится. А как показывает практика и общение с разными организациями и безопасниками лучше иметь обособленную медиа среду для безопасности, нежели гнать по общему lan с его узлами. Сразу скажу что общение происходило в тех организациях, которые экономят на всём и штат в них до 20 человек. Т.е. им дешевле обслуживать путь Камера-провод-DVR, нежели всю инфраструктуру lan (которая строится на каком нибудь asus rt-n66)
Опыт используемый в этой статье был взят из проекта который «не выстрелил».
А сервер нужен для стандартизации потоков с камер. После этого можно и в web, и в файлы, и в космос.
Архаичное решение как «сервер» нужен для архаичных камер, которые имеют совершенно разный h264 кодек с совершенно разными звуковыми дорожками и хочешь-не хочешь для вещания в web нужно всё декодировать.
А статьи про видео наблюдение обычно заканчиваются комментариями «Откройте для себя Ivideon».
Тема от IT обособлена по одной причине. Проще поставить коробку (DVR) и воткнуть туда камеры. Это обкатанный вариант, но не совсем бюджетный. Рынок довольно насыщенный и забит системами безопасности. И «пока оно работает» люди не особо хотят что то трогать.
А статей мало потому что есть либо zoneminder, либо скриптовый монстр на VLC (У меня такой есть), либо вы :)
Пока все производители камер не перейдут на «православный» web h264 ситуация особо не изменится. А как показывает практика и общение с разными организациями и безопасниками лучше иметь обособленную медиа среду для безопасности, нежели гнать по общему lan с его узлами. Сразу скажу что общение происходило в тех организациях, которые экономят на всём и штат в них до 20 человек. Т.е. им дешевле обслуживать путь Камера-провод-DVR, нежели всю инфраструктуру lan (которая строится на каком нибудь asus rt-n66)
Опыт используемый в этой статье был взят из проекта который «не выстрелил».
А сервер нужен для стандартизации потоков с камер. После этого можно и в web, и в файлы, и в космос.
+1
Вы написали достаточно много про то, как забирать видео по RTSP.
Осталась в стороне синхронизация времени с камеры по RTCP.
0,0,0,1 — это префикс AnnexB записи H264. Это не часть H264 NAL-юнита, а разделитель между юнитами.
Осталась в стороне синхронизация времени с камеры по RTCP.
0,0,0,1 — это префикс AnnexB записи H264. Это не часть H264 NAL-юнита, а разделитель между юнитами.
0
Также я не рассказал о том как «собирать» udp поток.
RTCP для сохранения потока не столь важен :)
Кадры есть в SDP (SPS, PPS), для поддержки связи используется GET_PARAMETER, OSD есть в кадре. Минимум соблюден. При желании через onvif можно поставить правильное время.
Ссылка на RFC: tools.ietf.org/html/rfc3550#page-19
Камеры шлют RTCP senders report (200), мы должны слать Receiver Report (201)
До реализации RTCP не дошло, так как не было в этом надобности (точнее она была только при прошивке 1.00 у Dlink DCS-2103, на прошивке 1.20 надобность отпала)
Рекомендованный интервал между RTCP пакетами — 5 (секунд)
Задача в том, чтобы сохранить последний RTCP (200) и спустя некоторое время ответить.
github.com/Calc86/camRecorder/blob/master/src/com/net/rtp/RTCP.java
Также нужно понимать о существовании RTCP source description (202)
Каждый Source у камеры имеет уникальное число (32 бита, SSRC)
Аудио и видео это разные Source.
Алгоритмы вычисления lost и jitter можно посмотреть в приложениях RFC 3550, или вольная интерпретация тут: github.com/Calc86/camRecorder/tree/master/src/com/net/rtp/rfc — но его надо тестить.
Такого класса вполне достаточно для ответа на RTCP 200
Ну а вот что делать со всеми этими Timestamp — хрен его знает. Если пакеты потерялись, то не будем же мы нули писать в поток. По этому берем поток, отправляем в OutputStream и всё.
RTCP для сохранения потока не столь важен :)
Кадры есть в SDP (SPS, PPS), для поддержки связи используется GET_PARAMETER, OSD есть в кадре. Минимум соблюден. При желании через onvif можно поставить правильное время.
Ссылка на RFC: tools.ietf.org/html/rfc3550#page-19
Камеры шлют RTCP senders report (200), мы должны слать Receiver Report (201)
До реализации RTCP не дошло, так как не было в этом надобности (точнее она была только при прошивке 1.00 у Dlink DCS-2103, на прошивке 1.20 надобность отпала)
/**
* Created by calc on 17.07.14.
* http://tools.ietf.org/html/rfc3550#page-19
*
* From wireshark:
* RTCP senders report (200)
* 01234567 01234567 01234567 01234567
* +--------+--------+--------+--------+
* |V P RC | type201| length (octets) |
* v-2bit
* p-1bit
* 01234567 01234567 01234567 01234567
* +--------+--------+--------+--------+
* SSRC
* NTP timestamp MSW
* NTP timestamp LSW
* RTPWrapper timestamp
* senders packet count
* senders octet count
*
* RTCP source description (202)
* +--------+--------+--------+--------+
* |V P SC | type202| length |
* chunks:
* Chunk 1:
* +--------+--------+--------+--------+
* Identifier (SSRC?)
* SDES:
* +--------+--------+
* type length Text... End(0)
*
*
* +--------+--------+--------+--------+
* |V P RC | type201| length (octets) |
* ssrc
* Sources:
* +-Source1:
* +-Identifier (4bytes)
* +-SSRC content
* + fraction lost 1byte
* + Cumulative number of packets lost: -1 (3 bytes)
* + extended highest sequence number received
* + cycle 2b
* + number 2b
* + jitter 4b
* + LSR (middle of NTP timestamp)
* + Delay since last SR 4b
*
*
*
*/
public static byte[] response201(RTCP rtcp, int loop, int seq, int channel, long last, int jitter){
byte[] buffer = new byte[32];
int i = 0;
//header
buffer[i++] = (byte)0x81; //1000 0001
buffer[i++] = (byte)RTCP.TYPE_RECEIVER_REPORT;
buffer[i++] = 0; buffer[i++] = 7; // 32/4-1
//my ssrc
System.arraycopy(ssrc, 0, buffer, i, ssrc.length);
i += ssrc.length;
buffer[i-1] = (byte)channel;
//source 1
System.arraycopy(rtcp.getBuffer(), rtcp.getSSRCStart(), buffer, i, 4);
i += 4;
//fraction lost
buffer[i++] = (byte)0x00;
//Cumulative number of packets lost: -1
/*buffer[i++] = (byte)0xff;
buffer[i++] = (byte)0xff;
buffer[i++] = (byte)0xff;*/
buffer[i++] = 0;
buffer[i++] = 0;
buffer[i++] = 0;
//Extended highest sequence number received:
buffer[i++] = BIT.HiByte(BIT.LoWord(loop));
buffer[i++] = BIT.LoByte(BIT.LoWord(loop));
buffer[i++] = BIT.HiByte(BIT.LoWord(seq));
buffer[i++] = BIT.LoByte(BIT.LoWord(seq));
//Interarrival jitter:
buffer[i++] = BIT.HiByte(BIT.HiWord(jitter));
buffer[i++] = BIT.LoByte(BIT.HiWord(jitter));
buffer[i++] = BIT.HiByte(BIT.LoWord(jitter));
buffer[i++] = BIT.LoByte(BIT.LoWord(jitter));
//Last SR timestamp: 3810671619 (0xe3223c03)
buffer[i++] = BIT.HiByte(BIT.LoWord(rtcp.getHiNTPTimestamp()));
buffer[i++] = BIT.LoByte(BIT.LoWord(rtcp.getHiNTPTimestamp()));
buffer[i++] = BIT.HiByte(BIT.HiWord(rtcp.getLowNTPTimestamp()));
buffer[i++] = BIT.LoByte(BIT.HiWord(rtcp.getLowNTPTimestamp()));
//Delay since last SR timestamp: 71531 (1091 milliseconds)
//1/65536
long now = System.currentTimeMillis();
int range = (int)(((double)(now - last)/1000) * 65536);
buffer[i++] = BIT.HiByte(BIT.HiWord(range));
buffer[i++] = BIT.LoByte(BIT.HiWord(range));
buffer[i++] = BIT.HiByte(BIT.LoWord(range));
buffer[i++] = BIT.LoByte(BIT.LoWord(range));
/*buffer[i++] = 0;
buffer[i++] = 0;
buffer[i++] = 0x06;
buffer[i++] = 0x68;*/
return buffer;
}
Рекомендованный интервал между RTCP пакетами — 5 (секунд)
Задача в том, чтобы сохранить последний RTCP (200) и спустя некоторое время ответить.
private Thread createRTCPThread(){
return new Thread(new Runnable() {
private void send(Source s){
if(s.lastRTCP == null) return;
ByteArrayOutputStream bo = new ByteArrayOutputStream();
byte[] frame = {'$', (byte)s.controlCh, 0, 52};
try {
bo.write(frame);
RTCP r = s.lastRTCP;
do {
if(r.getPT() == RTCP.TYPE_SENDER_REPORT){
bo.write(
RTCP.response201(r, s.loop, s.sequence, s.controlCh,
s.lastRTCPTime, (int)s.jitter));
}
else if(r.getPT() == RTCP.TYPE_SOURCE_DESCRIPTION){
bo.write(RTCP.response202(r, s.controlCh));
} else {
System.out.println("RTCP Thread - Херня какая то: " + r.getPT());
}
}while ( (r = r.getNextRTCP()) != null);
out.write(bo.toByteArray());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while(!stop){
try {
Thread.sleep(4500);
} catch (InterruptedException e) {
e.printStackTrace();
}
send(sources.get(0));
//send ch1
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
//send ch2
send(sources.get(1));
}
}
});
}
github.com/Calc86/camRecorder/blob/master/src/com/net/rtp/RTCP.java
Также нужно понимать о существовании RTCP source description (202)
Каждый Source у камеры имеет уникальное число (32 бита, SSRC)
Аудио и видео это разные Source.
Алгоритмы вычисления lost и jitter можно посмотреть в приложениях RFC 3550, или вольная интерпретация тут: github.com/Calc86/camRecorder/tree/master/src/com/net/rtp/rfc — но его надо тестить.
Такого класса вполне достаточно для ответа на RTCP 200
private class Source{
public int ch;
public int controlCh;
public int SSRC;
public RTCP lastRTCP;
public long lastRTCPTime;
public long jitter;
public long transit;
public int loop;
public int sequence;
//Перевезти в эти переменные массив os[]
private OutputStream dataOut;
private OutputStream controlOut;
public void calculate(RTPWrapper rtp){
long ts = uInt.get(rtp.getTimestamp());
long arrival = System.currentTimeMillis() / 1000L;
long transit = arrival - ts;
long d = transit - this.transit;
this.transit = transit;
if(d < 0) d = -d;
jitter += (1./16.) * ((double)d - jitter);
int oldSeq = sequence;
int newSeq = rtp.getSequence();
if(newSeq < oldSeq) loop++;
sequence = newSeq;
}
}
Ну а вот что делать со всеми этими Timestamp — хрен его знает. Если пакеты потерялись, то не будем же мы нули писать в поток. По этому берем поток, отправляем в OutputStream и всё.
0
Сейчас последняя версия на сайте 3.5.0. Насколько я помню поддержка ONVIF появилась с версии, где был проведен редизайн мастера установки камер и он стал выглядеть так:
Если у вас он другой, то в этой версии, скорей всего поддержка ONVIF отсутствует.
Этого не произойдёт никогда. Есть стандарт H264, как и RTSP и ONVIF, и есть огромное количество производителей, которые ему следуют совершенно как вздумается. Те кто работали и работают с камерами, например, erlyvideo знают не по наслышке о том, как по RTSP приходят от китайских камер заголовки вида «Content-Length5034» и подобные опусы. Всегда приходится использовать заплатки для таких решений.
Для этого, в том числе, у нас и есть облако. Вся обработка «не таких» потоков производится в нём. Мы облегчаем жизнь пользователя, как это банально не звучало бы.
И не останавливайтесь) Пишите ещё! Тема очень интересная! Кстати, мы постоянно ищем интересных и разбирающихся в теме авторов. Готовы оплачивать посты по теме в нашем блоге и всячески поддерживать!)
Если у вас он другой, то в этой версии, скорей всего поддержка ONVIF отсутствует.
Пока все производители камер не перейдут на «православный» web h264
Этого не произойдёт никогда. Есть стандарт H264, как и RTSP и ONVIF, и есть огромное количество производителей, которые ему следуют совершенно как вздумается. Те кто работали и работают с камерами, например, erlyvideo знают не по наслышке о том, как по RTSP приходят от китайских камер заголовки вида «Content-Length5034» и подобные опусы. Всегда приходится использовать заплатки для таких решений.
А сервер нужен для стандартизации потоков с камер. После этого можно и в web, и в файлы, и в космос.
Для этого, в том числе, у нас и есть облако. Вся обработка «не таких» потоков производится в нём. Мы облегчаем жизнь пользователя, как это банально не звучало бы.
И не останавливайтесь) Пишите ещё! Тема очень интересная! Кстати, мы постоянно ищем интересных и разбирающихся в теме авторов. Готовы оплачивать посты по теме в нашем блоге и всячески поддерживать!)
0
Понятно что все не перейдут.
А что писать то)
В сентябре новая работа будет искаться. Буду заниматься видео — что нибудь напишу, а так пока мысли только о том как себя ведет TCP при большой нагрузке (window size и etc)
В сторону SIP может быть занесет и гоняние видео по нему, но кто знает.
У меня «облако» это был Core-i5 с Proxmox на борту, 3 машины (DVR, Mysql, Web) и второй гроб FreeNAS. Для нас было «накладно» перекодировать на нашем железе, по этому искались решения как можно проще и «в лоб». 30 камер 720p держал влет с онлайн просмотром архива и детектором движения. Онлайн просмотр был страшным монстром. Иногда h264 елся, иногда тупо mjpeg отдалавли (4 кдра в секунду, что позволяло смотреть даже на nokia c5-00). Ну и тайплапсы видео за день (1 секунда = 3 минуты), что позволяло за 5-8 минут проверить работу целой толпы людей. Кто был, кто не был и кто когда пришел. Так как проект потонул, вот и описываю «опыт».
Доходило до изобретения «железяки» на openwrt, которая напрямую поток с камеры кладет на хард, который воткнут в эту «железяку». Это был любой роутер TP-link и OpenWRT прошивка. Идея была в том, чтобы через OpenWRT хоть как то стандартизировать получение потока, стопкадра и безопасности.
Можно конечно и всё это описать, но там велосипед на велосипеде.
А что писать то)
В сентябре новая работа будет искаться. Буду заниматься видео — что нибудь напишу, а так пока мысли только о том как себя ведет TCP при большой нагрузке (window size и etc)
В сторону SIP может быть занесет и гоняние видео по нему, но кто знает.
У меня «облако» это был Core-i5 с Proxmox на борту, 3 машины (DVR, Mysql, Web) и второй гроб FreeNAS. Для нас было «накладно» перекодировать на нашем железе, по этому искались решения как можно проще и «в лоб». 30 камер 720p держал влет с онлайн просмотром архива и детектором движения. Онлайн просмотр был страшным монстром. Иногда h264 елся, иногда тупо mjpeg отдалавли (4 кдра в секунду, что позволяло смотреть даже на nokia c5-00). Ну и тайплапсы видео за день (1 секунда = 3 минуты), что позволяло за 5-8 минут проверить работу целой толпы людей. Кто был, кто не был и кто когда пришел. Так как проект потонул, вот и описываю «опыт».
Доходило до изобретения «железяки» на openwrt, которая напрямую поток с камеры кладет на хард, который воткнут в эту «железяку». Это был любой роутер TP-link и OpenWRT прошивка. Идея была в том, чтобы через OpenWRT хоть как то стандартизировать получение потока, стопкадра и безопасности.
Можно конечно и всё это описать, но там велосипед на велосипеде.
+1
Ivideon Server 3.5.0 Build 95
onvif discovery не сработал у меня.
Да и как я говорил напрямую нельзя «скормить» ссылку на onvif камеры.
Мне просто попадались IP камеры где есть ссылка на onvif, но для ссылки на rtsp приходилось рыться в интернете, даже поставщик не мог сказать их.
Может в будущем вы реализуете что нибудь подобное
alpha.hstor.org/files/2f7/8e1/7f1/2f78e17f107742fb8ab445bb85149f7f.png
у меня 10.112.28.33, воткнуты в один свич, udp не режется.
onvif discovery не сработал у меня.
Да и как я говорил напрямую нельзя «скормить» ссылку на onvif камеры.
Мне просто попадались IP камеры где есть ссылка на onvif, но для ссылки на rtsp приходилось рыться в интернете, даже поставщик не мог сказать их.
Может в будущем вы реализуете что нибудь подобное
alpha.hstor.org/files/2f7/8e1/7f1/2f78e17f107742fb8ab445bb85149f7f.png
IP camera Name DCS-2103
Time & Date Wed Jan 16 07:32:58 2013
Firmware Version 1.20.00
MAC Address F0:7D:68:09:E4:F4
IP Address 10.112.28.231
IP Subnet Mask 255.255.255.0
Default Gateway 10.112.28.253
Primary DNS 10.112.1.1
Secondary DNS 10.112.2.1
PPPoE Disable
DDNS Disable
у меня 10.112.28.33, воткнуты в один свич, udp не режется.
0
Понял. Да. Это факт. Напрямую скормить ссылку в Ivideon Server пока нельзя.
Если в Москве, приходите к нам. У нас много чего дорабатывать есть. В том числе и задачи по улучшению работы ONVIF, подключение и поддержка на уровне аппаратных детекторов новых камер и т.д.
В сентябре новая работа будет искаться.
Если в Москве, приходите к нам. У нас много чего дорабатывать есть. В том числе и задачи по улучшению работы ONVIF, подключение и поддержка на уровне аппаратных детекторов новых камер и т.д.
0
Sign up to leave a comment.
Еще раз о видеонаблюдении, камерах, RTSP, onvif. И «велосипед»!