Pull to refresh
23
0

User

Send message
Ну желательно делать snmp по паролю (snmp v3?) и только на тех портах на которых можно его делать (ACL)
плюс там есть настройка для кого какие oid выдавать (для public одни, для private другие)
Ivideon Server 3.5.0 Build 95
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 не режется.
Понятно что все не перейдут.

А что писать то)
В сентябре новая работа будет искаться. Буду заниматься видео — что нибудь напишу, а так пока мысли только о том как себя ведет 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 хоть как то стандартизировать получение потока, стопкадра и безопасности.

Можно конечно и всё это описать, но там велосипед на велосипеде.
Также я не рассказал о том как «собирать» 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 надобность отпала)
/**
 * 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 и всё.
Спасибо, поправил. Видимо у вас идет поиск по камерам для которых включено обнаружение по onvif, но если я хочу добавить свою, у которой выключено обнаружение, то не могу найти в вашем сервере подобную настройку (3.4.5 build 78).
Архаичное решение как «сервер» нужен для архаичных камер, которые имеют совершенно разный h264 кодек с совершенно разными звуковыми дорожками и хочешь-не хочешь для вещания в web нужно всё декодировать.
А статьи про видео наблюдение обычно заканчиваются комментариями «Откройте для себя Ivideon».
Тема от IT обособлена по одной причине. Проще поставить коробку (DVR) и воткнуть туда камеры. Это обкатанный вариант, но не совсем бюджетный. Рынок довольно насыщенный и забит системами безопасности. И «пока оно работает» люди не особо хотят что то трогать.
А статей мало потому что есть либо zoneminder, либо скриптовый монстр на VLC (У меня такой есть), либо вы :)
Пока все производители камер не перейдут на «православный» web h264 ситуация особо не изменится. А как показывает практика и общение с разными организациями и безопасниками лучше иметь обособленную медиа среду для безопасности, нежели гнать по общему lan с его узлами. Сразу скажу что общение происходило в тех организациях, которые экономят на всём и штат в них до 20 человек. Т.е. им дешевле обслуживать путь Камера-провод-DVR, нежели всю инфраструктуру lan (которая строится на каком нибудь asus rt-n66)
Опыт используемый в этой статье был взят из проекта который «не выстрелил».

А сервер нужен для стандартизации потоков с камер. После этого можно и в web, и в файлы, и в космос.
Кстати, как у вас обстоят дела с собственной системой видео наблюдения? Текущие реалии позволяют брать h264 камеры со стоп кадром (почти все камеры с onvif имеют его, либо собственный датчик движения, можно подписаться на эвенты onvif). И по схеме 10 минут записи в ram диск и миграция через ffmpeg на любой NAS на core i5 дает возможность держать больше 30ти камер. У меня 20-25 потоков h264 грузят одно ядро процессора на 80-180% (ядер 4 — 400%) с детектором движения на motion.
У меня наоборот
Железо ни когда не купят, ну либо спустя год после заказа этого железа (в идеале)
нет ничего более долговечного чем временное решение :)
Вы правы, оперсорсных нет.
Могу предложить свое.
github.com/Calc86/dvr/tree/master/bin/system2/classes

Пример готовой системы (для записи TV)
github.com/Calc86/dvr/tree/master/bin/system2/classes/tv
Краткое описание
system имеем users, они имеют dvr(ретрансляторы), далее камеры, камеры имеют потоки

Всё создание происходит в AbstractFactory.php (и ее детях)
Есть предефайнед потоки
смотреть тут
github.com/Calc86/dvr/tree/master/bin/system2/classes/vlc
есть поддержка motion
до ffmpeg+server еще не добрался
В будущем планируется прикрутка onvif

Так как vlc и moion не очень стабильны есть костыльная система, пример тут
github.com/Calc86/dvr/blob/master/bin/system2/classes/bb/BBFactory.php

Система имеет local, nfs, tmpfs хранилища.
пишет 10 минут в tmpfs, потом перемещает запись в nfs
На core i5 держит больше 20ти камер и еще есть запас в процессорном времени.

Если всё правильно настроить работает стабильно уже пол года
Я не пойму. Вам действительно интересно или вы что то доказываете?
Если действительно интересно — добро пожаловать в vk/jabber расскажу как оно работает.
Если у вас свое видение теорпетическое/практическое, то вас ни кто ни в чем не отговаривает.
Пока не спросишь — не узнаешь, есть она или нет :)

Нет четкого алгоритма поведения. Нужно всегда коррелировать негатив, оплату труда и реализуемость человека на данной должности.

Это уже не задача сотрудника, а задача грамотного менеджера. В 2х словах то не рассказать.
Палка о двух концах.
Была бы возможность платить больше — платили бы больше.
А вы не думали что человеку просто нужна работа и ЗП юниора его устраивает, чтобы заплатить за квартиру. И он в себе уверен, что через 3 месяца можно будет пересмотреть его уровень?
И такое бывало
Ты с ним общаешься, пытаешься выяснить что и как.
Принимаешь заявление
Потом через 2 дня он забирает его обратно.

Я сам инроверт
Если есть свободные средства, то так и происходит.
У меня их денег нет.
Если нужно денег — пойду выбивать на отдел больше. Вот и всё.

А если работа возросла, то по любому должна быть прибавка. Любая работа должна быть оплачена.

Мы же говорим о том, что человек сидит, работает и вдруг ему стало мало, а не когда на него навесили +100500 обязанностей?
Когда то давно я работал на человека, который спокойно общался на тему денег.

Нужно больше — докажи почему. И всё решалось в момент обсуждения. Сейчас эта схема работает и для моих.
Отделы были разного размера. от 4х до 40 человек.
Люди обучаемы.
Берем на работу тех, кто может учиться

А сказать что денег мало, это не жалоба.
Это из разряда «мышка не работает, я не могу выполнять свою работу».

Можете минусовать дальше.

10 лет в должности подтверждает всё выше сказанное.

Information

Rating
Does not participate
Registered
Activity