Converted base camera into an ABC
This commit is contained in:
parent
3cf166226b
commit
f7ba68b443
1 changed files with 22 additions and 15 deletions
|
|
@ -5,6 +5,8 @@ import threading
|
||||||
import datetime
|
import datetime
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
from abc import ABCMeta, abstractmethod
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from greenlet import getcurrent as get_ident
|
from greenlet import getcurrent as get_ident
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
|
@ -43,6 +45,11 @@ def generate_numbered_basename(obj_list: list) -> str:
|
||||||
return basename
|
return basename
|
||||||
|
|
||||||
|
|
||||||
|
def shunt_captures(target_list: list):
|
||||||
|
for obj in target_list: # For each older capture
|
||||||
|
obj.shunt() # Shunt capture from memory to storage
|
||||||
|
|
||||||
|
|
||||||
class CameraEvent(object):
|
class CameraEvent(object):
|
||||||
"""
|
"""
|
||||||
A frame-signaller object used by any instances or subclasses of BaseCamera.
|
A frame-signaller object used by any instances or subclasses of BaseCamera.
|
||||||
|
|
@ -87,7 +94,7 @@ class CameraEvent(object):
|
||||||
self.events[get_ident()][0].clear()
|
self.events[get_ident()][0].clear()
|
||||||
|
|
||||||
|
|
||||||
class BaseCamera(object):
|
class BaseCamera(metaclass=ABCMeta):
|
||||||
"""
|
"""
|
||||||
Base implementation of StreamingCamera.
|
Base implementation of StreamingCamera.
|
||||||
|
|
||||||
|
|
@ -101,7 +108,6 @@ class BaseCamera(object):
|
||||||
stream_timeout (int): Number of inactive seconds before timing out the stream
|
stream_timeout (int): Number of inactive seconds before timing out the stream
|
||||||
stream_timeout_enabled (bool): Enable or disable timing out the stream
|
stream_timeout_enabled (bool): Enable or disable timing out the stream
|
||||||
state (dict): Dictionary for capture state
|
state (dict): Dictionary for capture state
|
||||||
config (dict): Dictionary of base camera config
|
|
||||||
paths (dict): Dictionary of capture paths
|
paths (dict): Dictionary of capture paths
|
||||||
images (list): List of image capture objects
|
images (list): List of image capture objects
|
||||||
videos (list): List of video capture objects
|
videos (list): List of video capture objects
|
||||||
|
|
@ -115,12 +121,12 @@ class BaseCamera(object):
|
||||||
self.frame = None
|
self.frame = None
|
||||||
self.last_access = 0
|
self.last_access = 0
|
||||||
self.event = CameraEvent()
|
self.event = CameraEvent()
|
||||||
|
self.stop = False # Used to indicate that the stream loop should break
|
||||||
|
|
||||||
self.stream_timeout = 20
|
self.stream_timeout = 20
|
||||||
self.stream_timeout_enabled = False
|
self.stream_timeout_enabled = False
|
||||||
|
|
||||||
self.state = {}
|
self.state = {}
|
||||||
self.config = {}
|
|
||||||
self.paths = {
|
self.paths = {
|
||||||
'image': BASE_CAPTURE_PATH,
|
'image': BASE_CAPTURE_PATH,
|
||||||
'video': BASE_CAPTURE_PATH,
|
'video': BASE_CAPTURE_PATH,
|
||||||
|
|
@ -132,13 +138,15 @@ class BaseCamera(object):
|
||||||
self.images = []
|
self.images = []
|
||||||
self.videos = []
|
self.videos = []
|
||||||
|
|
||||||
def apply_config(self, config):
|
@abstractmethod
|
||||||
|
def apply_config(self, config: dict):
|
||||||
"""Update settings from a config dictionary"""
|
"""Update settings from a config dictionary"""
|
||||||
self.config.update(config)
|
pass
|
||||||
|
|
||||||
def read_config(self, config):
|
@abstractmethod
|
||||||
|
def read_config(self):
|
||||||
"""Return the current settings as a dictionary"""
|
"""Return the current settings as a dictionary"""
|
||||||
return self.config
|
pass
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
"""Create camera on context enter."""
|
"""Create camera on context enter."""
|
||||||
|
|
@ -176,7 +184,7 @@ class BaseCamera(object):
|
||||||
|
|
||||||
self.last_access = time.time()
|
self.last_access = time.time()
|
||||||
self.stop = False
|
self.stop = False
|
||||||
|
|
||||||
if not self.state['stream_active']:
|
if not self.state['stream_active']:
|
||||||
# start background frame thread
|
# start background frame thread
|
||||||
self.thread = threading.Thread(target=self._thread)
|
self.thread = threading.Thread(target=self._thread)
|
||||||
|
|
@ -222,9 +230,10 @@ class BaseCamera(object):
|
||||||
|
|
||||||
return self.frame
|
return self.frame
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
def frames(self):
|
def frames(self):
|
||||||
"""Create generator that returns frames from the camera."""
|
"""Create generator that returns frames from the camera."""
|
||||||
raise RuntimeError('Must be implemented by subclasses.')
|
pass
|
||||||
|
|
||||||
# RETURNING CAPTURES
|
# RETURNING CAPTURES
|
||||||
|
|
||||||
|
|
@ -248,10 +257,6 @@ class BaseCamera(object):
|
||||||
|
|
||||||
# CREATING NEW CAPTURES
|
# CREATING NEW CAPTURES
|
||||||
|
|
||||||
def shunt_captures(self, target_list: list):
|
|
||||||
for obj in target_list: # For each older capture
|
|
||||||
obj.shunt() # Shunt capture from memory to storage
|
|
||||||
|
|
||||||
def new_image(
|
def new_image(
|
||||||
self,
|
self,
|
||||||
write_to_file: bool = True,
|
write_to_file: bool = True,
|
||||||
|
|
@ -268,6 +273,7 @@ class BaseCamera(object):
|
||||||
temporary (bool): Should the data be deleted after session ends.
|
temporary (bool): Should the data be deleted after session ends.
|
||||||
Creating the capture with a content manager sets this to true.
|
Creating the capture with a content manager sets this to true.
|
||||||
filename (str): Name of the stored file. Defaults to timestamp.
|
filename (str): Name of the stored file. Defaults to timestamp.
|
||||||
|
folder (str): Name of the folder in which to store the capture.
|
||||||
fmt (str): Format of the capture.
|
fmt (str): Format of the capture.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
@ -291,7 +297,7 @@ class BaseCamera(object):
|
||||||
filepath=filepath)
|
filepath=filepath)
|
||||||
|
|
||||||
# Update capture list
|
# Update capture list
|
||||||
self.shunt_captures(self.images)
|
shunt_captures(self.images)
|
||||||
self.images.append(output)
|
self.images.append(output)
|
||||||
|
|
||||||
return output
|
return output
|
||||||
|
|
@ -312,6 +318,7 @@ class BaseCamera(object):
|
||||||
temporary (bool): Should the data be deleted after session ends.
|
temporary (bool): Should the data be deleted after session ends.
|
||||||
Creating the capture with a content manager sets this to true.
|
Creating the capture with a content manager sets this to true.
|
||||||
filename (str): Name of the stored file. Defaults to timestamp.
|
filename (str): Name of the stored file. Defaults to timestamp.
|
||||||
|
folder (str): Name of the folder in which to store the capture.
|
||||||
fmt (str): Format of the capture.
|
fmt (str): Format of the capture.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
@ -335,7 +342,7 @@ class BaseCamera(object):
|
||||||
filepath=filepath)
|
filepath=filepath)
|
||||||
|
|
||||||
# Update capture list
|
# Update capture list
|
||||||
self.shunt_captures(self.videos)
|
shunt_captures(self.videos)
|
||||||
self.videos.append(output)
|
self.videos.append(output)
|
||||||
|
|
||||||
return output
|
return output
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue