суббота, 10 апреля 2021 г.

Node js Raspberry pi фотоснимок с usb камеры

 Для работы с видеокамерой в репозитории npm есть много разных библиотек, однако большинство из них работают с камерой не напрямую а посредством утилит на подобии fswebcam или ffmpeg. Если на raspberry pi уже установлена одна из этих утилит и node.js то сделать простейшее взаимодействие с камерой не составит труда и без дополнительных библиотек. Для этого можно использовать уже имеющиеся модули child_process (для взаимодействия с утилитой fswebcam (которая взаимодействует с камерой)) и fs (для работы с файлами (в данном случае для загрузки фотографии)). Т.о. можно организовать например получение фотоснимка с камеры подключенной к raspberry pi по нажатию кнопки в web интерфейсе браузера и вывод этого снимка в этот интерфейс в виде картинки. Для этого можно использовать простой скрипт приведенный ниже:

Данный скрипт создает сервер используя модуль http. В функцию createServer передается анонимная функция в которой происходит обращение с утилите fswebcam чтобы сделать снимок и сохранить его в виде файла с расширением jpg. Для этого используется функция exec модуля child_process. В эту функцию передается ещё одна анонимная функция (так делается по тому что в javascript есть асинхронные функции которые если просто поставить друг за другом не будут выполняться по очереди (как это происходит в обычных языках вроде C++ или java) и чтобы обеспечить последовательность выполнения функций в javascript есть несколько способов напр. колбэки (как в данном случае) а также промисы). После того как снимок сделан и сохранен в виде файла. Происходит чтение этого файла (это не самый быстрый способ получить фотографию но его не трудно было реализовать). Далее, в зависимости от запроса на сервер, формируется web страница либо выдается картинка либо выводиться сообщение об ошибке. В веб странице есть кнопка по нажатию на которую на сервер приходит запрос о получении картинки. При этом запрос каждый раз немного отличается от предыдущего (благодаря дополнительному рандомному числу) т.к. если он будет каждый раз одинаковым то картинка будет браться не из сервера а из кэша браузера (так работают браузеры для минимизации обращения на сервер что ускоряет вывод пользователю информации и экономит интернет трафик, однако в нашем случае приходиться бороться с этим эффектом т.к. он не дает возможности поменять картинку). Чтобы сервер выдал картинку по немного новому адресу можно использовать регулярные выражения которые уже имеются в javascript по умолчанию поэтому не требуют установки дополнительных библиотек. Регулярные выражения значительно упрощают процесс написания кода т.к. если бы их не было и использовался бы например язык C++ (в котором их нет) то пришлось бы организовывать посимвольное сравнение массивов для чего пришлось бы написать некоторое количество строк кода явно большее чем одна (как в данном случае). И при этом удалось обойтись без подключения дополнительных библиотек.


node.js можно использовать с raspberry pi 2 (данный одноплатный п.к. на имеет встроенного wifi но есть ethernet разъем, также можно подключить usb-wifi или usb модем), raspberry pi 3, raspberry pi 4 и с д.р. аналогичными одноплатными компьютерами. Подобрать и заказать подходящий raspberry pi можно, например, после перехода по ссылке -> http://alii.pub/6cpwso