Недавно у меня возникла необходимость соорудить некое подобие видеонаблюдения. Требования были довольно простые:
  • возможность наблюдать через интернет
  • не обязателен режим реального времени, достаточно вечером просмотреть основные события за день (скажем, узнать, сидит ли кто-нибудь за вашим любимым компом, пока вы на работе)
  • отсутствие необходимости тратить часы на отсмотр результатов
  • максимально возможное качество картинки
  • минимальная стоимость

Исходя из критериев, можно было бы остановиться на готовых решениях в виде IP-камер. Однако, проведенный на скорую руку анализ рынка показал, что в устройствах, стоимостью до $100, размер картинки редко превышает 640x480 точек, и, при этом, они не могут похвастать хорошими возможностями для настройки софта. То есть, вполне возможно, что купив такую камеру, вам придется мириться с кривизной заводской прошивки и невозможностью в полной мере реализовать свои замыслы.

В противовес готовым решениям, самоделка на Raspberry Pi – это достаточно недорого, куда более увлекательно, и гораздо более гибко, благодаря полноценной ОС на борту и терабайтам готового софта на любой вкус.

Для решения описанных задач был придуман следующий алгоритм работы:

В начале дня (по расписанию) в системе запускается процесс, который делает фотоснимки с некоторым интервалом (скажем, раз в минуту), сохраняет их локально на карту памяти и тут же выкладывает на какой-нибудь облачный диск по WebDAV протоколу. Это обеспечивает некоторое подобие «живого» наблюдения, которое, хоть и не требуется по условиям, но является приятным бонусом. В конце дня (тоже по расписанию) процесс фотосъемки прерывается и запускается сборка видеофайла из фотографий. По окончании сборки, видео выкладывается на тот же облачный диск, что дает возможность быстрого удаленного просмотра цельной avi-шки, без необходимости переключения между фото-файлами (10 часов работы, по кадру в минуту, дадут общий хронометраж видео – всего около минуты, при 10 fps).

В таком подходе, конечно, не реализуется видеонаблюдение в его привычном виде, но решаются все поставленные задачи. Кроме того отпадает необходимость покупать у провайдера выделенный IP, чтобы подключаться к камере напрямую, а также нет нужды заводить отдельный сервер видеонаблюдения, потому что его функции хранения и доступа к данным перекладываются на бесплатный сервис (например Яндекс.Диск).

Итак, железо:

  • Raspberry Pi ($50-$60 в наших краях): я использовал model B, ту что c Ethernet, двумя USB и 256 Мб ОЗУ
  • Logitech C270 ($20): относительно дешевая и популярная HD (1280x720) веб-камера, соответствующая спецификации UVC (как следствие, без проблем работающая в Linux системах)
  • Зарядка от iPhone ($10): на самом деле айфон, конечно, ни при чем, подойдет любой источник питания с выходным током от 1А и разъемом micro-USB. Можно найти китайские импульсные зарядки не дороже $2 за штуку, только проверять их надо тщательно.
  • SD карта на 4 Гб ($6): четыре гига — минимальный объем карты для комфортной работы.
  • Корпус для малины ($1): сделан с помощью дремеля из более-менее подходящей коробки, купленной в строительном гипермаркете.

В сборе все выглядит примерно так:



Поскольку это мой первый опыт работы с Raspberry, чуть-чуть остановлюсь на вещах, возможно уже известных более продвинутым пользователям.

Первый нюанс – это питание периферийных устройств. Дело в том, что при включении Raspberry от одноамперного источника, USB портам достается совсем немного тока. В итоге у меня не получилось подключить одновременно веб-камеру и USB Wi-Fi dongle, или две веб-камеры: одно из устройств работало стабильно, а другое сначала вроде бы заводилось в системе, но через минуту просто отказывалось работать.

Второй нюанс – количество USB портов. Их в малинке всего два, а значит подключить камеру, клавиатуру и wi-fi одновременно не получится. Однако есть пара решений.

Во-первых можно подключить к Raspberry питающий USB хаб, а в него уже воткнуть всю необходимую периферию. У меня, например, все работало с таким:



Это увеличит число доступных портов и даст им всем достаточно тока, хотя и потребует занять еще одну розетку 220В.

Во-вторых, имеет смысл управлять малиной по SSH – тогда не нужно подключать ни клавиатуру, ни мышь, ни монитор. А если очень хочется увидеть графическую оболочку, то можно установить VNC server и получить удаленный доступ к рабочему столу. Делается это примерно так:

установка:

sudo apt-get install tightvncserver


запуск сервера на первом порту:

vncserver :1 -geometry 1200x700 -depth 16


Теперь подключиться к «малиновому» VNC можно клиентом из под рабочей ОС (под Windows, например, отлично работает UltraVNC )

Выбор и установка софта:

В качестве ОС я использовал Raspbian, как наиболее подходящую для непродвинутых пользователей. Нужно скачать образ системы и установить его на карту памяти с помощью специальной утилиты (Win32DiskImager под Windows). Все это подробно описано на странице загрузок официального сайта Raspberry: www.raspberrypi.org/downloads

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



Конечно, это можно сделать и позже, командой

sudo dpkg-reconfigure tzdata


Для захвата фото с веб-камеры настоятельно рекомендую использовать mjpg-streamer. Эта утилита – единственная среди опробованных на данной конфигурации железа, смогла выдать фото в «правильном» разрешении. Остальные инструменты которые мне довелось испытать (motion, ffmpeg, streamer), никак не отдавали HD картинку, предлагая в лучшем случае только 640x480, а то и вовсе отказывались запускаться. К сожалению в виде исполняемых файлов mjpg-streamer не распространен, однако скомпилировать его оказывается не сложнее, чем установить готовый пакет. Чем и займемся (предполагается, что все операции производятся от имени пользователя pi).

Сначала стоит обновить локальный индекс пакетов, доступных для установки:

sudo apt-get update


Также можно запустить апгрейд уже установленных в системе пакетов, если нужно, хотя на практике вс�� работает и без этого:

sudo apt-get upgrade


Чтобы вывести на фотографиях дату и время их создания, нам понадобится пакет imagemagick, в состав которого входит утилита convert. Она обладает поистине неограниченными возможностями по изменению изображений, так что написать в углу десяток цифр с ее помощью оказывается совершенно несложно. Этот же пакет понадобится и для компиляции mjpg-streamer, так что ставим его, не задумываясь:

sudo apt-get install imagemagick


Склейкой видео из набора фотографий занимается программа aviconv, которую мы тоже установим не самостоятельно, а вместе с пакетом libav-tools, без которого компиляция mjpg-streamer не будет успешной. Ставим:

sudo apt-get install libav-tools


Еще понадобится пакет libjpeg8-dev, который также содержит необходимые библиотеки для mjpg-streamer:

sudo apt-get install libjpeg8-dev


Для скачивания исходников c sourceforge понадобится subversion:

sudo apt-get install subversion


А само скачивание и компиляция mjpg-streamer делается так:

sudo svn co https://svn.code.sf.net/p/mjpg-streamer/code/mjpg-streamer/ mjpg-streamer
cd mjpg-streamer
make


Последний шаг – установка пакета для работы с удаленной файловой системой по WebDAV и, собственно, ее монтирование:

sudo apt-get install davfs2
sudo mkdir /mnt/dav
sudo mount -t davfs https://webdav.yandex.ru /mnt/dav -o uid=pi,gid=pi

В процессе монтирования нужно будет ввести имя пользователя и пароль.

Рабочий процесс шаг за шагом:

Теперь у нас есть все необходимое для дальнейшей работы. Вкратце опишу осно��ные команды, не особо налегая на bash, чтобы не перегружать статью. Думаю, что описание автоматизированных скриптов для запуска отдельных операций может быть поводом для отдельного эссе.

Итак, запускаем mjpg-streamer:

cd mjpg-streamer 
./mjpg_streamer -i "./input_uvc.so -r 1280x720 -f 1" -o "./output_file.so -f ./ -d 60000"

В таком режиме он будет раз в минуту (-d 60000) в текущем каталоге (-f ./) создавать файл с красивым именем, вроде такого: 2013_10_04_12_11_30_picture_000000000.jpg.

Для отрисовки временной метки на изображении используем скрипт примерно такого вида:

filename="2013_10_04_12_11_30_picture_000000000.jpg"
timestamp=`stat -c %y $filename`
convert $filename -fill black -draw "rectangle 1130,695 1270,715" -fill white -pointsize 15 -draw  "text 1135,710 '${timestamp:0:19}'" ./out.jpg.

Он поставит метку в правом нижнем углу изображения и запишет результат в out.jpg. Получится примерно так:



Для записи на Яндекс.Диск просто копируем нужный файл в /mnt/dav:

cp out.jpg /mnt/dav


Стоит отметить, что само копирование на удаленную файловую систему осуществляется в 2 этапа: сначала файл копируется в локальный кэш где-то в /var/cache/davfs2, а дальше davfs уже занимается собственно переносом файла по сети. Это значит, что команда копирования завершится раньше, чем файл физически окажется доступен в Яндекс.Диске. Поэтому не расстраивайтесь, если не обнаружите на Яндексе только что скопированный файл – скорее всего нужно немного подождать.

Создание видео из набора jpeg-ов нуждается в подготовке: имена файлов должны представлять собой последовательность возрастающих чисел, подчиняющихся определенному шаблону. Вот скрипт, который переименует все jpg файлы в текущем каталоге по возрастанию времени их модификации, а затем запустит конвертацию в avi:

i=0
for f in `ls -tr *.jpg 2>/dev/null`
do
  newf=`printf %06d $i`.jpg
  echo $f "-->" $newf
  mv $f $newf
  i=$((i+1))
done
avconv -r 10 -i %06d.jpg -r 10 -vcodec mjpeg -qscale 1  out.avi


Надо сказать, что avconv – тоже очень мощная утилита, умеющая кодировать практически что угодно во что угодно с доброй сотней параметров. Однако стоит учитывать довольно скромные возможности по софтовому кодированию-декодированию видео у Raspberry, чтобы не возлагать на нее слишком много надежд. Например конвертация набора из примерно 600 файлов в фильм, сжатый в H.264, занимала у меня около двух часов. Поэтому в примере выше я использую кодирование в MJPEG, которое по сути ничего не сжимает, а только склеивает jpg друг с другом. Такая конвертация выполняется за несколько минут и не теряет исходного качества картинок.

Далее, при некоторой сноровке и навыках разработки bash скриптов, можно настроить полностью автоматизированную систему, которая будет, включаться и выключаться по расписанию, убирать за собой мусор, отслеживать доступность свободного места на удаленном диске и т.п. Также через диск можно организовать удаленное управление Raspberry, например, выкладывая в определенный каталог скрипты, которые малинка будет сама забирать и выполнять.

В завершение предлагаю пример самодельного timelapse видео. Обратите внимание, что время в правом нижнем углу — неверное. Это из-за того, что в Raspberry нет часов реального времени, и если ее включить без подключения к интернету, то будет использоваться последнее время работы, без учета часового пояса.