Fixed camera.pi plugin
This commit is contained in:
parent
25cbe759cf
commit
190ab15a76
2 changed files with 107 additions and 77 deletions
|
@ -88,8 +88,9 @@ class WebsocketBackend(Backend):
|
||||||
self.logger.warning('Error on websocket send_event: {}'.format(e))
|
self.logger.warning('Error on websocket send_event: {}'.format(e))
|
||||||
|
|
||||||
loop = get_or_create_event_loop()
|
loop = get_or_create_event_loop()
|
||||||
|
active_websockets = self.active_websockets.copy()
|
||||||
|
|
||||||
for websocket in self.active_websockets:
|
for websocket in active_websockets:
|
||||||
try:
|
try:
|
||||||
loop.run_until_complete(send_event(websocket))
|
loop.run_until_complete(send_event(websocket))
|
||||||
except websockets.exceptions.ConnectionClosed:
|
except websockets.exceptions.ConnectionClosed:
|
||||||
|
|
|
@ -69,9 +69,9 @@ class CameraPiPlugin(CameraPlugin):
|
||||||
import picamera
|
import picamera
|
||||||
self._camera = picamera.PiCamera()
|
self._camera = picamera.PiCamera()
|
||||||
|
|
||||||
for (attr, value) in self.camera_args:
|
for (attr, value) in self.camera_args.items():
|
||||||
setattr(self._camera, attr, value)
|
setattr(self._camera, attr, value)
|
||||||
for (attr, value) in opts:
|
for (attr, value) in opts.items():
|
||||||
setattr(self._camera, attr, value)
|
setattr(self._camera, attr, value)
|
||||||
|
|
||||||
return self._camera
|
return self._camera
|
||||||
|
@ -171,7 +171,7 @@ class CameraPiPlugin(CameraPlugin):
|
||||||
if resize:
|
if resize:
|
||||||
capture_opts['resize'] = tuple(resize)
|
capture_opts['resize'] = tuple(resize)
|
||||||
|
|
||||||
images = [os.path.join(directory, name_format % str(i+1)) for i in range(0, n_images)]
|
images = [os.path.join(directory, name_format % (i+1)) for i in range(0, n_images)]
|
||||||
camera.capture_sequence(images, **capture_opts)
|
camera.capture_sequence(images, **capture_opts)
|
||||||
return {'image_files': images}
|
return {'image_files': images}
|
||||||
|
|
||||||
|
@ -214,14 +214,15 @@ class CameraPiPlugin(CameraPlugin):
|
||||||
capture_opts['resize'] = tuple(resize)
|
capture_opts['resize'] = tuple(resize)
|
||||||
|
|
||||||
def capture_thread():
|
def capture_thread():
|
||||||
|
try:
|
||||||
self.logger.info('Starting time lapse recording to directory {}'.format(directory))
|
self.logger.info('Starting time lapse recording to directory {}'.format(directory))
|
||||||
i = 0
|
i = 0
|
||||||
|
|
||||||
for filename in camera.capture_continuous(os.path.join(directory, 'image_{counter:04d}.jpg')):
|
for filename in camera.capture_continuous(os.path.join(directory, 'image_{counter:04d}.jpg')):
|
||||||
i += 1
|
i += 1
|
||||||
self.logger.debug('Captured {}'.format(filename))
|
self.logger.info('Captured {}'.format(filename))
|
||||||
|
|
||||||
if i >= n_images:
|
if n_images and i >= n_images:
|
||||||
break
|
break
|
||||||
|
|
||||||
self._time_lapse_stop_condition.acquire()
|
self._time_lapse_stop_condition.acquire()
|
||||||
|
@ -230,7 +231,7 @@ class CameraPiPlugin(CameraPlugin):
|
||||||
|
|
||||||
if should_stop:
|
if should_stop:
|
||||||
break
|
break
|
||||||
|
finally:
|
||||||
self._time_lapse_thread = None
|
self._time_lapse_thread = None
|
||||||
self.logger.info('Stopped time lapse recording')
|
self.logger.info('Stopped time lapse recording')
|
||||||
|
|
||||||
|
@ -297,9 +298,10 @@ class CameraPiPlugin(CameraPlugin):
|
||||||
video_file = os.path.abspath(os.path.expanduser(video_file))
|
video_file = os.path.abspath(os.path.expanduser(video_file))
|
||||||
|
|
||||||
def recording_thread():
|
def recording_thread():
|
||||||
|
try:
|
||||||
if not multifile:
|
if not multifile:
|
||||||
self.logger.info('Starting recording to video file {}'.format(video_file))
|
self.logger.info('Starting recording to video file {}'.format(video_file))
|
||||||
camera.start_recording(video_file)
|
camera.start_recording(video_file, format='h264')
|
||||||
self._recording_stop_condition.acquire()
|
self._recording_stop_condition.acquire()
|
||||||
self._recording_stop_condition.wait(timeout=duration)
|
self._recording_stop_condition.wait(timeout=duration)
|
||||||
self._recording_stop_condition.release()
|
self._recording_stop_condition.release()
|
||||||
|
@ -313,7 +315,7 @@ class CameraPiPlugin(CameraPlugin):
|
||||||
if duration is not None:
|
if duration is not None:
|
||||||
end_time = time.time() + duration
|
end_time = time.time() + duration
|
||||||
|
|
||||||
camera.start_recording(name_format % i)
|
camera.start_recording(name_format % i, format='h264')
|
||||||
self._recording_stop_condition.acquire()
|
self._recording_stop_condition.acquire()
|
||||||
self._recording_stop_condition.wait(timeout=split_duration)
|
self._recording_stop_condition.wait(timeout=split_duration)
|
||||||
self._recording_stop_condition.release()
|
self._recording_stop_condition.release()
|
||||||
|
@ -337,9 +339,14 @@ class CameraPiPlugin(CameraPlugin):
|
||||||
|
|
||||||
if should_stop:
|
if should_stop:
|
||||||
break
|
break
|
||||||
|
finally:
|
||||||
|
try:
|
||||||
|
camera.stop_recording()
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.exception(e)
|
||||||
|
|
||||||
self.camera.stop_recording()
|
|
||||||
self._recording_thread = None
|
self._recording_thread = None
|
||||||
|
self.logger.info('Stopped camera recording')
|
||||||
|
|
||||||
self._recording_thread = threading.Thread(target=recording_thread)
|
self._recording_thread = threading.Thread(target=recording_thread)
|
||||||
self._recording_thread.start()
|
self._recording_thread.start()
|
||||||
|
@ -362,7 +369,7 @@ class CameraPiPlugin(CameraPlugin):
|
||||||
self._recording_thread.join()
|
self._recording_thread.join()
|
||||||
|
|
||||||
@action
|
@action
|
||||||
def start_streaming(self, listen_port=5000, duration=None, format='h264' **opts):
|
def start_streaming(self, listen_port=5000, duration=None, format='h264', **opts):
|
||||||
"""
|
"""
|
||||||
Start recording to a network stream
|
Start recording to a network stream
|
||||||
|
|
||||||
|
@ -388,17 +395,33 @@ class CameraPiPlugin(CameraPlugin):
|
||||||
server_socket.listen(0)
|
server_socket.listen(0)
|
||||||
|
|
||||||
def streaming_thread():
|
def streaming_thread():
|
||||||
self.logger.info('Starting streaming on listen port {}'.format(listen_port))
|
try:
|
||||||
|
self.logger.info('Starting streaming on port {}'.format(listen_port))
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
self.logger.info('Listening for client connection')
|
||||||
socket = server_socket.accept()[0].makefile('wb')
|
socket = server_socket.accept()[0].makefile('wb')
|
||||||
self.logger.info('Accepted client connection from {}'.format(socket.getpeername()))
|
self.logger.info('Accepted client connection')
|
||||||
|
start_time = time.time()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
camera.start_recording(socket, format=format)
|
camera.start_recording(socket, format=format)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
wait_time = 1
|
||||||
|
if duration:
|
||||||
|
wait_time = min(wait_time, duration)
|
||||||
|
if time.time() - start_time >= duration:
|
||||||
|
break
|
||||||
|
|
||||||
|
camera.wait_recording(wait_time)
|
||||||
self._streaming_stop_condition.acquire()
|
self._streaming_stop_condition.acquire()
|
||||||
self._streaming_stop_condition.wait(timeout=duration)
|
should_stop = self._streaming_stop_condition.wait(timeout=0.1)
|
||||||
self._streaming_stop_condition.release()
|
self._streaming_stop_condition.release()
|
||||||
|
|
||||||
|
if should_stop:
|
||||||
|
break
|
||||||
|
|
||||||
break
|
break
|
||||||
except ConnectionError:
|
except ConnectionError:
|
||||||
self.logger.info('Client closed connection')
|
self.logger.info('Client closed connection')
|
||||||
|
@ -407,8 +430,14 @@ class CameraPiPlugin(CameraPlugin):
|
||||||
socket.close()
|
socket.close()
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
finally:
|
||||||
self.camera.stop_recording()
|
try:
|
||||||
|
camera.stop_recording()
|
||||||
|
except BrokenPipeError:
|
||||||
|
pass
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.exception(e)
|
||||||
|
finally:
|
||||||
self._streaming_thread = None
|
self._streaming_thread = None
|
||||||
self.logger.info('Stopped camera stream')
|
self.logger.info('Stopped camera stream')
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue