Старый фотик + bash = таймлапс
Думаю у многих из нас, в шкафу пылился старый зеркальный фотоаппарат, типа Canon EOS 400D. Он как чемодан без ручки: выбросить жалко, продать смысла нет, и использовать вряд ли будешь. Достал его так одним вечером, и подумал: вещь хорошая и вполне годная для всяких опытов. И сразу загорелся применить его во всяких своих самоделках. А что, весьма хорошо фотографирует из коробки, достаточно широкий спектр всяких регулировок, осталось только научиться с ним работать. Всего-то подружить его с компьютером, да Linux, и дело в шляпе! В результате у нас получается просто непаханое поле для фотографических экспериментов и применения в своих придумках. Давайте же поглядим, как это можно сделать и что получилось из таких экспериментов.
▍ Исходники
Как я уже сказал, у меня достаточно давно лежит в шкафу фотоаппарат Canon EOS 400D, для своего времени неплохой фотик для семейного фотоальбома, но с появлением хороших телефонов, практически не используется. Когда в очередной раз я его достал, то понял, что из него нужно сотворить что-то прикольное. Для того чтобы отвязать фотоаппарат от аккумулятора, и чтобы он работал «вечно», ему нужен источник питания от сети. Для этого пришлось приобрести адаптер ACK-DC20. Умышленно даю марку, потому что поиск для конкретной модели фотоаппарата оказался тем ещё квестом. Но оказалось, что можно вполне купить «здесь и сейчас», а не ждать с Китая. Всё это можно провернуть и с другими фотоаппаратами, только надо подобрать подходящий блок питания.
Также рекомендую обзавестись штативом, стоит более-менее вменяемый штатив недорого (мой стоил всего 1500 рублей в известном интернет-магазине), зато позволяет делать хорошие фото.
В качестве ЭВМ для работы с фотоаппаратом можно использовать подходящий одноплатник, лично я использовал какой-то древний портативный ноутбук, который зависает при открытии браузера, но вполне сносно справился с задачей снимать фотографии.
Всё готово к экспериментам: фотоаппарат, источник питания, штатив и ЭВМ.
▍ Настройка ПО
На ноутбуке установлен Linux Mint 19, и я буду рассказывать об особенностях настройки именно этой системы. Всё, что далее будет описано, может подойти к Ubuntu. В качестве основного источника информации, я использовал статью «How to Use Your DSLR Camera as a Webcam in Linux». Мой фотоаппарат не умеет снимать видео, и в качестве вебкамеры выступать отказался, но в ней изложены основные нюансы настройки, которые я и применил.
Для начала поставим все необходимые пакеты.
sudo apt-get install gphoto2 v4l2loopback-utils v4l2loopback-dkms ffmpeg
ffmpeg
нам понадобится чуточку позже, для монтирования видео.
В принципе, если вы хотите просто попробовать, работает ли у вас фотоаппарат, то можно модуль загрузить вручную.
sudo modprobe v4l2loopback exclusive_caps=1 max_buffers=2
Но после каждой перезагрузки, вспоминать, что надо загрузить модуль, мне было лень. Поэтому давайте это всё пропишем в системе/
Добавим в файл /etc/modules
строку dslr-webcam
:
$ sudo vi /etc/modules
# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.
dslr-webcam
Создадим новый файл /etc/modprobe.d/dslr-webcam.conf
и запишем в него следующие строки:
alias dslr-webcam v4l2loopback
options v4l2loopback exclusive_caps=1 max_buffers=2
После всех проделанных манипуляций перезагружаемся. Подключаем камеру с помощью microUSB, и включаем её. В результате dmesg должно показать следующий выхлоп:
[474969.683623] usb 2-1.7.2: new full-speed USB device number 14 using ehci-pci
[474969.797751] usb 2-1.7.2: not running at top speed; connect to a high speed hub
[474969.820004] usb 2-1.7.2: New USB device found, idVendor=04a9, idProduct=3110
[474969.820008] usb 2-1.7.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[474969.820009] usb 2-1.7.2: Product: Canon Digital Camera
[474969.820011] usb 2-1.7.2: Manufacturer: Canon Inc.
Проверяем, что камера успешно определилась:
gphoto2 --auto-detect
Модель Порт
----------------------------------------------------------
Canon EOS 400D (PTP mode) usb:002,014
Радостно пытаемся сделать фото:
gphoto2 --capture-image-and-download
И вероятнее всего у вас на этом моменте (или ещё на этапе подключения камеры) вылезет окошко системы и спросит, что делать с фотографиями на камере. А в консоли выпадет следующая или аналогичная ошибка:
gphoto2 --capture-image-and-download
*** Ошибка ***
An error occurred in the io-library ('Could not claim the USB device'): Could not claim interface 0 (Устройство или ресурс занято). Make sure no other program (gvfs-gphoto2-volume-monitor) or kernel module (such as sdc2xx, stv680, spca50x) is using the device and you have read/write access to the device.
ОШИБКА: Невозможно сделать снимок.
ОШИБКА: Невозможно сделать снимок.
*** Ошибка (-53: «Could not claim the USB device») ***
Для получения отладочных сообщений воспользуйтесь параметром --debug.
Отладочные сообщения могут помочь найти решение вашей проблемы.
Если вы хотите какие-либо сообщения gphoto, список рассылки авторов
программы , то запускайте
gphoto2 со следующими параметрами:
env LANG=C gphoto2 --debug --debug-logfile=my-logfile.txt --capture-image-and-download
Проверьте, что аргументы надёжно экранированы.
Честно говоря долго не мог понять, что с этим делать. У меня она прекрасно воспроизводилась на двух разных машинах с разными версиями linux mint, и заключалась она в том, что в системе работает демон gvfsd-metadata
, который следит за тем, что подключается медиаустройство. И он после этого уже запускает собственные клиенты работы с фотоаппаратом. Это можно увидеть следующей командой:
ps ax | grep photo
16478 ? Sl 0:00 /usr/lib/gvfs/gvfs-gphoto2-volume-monitor
21405 ? Sl 0:00 /usr/lib/gvfs/gvfsd-gphoto2 --spawner :1.31 /org/gtk/gvfs/exec_spaw/7
Первое, что нужно сделать — это поубивать эти процессы. После этого, либо грубо выкорчевать из системы демона gvfsd-metadata
:
systemctl --user mask gvfs-metadata.service
На ноуте я так и сделал, чтобы после каждой перезагрузки он меня не беспокоил. Вернуть всё обратно можно так:
systemctl --user unmask gvfs-metadata.service
Если вы хотите разово отключить сервис, то выполните:
systemctl --user stop gvfs-metadata.service
После этого всё это должно корректно заработать.
gphoto2 --capture-image-and-download
Новый файл находится в фотоаппарате в /capt0000.jpg
Файл сохраняется с именем capt0000.jpg
Удаляется файл /capt0000.jpg в фотоаппарате
Могу сказать сразу, что в разных системах этот демон может быть разным (у меня он отличается), и именно это может мешать корректно делать снимки.
На ноуте у меня всё корректно работало только под root, и пришлось все скрипты запускать только под sudo. Под обычным пользователем работало через раз, linux way, да-да. Так и не победил.
Скажу сразу, что на этом проблемы не заканчиваются, часто бывает, что возникает внутренняя ошибка фотоаппарата, которая решается только жёсткой перезагрузкой, со съёмкой аккумулятора. Например:
*** Ошибка ***
Canon EOS Capture failed (0x02ff: PTP I/O Error)
ОШИБКА: Невозможно сделать снимок.
ОШИБКА: Невозможно сделать снимок.
Притом на фотоаппарате висит Busy, и он ни на что не реагирует. Как её победить, я так и не понял.
Из дополнительных опций, хорошо управлять всем этим добром удалённо. Скрипты запускать в tmux, а папку с фотографиями монтировать по ssh. И для этих целей ноутбук оказался очень идеальным решением, потому что на нём есть wifi, и всю настройку и контроль делал удалённо. Папку с фотографиями монтировал следующей командой:
sudo sshfs -o allow_other,default_permissions user@ip:/home/user/canon ~/canon
▍ Настройки фотоаппарата
Для подобных съёмок фотоаппарат тоже стоит немного настроить. Первое, и очевидное — это сделать так, чтобы фотоаппарат не отключался самостоятельно. При работе от аккумулятора — это просто его разрядит, но при работе от сети — идеальный режим.
Убираем опцию «Автоотключение».
Следующая настройка — не такая очевидная. Для видео не требуется такого хорошего качества, даже самое низкое качество съёмки будет давать Full HD (1920×1080 точек). Поэтому снижаем качество съёмки.
Ставим самое «плохое» качество съёмки.
В результате будет кадр 1936×1288 пикселов, что тоже очень даже хорошо. Причина уменьшения качества съёмки банальна — это скорость передачи через USB. Если поставить больше, фотоаппарат просто не будет успевать передать полученную фотографию. Это тоже было выяснено эмпирическим путём.
▍ Немного программирования на bash
Изначально думал написать программу на питоне, для работы с фотоаппаратом. Даже нашёл неплохой мануал, но при попытке установить необходимые пакеты, получил кучу проблем:
sudo apt install libgphoto2-dev
sudo pip3 install -v gphoto2
Но библиотека пайтона gphoto2 упорно не хотела вставать на мою систему, убив минут 40, в попытке разрулить ситуацию с установкой модуля, принял решение писать на баше. Мы люди не гордые, сделаем на том, что работает. Да, и код на python, даже в примере был слишком монструозен, чем моя реализация на bash. Тем более что в нашем блоге есть шикарная серия статей по программированию на bash.
В результате мозгового штурма (я тот ещё «программист» на bash), родился следующий код.
#!/bin/bash
END=600
SLEEPTIME=10
for i in `seq -w 0 $END`
do
gphoto2 --capture-image-and-download --filename "$i.jpg"
sleep $SLEEPTIME
done
Где переменная END
— это суммарное количество снимков, которое сделает фотоаппарат. SLEEPTIME
— время между снимками. Опытным путём установлено, что время менее 10 секунд может приводить к ошибкам, особенно если снимать в ночное время в автоматическом режиме (когда выбирается автоматом время экспозиции).
Количество кадров, равное 2880 взято тоже не с потолка. Прикинул, что если сводить 24 кадра в секунду, сделать минутный ролик, то это получится 1440 кадров. Это как раз съёмка в течение 4-х часов, каждые 10 секунд. Если снимать 8 часов, то как раз значение будет больше. Но, увы, 8 часов мне снять так и не удалось, фотоаппарат зависал.
Полученные кадры необходимо свести в видео, чтобы можно было смотреть. Для этого воспользуемся ffmpeg
.
ffmpeg -framerate 24 -i %04d.jpg -c:v libx264 -profile:v high -crf 20 -pix_fmt yuv420p output.mp4
Не буду детально разбирать данную команду, обращу внимания на два момента:
framerate 24
— это количество кадров в секунду, я выбрал 24, и мне кажется этого маловато. Можно выбрать 60, и будет абсолютная гладкость.%04d.jpg
тип входящего файла, число после нуля будет показывать сколько чисел в имени файла (оно будет у вас разное, подбирайте под конкретную задачу).
Если хочется потом наложить аудиодорожку на видео, то можно воспользоваться следующей командой:
ffmpeg -i output.mp4 -i audio.wav -map 0:v -map 1:a -c:v copy -shortest output_audio.mp4
Где соответственно:
output.mp4
— входной видеофайлaudio.wav
— входной аудиофайл (любой формат)output_audio.mp4
— выходной видеофайл
Выходной файл получится длинной, того файла кто короче по воспроизведению видео или аудио (опция -shortest
).
▍ Даёшь съёмку и результаты!
Меньше слов, больше дела. Надо наконец попробовать, результат проделанной работы. Поскольку у меня из окна видна только помойка, то было принято решение поехать к хорошему приятелю с ночёвкой на окраину города. Там и просторы большие, рядом аэропорт, летает много самолётов, и просто более приятный вид из окна.
Первый опыт был просто в комнате, самое сложное было — это не включать свет, и не мелькать в окне, чтобы не было бликов на фотоаппарате. Но вроде всё получилось.
В процессе фотосъёмки.
Могу честно признаться, я тот ещё фотограф. Снимал просто в режиме «без вспышки», поэтому баланс белого, выдержка, ISO, диафрагма выбиралось автоматически каждый раз. Каждый кадр сделан с интервалом в 5 секунд. От этого получилась такая «ламповость», но, как по мне, для первого раза потрясающий результат:
Больше мы не выдержали, потому что сидеть впотьмах (свет включать нельзя) и «не дышать» (не ходить, чтобы не было бликов) просто невозможно, и съёмку было решено прервать, тут не спасли даже хорошие дружеские разговоры.
«Дефекты плёнки» на видео — это пролетающие птицы. Есть много вопросов к видео: мерцание, неестественные цвета и т.п. Есть куда расти и работать, но даже с этого можно отталкиваться.
Думаю, что если не полениться и настроить нормально фотоаппарат, и поставить на ночь, можно снять очень крутые перемигивания окнами.
Следующую съёмку было решено проводить на балконе, чтобы заснять рассвет.
Съёмочный стенд.
Но тут я совершил несколько роковых ошибок: не настроил фотоаппарат, пока было светло, при этом съёмку вёл в полностью мануальном режиме. В результате все фото получились размытыми. Другая ошибка, чуть не стоила мне фотоаппарата: я забыл про Солнце. И фотоаппарат был направлен прямо точно по траектории нашего светила. Пока мы спали, фотоаппарат чудом не расплавился — его спасла дымка и то что утром солнечные лучи не такие горячие. Поэтому, когда снимаете такие таймлапсы, обязательно помните про главное наше светило!
Поскольку восход не вышел, принято было волевое решение перед отъездом снять закат, и вот он уже получился. Дождался, когда солнечный диск уйдёт из объектива камеры (примерно 2 часа дня), и запустил съёмку. На первых кадрах ещё видны солнечные засветы линзы. Лично меня результат просто потряс, при совершенно незначительных трудозатратах.
Потрясающе: треки от самолётов, огни домов, закат, прямо-таки виден пульс засыпающего города. Мне после этого захотелось по всему городу расставить таких камер и снимать, снимать, снимать.
▍ Выводы
Не претендую, что открыл Америку, современные фотоаппараты умеют делать такое прямо из коробки, без всяких скриптов. Но, найти применение старой хорошей вещи — почему бы и нет? Например, можно поставить камеру во время какого-то действия, и сделать вот такой таймлапс. Кроме таймлапсов, можно использовать камеру, например, в фотоловушках. В общем, идей море, главное — успевать их реализовывать! Gphoto2 позволяют полностью управлять фотоаппаратом: балансом белого, выставлять диафрагму и т.д., что даёт просто неограниченные возможности. Главный плюс — это возможность вести удалённую фотосъёмку.
Выражаю благодарность своему другу Алексею, который двое выходных терпел меня, мои эксперименты, помогал и советовал, как лучше всё сделать.