1#!/usr/local/bin/python3.8 2 3# python-gphoto2 - Python interface to libgphoto2 4# http://github.com/jim-easterbrook/python-gphoto2 5# Copyright (C) 2018-19 Jim Easterbrook jim@jim-easterbrook.me.uk 6# 7# This program is free software: you can redistribute it and/or modify 8# it under the terms of the GNU General Public License as published by 9# the Free Software Foundation, either version 3 of the License, or 10# (at your option) any later version. 11# 12# This program is distributed in the hope that it will be useful, 13# but WITHOUT ANY WARRANTY; without even the implied warranty of 14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15# GNU General Public License for more details. 16# 17# You should have received a copy of the GNU General Public License 18# along with this program. If not, see <http://www.gnu.org/licenses/>. 19 20"""Simple time lapse script. 21 22This works OK with my Canon SLR, but will probably need changes to work 23with another camera. 24 25""" 26 27from __future__ import print_function 28 29from contextlib import contextmanager 30import os 31import subprocess 32import sys 33import time 34 35import gphoto2 as gp 36 37 38# time between captures 39INTERVAL = 10.0 40# temporary directory 41WORK_DIR = '/tmp/time_lapse' 42# result 43OUT_FILE = 'time_lapse.mp4' 44 45 46@contextmanager 47def configured_camera(): 48 # initialise camera 49 camera = gp.Camera() 50 camera.init() 51 try: 52 # adjust camera configuratiuon 53 cfg = camera.get_config() 54 capturetarget_cfg = cfg.get_child_by_name('capturetarget') 55 capturetarget = capturetarget_cfg.get_value() 56 capturetarget_cfg.set_value('Internal RAM') 57 # camera dependent - 'imageformat' is 'imagequality' on some 58 imageformat_cfg = cfg.get_child_by_name('imageformat') 59 imageformat = imageformat_cfg.get_value() 60 imageformat_cfg.set_value('Small Fine JPEG') 61 camera.set_config(cfg) 62 # use camera 63 yield camera 64 finally: 65 # reset configuration 66 capturetarget_cfg.set_value(capturetarget) 67 imageformat_cfg.set_value(imageformat) 68 camera.set_config(cfg) 69 # free camera 70 camera.exit() 71 72 73def empty_event_queue(camera): 74 while True: 75 type_, data = camera.wait_for_event(10) 76 if type_ == gp.GP_EVENT_TIMEOUT: 77 return 78 if type_ == gp.GP_EVENT_FILE_ADDED: 79 # get a second image if camera is set to raw + jpeg 80 print('Unexpected new file', data.folder + data.name) 81 82 83def main(): 84 if not os.path.exists(WORK_DIR): 85 os.makedirs(WORK_DIR) 86 template = os.path.join(WORK_DIR, 'frame%04d.jpg') 87 next_shot = time.time() + 1.0 88 count = 0 89 with configured_camera() as camera: 90 while True: 91 try: 92 empty_event_queue(camera) 93 while True: 94 sleep = next_shot - time.time() 95 if sleep < 0.0: 96 break 97 time.sleep(sleep) 98 path = camera.capture(gp.GP_CAPTURE_IMAGE) 99 print('capture', path.folder + path.name) 100 camera_file = camera.file_get( 101 path.folder, path.name, gp.GP_FILE_TYPE_NORMAL) 102 camera_file.save(template % count) 103 camera.file_delete(path.folder, path.name) 104 next_shot += INTERVAL 105 count += 1 106 except KeyboardInterrupt: 107 break 108 subprocess.check_call(['ffmpeg', '-r', '25', 109 '-i', template, '-c:v', 'h264', OUT_FILE]) 110 for i in range(count): 111 os.unlink(template % i) 112 return 0 113 114 115if __name__ == "__main__": 116 sys.exit(main()) 117