Added basic support for camera events in the camera plugin

This commit is contained in:
Fabio Manganiello 2019-02-27 20:12:40 +01:00
parent 811af1bf9d
commit 29b8d0827b
2 changed files with 79 additions and 0 deletions

View file

@ -0,0 +1,47 @@
from platypush.message.event import Event
class CameraEvent(Event):
""" Base class for camera events """
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
class CameraRecordingStartedEvent(CameraEvent):
"""
Event triggered when a new recording starts
"""
def __init__(self, device_id, filename=None, *args, **kwargs):
super().__init__(*args, device_id=device_id, filename=filename, **kwargs)
class CameraRecordingStoppedEvent(CameraEvent):
"""
Event triggered when a recording stops
"""
def __init__(self, device_id, *args, **kwargs):
super().__init__(*args, device_id=device_id, **kwargs)
class CameraVideoRenderedEvent(CameraEvent):
"""
Event triggered when a sequence of frames has been rendered into a video
"""
def __init__(self, filename=None, *args, **kwargs):
super().__init__(*args, filename=filename, **kwargs)
class CameraPictureTakenEvent(CameraEvent):
"""
Event triggered when a snapshot has been taken
"""
def __init__(self, filename=None, *args, **kwargs):
super().__init__(*args, filename=filename, **kwargs)
# vim:sw=4:ts=4:et:

View file

@ -9,6 +9,11 @@ import cv2
from datetime import datetime from datetime import datetime
from platypush.config import Config from platypush.config import Config
from platypush.context import get_bus
from platypush.message.event.camera import CameraRecordingStartedEvent, \
CameraRecordingStoppedEvent, CameraVideoRenderedEvent, \
CameraPictureTakenEvent
from platypush.plugins import Plugin, action from platypush.plugins import Plugin, action
@ -16,6 +21,17 @@ class CameraPlugin(Plugin):
""" """
Plugin to control generic cameras over OpenCV. Plugin to control generic cameras over OpenCV.
Triggers:
* :class:`platypush.message.event.camera.CameraRecordingStartedEvent`
when a new video recording/photo burst starts
* :class:`platypush.message.event.camera.CameraRecordingStoppedEvent`
when a video recording/photo burst ends
* :class:`platypush.message.event.camera.CameraVideoRenderedEvent`
when a sequence of captured is successfully rendered into a video
* :class:`platypush.message.event.camera.CameraPictureTakenEvent`
when a snapshot is captured and stored to an image file
Requires: Requires:
* **opencv** (``pip install opencv-python``) * **opencv** (``pip install opencv-python``)
@ -107,6 +123,7 @@ class CameraPlugin(Plugin):
if device_id in self._devices: if device_id in self._devices:
self._devices[device_id].release() self._devices[device_id].release()
del self._devices[device_id] del self._devices[device_id]
get_bus().post(CameraRecordingStoppedEvent(device_id=device_id))
def _store_frame_to_file(self, frame, frames_dir, image_file): def _store_frame_to_file(self, frame, frames_dir, image_file):
@ -118,6 +135,9 @@ class CameraPlugin(Plugin):
frames_dir, datetime.now().strftime('%Y-%m-%d_%H-%M-%S-%f.jpg')) frames_dir, datetime.now().strftime('%Y-%m-%d_%H-%M-%S-%f.jpg'))
cv2.imwrite(filepath, frame) cv2.imwrite(filepath, frame)
if image_file:
get_bus().post(CameraPictureTakenEvent(filename=image_file))
return filepath return filepath
@ -169,6 +189,7 @@ class CameraPlugin(Plugin):
for f in files: for f in files:
video.write(cv2.imread(f)) video.write(cv2.imread(f))
video.release() video.release()
get_bus().post(CameraVideoRenderedEvent(filename=video_file))
shutil.rmtree(frames_dir, ignore_errors=True) shutil.rmtree(frames_dir, ignore_errors=True)
@ -185,6 +206,17 @@ class CameraPlugin(Plugin):
recording_started_time = time.time() recording_started_time = time.time()
captured_frames = 0 captured_frames = 0
evt_args = {
'device_id': device_id,
}
if video_file or image_file:
evt_args['filename'] = video_file or image_file
if frames_dir:
evt_args['frames_dir'] = frames_dir
get_bus().post(CameraRecordingStartedEvent(**evt_args))
while self._is_recording[device_id].is_set(): while self._is_recording[device_id].is_set():
if duration and time.time() - recording_started_time >= duration \ if duration and time.time() - recording_started_time >= duration \
or n_frames and captured_frames >= n_frames: or n_frames and captured_frames >= n_frames: