I'm capturing a timelapse with the picamera module for python:
from picamera import PiCamera, Color
class EggAlertCam:
def __init__(self):
self.camera = PiCamera()
self.camera.start_preview()
def capture_thread_task(self):
filename = os.path.join(self.SAVEPATH, self.safe_camname + '_{timestamp:%Y%m%d-%H%M%S}-{counter:03d}' + '.jpg' )
starttime = dt.datetime.now()
current_time = dt.datetime.now()
for filename in self.camera.capture_continuous(filename):
print('Captured {}'.format(filename))
self.wait(current_time)
current_time = dt.datetime.now()
def get_frame(self, size=None):
if size is None:
size = (640,480)
output = io.BytesIO()
self.camera.capture(output, format='jpeg', resize=size, use_video_port=True)
output.seek(0)
return output
This capture_thread_task
runs in a thread, and I have a Flask application allowing to capture frames from the camera through a REST call which calls get_frame
.
I'm using video_port=True
with the hope that I can fetch an (higher noise, but I don't care) image even while capturing the timelapse, but I get an exception:
Traceback (most recent call last):
File "/usr/local/lib/python3.7/dist-packages/flask/app.py", line 2446, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python3.7/dist-packages/flask/app.py", line 1951, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python3.7/dist-packages/flask/app.py", line 1820, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python3.7/dist-packages/flask/_compat.py", line 39, in reraise
raise value
File "/usr/local/lib/python3.7/dist-packages/flask/app.py", line 1949, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python3.7/dist-packages/flask/app.py", line 1935, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/usr/local/lib/python3.7/dist-packages/xxx/webapp.py", line 53, in get_frame
jpg = scheduler.cam.get_frame(size=size)
File "/usr/local/lib/python3.7/dist-packages/xxx/xxx.py", line 124, in get_frame
self.camera.capture(output, format='jpeg', resize=size, use_video_port=True)
File "/usr/local/lib/python3.7/dist-packages/picamera/camera.py", line 1409, in capture
camera_port, output_port = self._get_ports(use_video_port, splitter_port)
File "/usr/local/lib/python3.7/dist-packages/picamera/camera.py", line 562, in _get_ports
'The camera is already using port %d ' % splitter_port)
picamera.exc.PiCameraAlreadyRecording: The camera is already using port 0
I thought I'd be using another port for that capture, but alas it doesn't seem to work.
From the documentation here: https://picamera.readthedocs.io/en/release-1.10/fov.html?highlight=splitter#under-the-hood I figured that the capture_continuous function used port 0, and I should be able to use the port 1 which is the one used when telling use_video_port=True
.
But the exception message tells me it still wants to use port 0..
EDIT: I tried with splitter port 2, and for some of my Pi's it seems to work, and for others the port 2 seems used. After a few minutes, the port starts to be avaiable and I can fetch a frame from it.
This looks like a capture that takes a too long time, but I don't know how to properly ask the port 2 to free itself for a new capture.
What am I doing wrong ?