Make sure that the PiCamera session is properly closed and re-opened on each stream request

This commit is contained in:
Fabio Manganiello 2020-09-25 18:06:27 +02:00
parent 258a9b57ce
commit ac42f7eba4
3 changed files with 11 additions and 9 deletions

View file

@ -17,13 +17,13 @@ from platypush.message.event.camera import CameraRecordingStartedEvent, CameraPi
CameraRecordingStoppedEvent, CameraVideoRenderedEvent CameraRecordingStoppedEvent, CameraVideoRenderedEvent
from platypush.plugins import Plugin, action from platypush.plugins import Plugin, action
from platypush.plugins.camera.model.camera import CameraInfo, Camera from platypush.plugins.camera.model.camera import CameraInfo, Camera
from platypush.plugins.camera.model.exceptions import CameraException, CaptureSessionAlreadyRunningException from platypush.plugins.camera.model.exceptions import CameraException, CaptureAlreadyRunningException
from platypush.plugins.camera.model.writer import VideoWriter, StreamWriter from platypush.plugins.camera.model.writer import VideoWriter, StreamWriter
from platypush.plugins.camera.model.writer.ffmpeg import FFmpegFileWriter from platypush.plugins.camera.model.writer.ffmpeg import FFmpegFileWriter
from platypush.plugins.camera.model.writer.preview import PreviewWriter, PreviewWriterFactory from platypush.plugins.camera.model.writer.preview import PreviewWriter, PreviewWriterFactory
from platypush.utils import get_plugin_name_by_class from platypush.utils import get_plugin_name_by_class
__all__ = ['Camera', 'CameraInfo', 'CameraException', 'CameraPlugin', 'CaptureSessionAlreadyRunningException', __all__ = ['Camera', 'CameraInfo', 'CameraException', 'CameraPlugin', 'CaptureAlreadyRunningException',
'StreamWriter'] 'StreamWriter']
@ -139,11 +139,10 @@ class CameraPlugin(Plugin, ABC):
:return: The initialized camera device. :return: The initialized camera device.
:raises: :class:`platypush.plugins.camera.CaptureSessionAlreadyRunningException` :raises: :class:`platypush.plugins.camera.CaptureSessionAlreadyRunningException`
""" """
info = self._merge_info(**params)
if device is None: if device is None:
info = self.camera_info.clone()
device = info.device device = info.device
elif device not in self._devices: elif device not in self._devices:
info = self._merge_info(**params)
info.device = device info.device = device
else: else:
info = self._devices[device].info.clone() info = self._devices[device].info.clone()
@ -152,7 +151,7 @@ class CameraPlugin(Plugin, ABC):
if device in self._devices: if device in self._devices:
camera = self._devices[device] camera = self._devices[device]
if camera.capture_thread and camera.capture_thread.is_alive() and camera.start_event.is_set(): if camera.capture_thread and camera.capture_thread.is_alive() and camera.start_event.is_set():
raise CaptureSessionAlreadyRunningException(device) raise CaptureAlreadyRunningException(device)
camera.start_event.clear() camera.start_event.clear()
camera.capture_thread = None camera.capture_thread = None

View file

@ -2,7 +2,7 @@ class CameraException(RuntimeError):
pass pass
class CaptureSessionAlreadyRunningException(CameraException): class CaptureAlreadyRunningException(CameraException):
def __init__(self, device): def __init__(self, device):
super().__init__('A capturing session on the device {} is already running'.format(device)) super().__init__('A capturing session on the device {} is already running'.format(device))

View file

@ -147,10 +147,13 @@ class CameraPiPlugin(CameraPlugin):
if not sock: if not sock:
continue continue
picam = self.open_device(**camera.info.to_dict()) if camera.object is None or camera.object.closed \
else camera.object
try: try:
camera.object.start_recording(sock, format=stream_format) picam.start_recording(sock, format=stream_format)
while camera.stream_event.is_set(): while camera.stream_event.is_set():
camera.object.wait_recording(1) picam.wait_recording(1)
except ConnectionError: except ConnectionError:
self.logger.info('Client closed connection') self.logger.info('Client closed connection')
finally: finally:
@ -160,7 +163,7 @@ class CameraPiPlugin(CameraPlugin):
except Exception as e: except Exception as e:
self.logger.warning('Error while closing client socket: {}'.format(str(e))) self.logger.warning('Error while closing client socket: {}'.format(str(e)))
self.release_device(camera) self.close_device(camera)
finally: finally:
self._cleanup_stream(camera, server_socket, sock) self._cleanup_stream(camera, server_socket, sock)
self.logger.info('Stopped camera stream') self.logger.info('Stopped camera stream')