avatar

Стриминг видео c USB камеры через SSH

Опубликовал в блог Linux и другие Unix-like
Было такое дело, собрался я в отпуск. При этом, хотелось иногда поглядывать «что дома творится». Благо, небольшой безголовый сервер на базе моноплатного компьютера имелся, а найти в домашних завалах пару USB-камер тоже не составило труда.

Linux и другие Unix-like: Один из вариантов подключения

Итак, имеем:
Моноплатный ПК на базе Cubieboard Cubietruck, с подключенными USB камерами, ОС на базе одной из дебиановских сборок Linux под arm.

Хотим:
Максимально простое удалённое подключение к видеокамере.

Рассматриваемых вариантов подключения к камерам было несколько:

Первый вариант
Запустить X приложение через ssh (проброс событий X-сервера, ssh -X и т.д.), в принципе, это раньше работало без проблем из коробки, когда я подключался к удалённому рабочему столу на Linux и хотел посмотреть веб-камеру. (Или почти из коробки, такой вариант весьма сильно подтормаживает). Но в данном случае это решение не работало, т. к. на моноплатном компе X-сервер отсутствовал, и приложения, работающие с ним, тоже.

Второй вариант
Веб-стриминг. Можно было запустить что-то вроде VLC без интерфейса, чтобы он передавал данные на определённом порту через какой-то протокол вроде RTSP, но это выглядело не очень безопасным по сравнению с SSH, да и захламлять память моноплатного компа тяжелыми приложениями не хотелось.

В итоге, мне внезапно пришла следующая идея: а что если читать видеоустройство в stdout по SSH, а потом этот stdout будет обрабатывать уже программа на локальном компе? Ведь SSH позволяет локальным приложениям читать вывод удалённых приложений, если задать правильную команду. И я приступил к экспериментам.

Для начала, необходимо предоставить доступ к видеоустройству на удалённом компьютере (с видеокамерами) для текущего пользователя, не root. Устройства /dev/video* имеют группу video, членом которой мой пользователь по умолчанию не являлся. Исправляем:

sudo usermod -a -G video user

где user — имя текущего пользователя.

Особенность видеоустройств в том, что просто через cat или dd их содержимое в stdout не отправишь, они выдадут ошибку. Нужна программа, которая сделает видеопоток пригодным к «потреблению». Сначала мой выбор пал на ffmpeg. В качестве локального плеера я использовал VLC, но подойдёт любой другой, умеющий читать stdin.

Ставим ffmpeg на компьютер с видеокамерами, и на удалённом компе запускаем:

ssh user@server ffmpeg -an -f video4linux2 -s 320x240 -i /dev/video0 -r 12 -b:v 30k -f ogg — | vlc -

где user — имя текущего пользователя, server — сервер для подключения.

Вкратце, эта команда использует драйвер video4linux2 для чтения видеовывода /dev/video0 (у вас может быть другой), и жмет его в ogg с размером кадра 320х240 12 кадров в секунду, а затем направляет его в stdout, который, в свою очередь, читается локальным плеером VLC. Схема рабочая, но на arm-компе немного подтормаживающая.

И тут я вспомнил об утилите streamer. Она позволяет создавать легковесные видеофайлы с камеры, при этом не сильно занимая процессорное время. Проблема в том, что данная программа не умеет писать в stdout, но мы можем ее научить :)

Для начала создадим именованный pipe для нашей программы, через команду mkfifo.

mkfifo dummyavi.avi

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

Теперь запускаем наш конвеер (не забыв установить streamer). Streamer пишет данные в наш fifo pipe, оттуда их забирает cat, который, в свою очередь, гонит их в stdout для локального плеера VLC.

ssh user@server '(streamer -c /dev/video0 -t 0:30 -r 24 -o dummyavi.avi -f jpeg > /dev/null & cat dummyavi.avi)' | vlc -

В данной команде интересен параметр -t — это время записи. Де-факто, он означает, что файл будет писаться в течение 30 секунд. Если мы хотим непрерывное наблюдение, этот параметр стоит попробовать сделать очень большим. Кстати, в принимающем плеере не стоит выбирать видеовывод VDPAU — он с выводом streamer не справится.

Качество видео не очень хорошее, зато не тормозит даже на слабом компе при достаточно медленной связи.
0 комментариев RSS
Нет комментариев
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.