Видеонаблюдение дома

Много разных статей встречается в сети на тему домашнего видеонаблюдения. Я решил изобрести свой велосипед, с преферансом и куртизанками.

Для начала я порылся в закромах и нашел Noname Chinese IP Camera, которая умеет слать поток куда-то в Китай, а значит его можно попробовать поймать.

Подключаем камеру и пытаемся посмотреть, какие открытые порты она имеет:

$ sudo nmap -A 192.168.1.156

Ответ впечатляет разнообразностью:

Starting Nmap 6.40 ( http://nmap.org ) at 2017-12-05 11:26 EET
Nmap scan report for 172.20.0.156
Host is up (0.0077s latency).
Not shown: 994 closed ports
PORT     STATE SERVICE    VERSION
23/tcp   open  telnet     Busybox telnetd
554/tcp  open  http       GM Streaming Server httpd
|_http-methods: No Allow or Public header in OPTIONS response (status code 501)
|_http-title: Site doesn't have a title (text/html).
| rtsp-methods:
|_  DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, SET_PARAMETER, GET_PARAMETER
5050/tcp open  tcpwrapped
5051/tcp open  tcpwrapped
8800/tcp open  tcpwrapped
8899/tcp open  soap       gSOAP soap 2.8
|_http-methods: No Allow or Public header in OPTIONS response (status code 200)
|_http-title: Site doesn't have a title (text/xml; charset=utf-8).
MAC Address: 28:F3:66:50:F4:FC (Unknown)
Device type: general purpose
Running: Linux 2.6.X|3.X
OS CPE: cpe:/o:linux:linux_kernel:2.6 cpe:/o:linux:linux_kernel:3
OS details: Linux 2.6.32 - 3.9
Network Distance: 1 hop
Service Info: Host: GM; Device: webcam

TRACEROUTE
HOP RTT     ADDRESS
1   7.72 ms 172.20.0.156

OS and Service detection performed. Please report any incorrect results at http://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 23.02 seconds

Это уже интересно. Нас интересуют два порта:

  1. 554 - стандартный порт для RTSP вещания.
  2. 8899 - SOAP сервер. Очень вероятно, что это ONVIF протокол для настройки камеры.

Это уже что-то. Попробуем получить URI потока используя запросы через ONVIF.

Ставим библиотеку onvif для python:

$ sudo pip install onvif

и пишем обертку для камеры:

#!/usr/bin/env python
from onvif import ONVIFCamera

cam = ONVIFCamera('192.168.1.156', 8899, '', '', '/tmp/python-onvif/wsdl')
media_service = cam.create_media_service()
profiles = media_service.GetProfiles()
token = profiles[0]._token
print media_service.GetStreamUri({'StreamSetup':{'Stream':'RTP-Unicast','Transport':'UDP'},'ProfileToken':token})

Теперь, чтоб не искать wsdl у себя в системе, просто скачаем их во временный каталог:

$ git clone https://github.com/quatanium/python-onvif.git /tmp

Запускаем и получаем на выходе URI для получения видео-потока с камеры: rtsp://192.168.1.156//live/ch00_1

Теперь можно настроить запись и детектор движения. Для этого мы будем использовать motion.

Тот motion, что идет в репозитории Ubuntu не умеет работать с rtsp протоколом, а потому нам надо поставить более свежий:

$ wget -O /tmp/motion.deb https://github.com/Motion-Project/motion/releases/download/release-4.1/trusty_motion_4.1-1_amd64.deb
$ sudo dpkg -i /tmp/motion.deb

Дальше пишем конфиг для него. Здесь я приведу важные моменты, а ссылка на полный конфиг будет ниже.

Адрес потока:

netcam_url rtsp://192.168.1.156:554/live/ch00_1

Каталог, для созранения результатов:

target_dir /home/silver/Camera

Если у вас есть большое количество места в Dropbox, то вы можете указать его и видео будет автоматически созраняться в облаке.

После того, как срабатывание датчика завершится, motion вызовет скрипт загрузки файла на удаленное хранилище:

on_event_end /home/silver/Projects/cctv/upload %f
on_movie_end /home/silver/Projects/cctv/upload %f

При начале события мы создаем картинки и шлем их в Telegram:

on_area_detected /home/silver/Projects/cctv/sendpic
on_movie_start /home/silver/Projects/cctv/sendpic

При потере потока от камеры - перегружаемся:

on_camera_lost /home/silver/Projects/cctv/restart_motion

Зона проверки движения:

area_detect 123456789

Формат такой - делим видео на 9 частей и вводим то, где должна быть проверка на движение:

1 2 3
4 5 6
7 8 9

Полный конфиг можно взять тут.

Теперь самое время разобраться со скриптами.

upload:

#!/bin/bash

rsync $1 remote.server.com:~/backup
echo "Uploaded ${1}" >> /tmp/upload.log

sendpic:

#!/bin/bash

export DISPLAY=:0
TOKEN="YouRTokenFor:TelegramBot"
CHATID="12345678"

cvlc -I dummy -v rtsp://172.20.0.156//live/ch00_1 --video-filter=scene --scene-format=jpg --scene-prefix=CameraImage --scene-path=/tmp/ --scene-replace --scene-ratio=30 --sout-x264-lookahead=1 --sout-x264-tune=stillimage --vout=dummy --aout=dummy --run-time 5 vlc://quit > /tmp/vlc.log 2>&1
curl -s "https://api.telegram.org/bot${TOKEN}/sendPhoto" -F chat_id=${CHATID} -F photo="@/tmp/CameraImage.jpg" -F caption=$1
rm /tmp/CameraImage.jpg
sleep 1
cvlc -I dummy -v rtsp://172.20.0.156//live/ch00_1 --video-filter=scene --scene-format=jpg --scene-prefix=CameraImage --scene-path=/tmp/ --scene-replace --scene-ratio=30 --sout-x264-lookahead=1 --sout-x264-tune=stillimage --vout=dummy --aout=dummy --run-time 5 vlc://quit > /tmp/vlc.log 2>&1
curl -s "https://api.telegram.org/bot${TOKEN}/sendPhoto" -F chat_id=${CHATID} -F photo="@/tmp/CameraImage.jpg" -F caption=$1
rm /tmp/CameraImage.jpg
sleep 0.5
cvlc -I dummy -v rtsp://172.20.0.156//live/ch00_1 --video-filter=scene --scene-format=jpg --scene-prefix=CameraImage --scene-path=/tmp/ --scene-replace --scene-ratio=30 --sout-x264-lookahead=1 --sout-x264-tune=stillimage --vout=dummy --aout=dummy --run-time 5 vlc://quit > /tmp/vlc.log 2>&1
curl -s "https://api.telegram.org/bot${TOKEN}/sendPhoto" -F chat_id=${CHATID} -F photo="@/tmp/CameraImage.jpg" -F caption=$1
rm /tmp/CameraImage.jpg
sleep 0.5
cvlc -I dummy -v rtsp://172.20.0.156//live/ch00_1 --video-filter=scene --scene-format=jpg --scene-prefix=CameraImage --scene-path=/tmp/ --scene-replace --scene-ratio=30 --sout-x264-lookahead=1 --sout-x264-tune=stillimage --vout=dummy --aout=dummy --run-time 5 vlc://quit > /tmp/vlc.log 2>&1
curl -s "https://api.telegram.org/bot${TOKEN}/sendPhoto" -F chat_id=${CHATID} -F photo="@/tmp/CameraImage.jpg" -F caption=$1
rm /tmp/CameraImage.jpg

Этот скрипт использует VLC media player для получения картинок, поэтому его надо установить:

$ sudo apt install vlc

restart_motion:

#!/bin/bash

killall -9 motion
motion -c /home/silver/Projects/cctv/motion.conf

Запускаем сервер:

$ motion -c /home/silver/Projects/cctv/motion.conf

Наблюдение доступно по адресу http://localhost:8081, можно тестировать работу датчика движения.


Comments !