Refactored camera.pi endpoints

This commit is contained in:
Fabio Manganiello 2019-12-17 21:51:55 +01:00
parent 17af488b32
commit 634aeec58d
2 changed files with 20 additions and 43 deletions

View file

@ -10,50 +10,36 @@ from platypush.config import Config
from platypush.plugins.camera.pi import CameraPiPlugin from platypush.plugins.camera.pi import CameraPiPlugin
camera_pi = Blueprint('camera.pi', __name__, template_folder=template_folder) camera_pi = Blueprint('camera.pi', __name__, template_folder=template_folder)
filename = os.path.join(tempfile.gettempdir(), 'camera_pi.jpg')
# Declare routes list # Declare routes list
__routes__ = [ __routes__ = [
camera_pi, camera_pi,
] ]
_camera: Optional[CameraPiPlugin] = None
def get_camera() -> CameraPiPlugin:
global _camera
# noinspection PyProtectedMember
if _camera and _camera._camera and not _camera._camera.closed:
return _camera
camera_conf = Config.get('camera.pi') or {}
_camera = CameraPiPlugin(**camera_conf)
return _camera
def get_frame():
camera = get_camera()
output = camera.get_output_stream()
with output.ready:
output.ready.wait()
return output.frame
def video_feed(): def video_feed():
camera: Optional[CameraPiPlugin] = None
try: try:
camera_conf = Config.get('camera.pi') or {}
camera = CameraPiPlugin(**camera_conf)
while True: while True:
frame = get_frame() output = camera.get_output_stream()
with output.ready:
output.ready.wait()
yield (b'--frame\r\n' yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n') b'Content-Type: image/jpeg\r\n\r\n' + output.frame + b'\r\n')
finally: finally:
send_request(action='camera.pi.close') if camera:
camera.close_output_stream()
@camera_pi.route('/camera/pi/frame', methods=['GET']) @camera_pi.route('/camera/pi/frame', methods=['GET'])
@authenticate() @authenticate()
def get_frame_img(): def get_frame_img():
filename = os.path.join(tempfile.gettempdir(), 'camera_pi.jpg')
response = send_request('camera.pi.take_picture', image_file=filename) response = send_request('camera.pi.take_picture', image_file=filename)
frame_file = (response.output or {}).get('image_file') frame_file = (response.output or {}).get('image_file')
assert frame_file is not None assert frame_file is not None
@ -65,16 +51,9 @@ def get_frame_img():
@camera_pi.route('/camera/pi/stream', methods=['GET']) @camera_pi.route('/camera/pi/stream', methods=['GET'])
@authenticate() @authenticate()
def get_stream_feed(): def get_stream_feed():
global _camera return Response(video_feed(),
headers={'Cache-Control': 'no-cache, private', 'Pragma': 'no-cache', 'Age': 0},
try: mimetype='multipart/x-mixed-replace; boundary=frame')
return Response(video_feed(),
headers={'Cache-Control': 'no-cache, private', 'Pragma': 'no-cache', 'Age': 0},
mimetype='multipart/x-mixed-replace; boundary=frame')
finally:
if _camera:
_camera.close_output_stream()
_camera = None
# vim:sw=4:ts=4:et: # vim:sw=4:ts=4:et:

View file

@ -67,7 +67,7 @@ class CameraPiPlugin(CameraPlugin):
self._time_lapse_stop_condition = threading.Condition() self._time_lapse_stop_condition = threading.Condition()
self._recording_stop_condition = threading.Condition() self._recording_stop_condition = threading.Condition()
self._streaming_stop_condition = threading.Condition() self._streaming_stop_condition = threading.Condition()
self._output: StreamingOutput = None self._output: Optional[StreamingOutput] = None
# noinspection PyUnresolvedReferences,PyPackageRequirements # noinspection PyUnresolvedReferences,PyPackageRequirements
def _get_camera(self, **opts): def _get_camera(self, **opts):
@ -175,11 +175,10 @@ class CameraPiPlugin(CameraPlugin):
self.close() self.close()
def get_output_stream(self, resize: Union[tuple, list] = None, **opts) -> StreamingOutput: def get_output_stream(self, resize: Union[tuple, list] = None, **opts) -> StreamingOutput:
camera = self._get_camera(**opts) if self._output:
if self._output and not camera.closed:
return self._output return self._output
camera = self._get_camera(**opts)
capture_opts = {} capture_opts = {}
if resize: if resize:
capture_opts['resize'] = tuple(resize) capture_opts['resize'] = tuple(resize)
@ -189,9 +188,8 @@ class CameraPiPlugin(CameraPlugin):
return self._output return self._output
def close_output_stream(self): def close_output_stream(self):
if self._camera and not self._camera.closed: if self._output:
self._camera.stop_recording() self._camera.stop_recording()
self._output = None self._output = None
@action @action