Tried this modified script with an updated mergeviews function to help prevent the “CompletedRequest” error.
I was able to record a bit longer but then got errors again.
I was able to record a bit longer but then got errors again.
Code:
#!/usr/bin/python3# Encode and store a pair of side-by-side 1500x1500 image streams to give 3000x1500 video at ~15fps.from picamera2 import Picamera2, MappedArrayfrom picamera2.encoders import H264Encoderfrom picamera2.outputs import FfmpegOutputfrom libcamera import Transformimport timeimport osimport sys# Ensure the "pop" directory existsoutput_dir = "pop"os.makedirs(output_dir, exist_ok=True) # Ensure the output directory exists# Get the name from the argumentsif len(sys.argv) > 1: video_name = sys.argv[1]else: video_name = "fusion.mp4" # fallback name# Set the full path including the "pop" foldervideo_name = os.path.join(output_dir, video_name)fps = 15height = 1500leftsize = (2 * height, height) # define 2:1 format for left main streamrightsize = (height, height) # define 1:1 right main streamFrameTime = int(1000000 / fps)# select fastest full format sensor modebinned2x2ffmode = 2# adopt a mixture of callback methods to repackage downsampled left image# into left half of stream, and also package 1:1 right image into the other half. def mergeviews(request): global cam2_request if cam2_request is None: return try: request_2 = cam2_request request_2.acquire() with MappedArray(request, "main") as m1, MappedArray(request_2, "main") as m2: # Fill left half of original left array with half-width downsampled left camera view m1.array[:, :height] = m1.array[:, ::2] # Fill right half with 1:1 right camera view m1.array[:, height:] = m2.array finally: request_2.release()def save_request(request): # Store most recent request for use by other camera global cam2_request if cam2_request is not None: cam2_request.release() request.acquire() cam2_request = requestlcam = Picamera2(0)rcam = Picamera2(1)# Select best modemode = lcam.sensor_modes[2]# Calculate dimensions for crop of central square full height region of sensorsensorsize = lcam.camera_properties['PixelArraySize']sensorwidth = sensorsize[0]sensorheight = sensorsize[1]x = (sensorwidth - sensorheight) // 2crop = (x, 0, sensorheight, sensorheight)# Configure both cameras to full format binned 2x2 mode and set the main stream to be 2:1 wide in left cam,# filled with the stretched central square zone of the sensor, right cam stream is set for equivalent square zone at 1:1.lconfig = lcam.create_video_configuration(sensor={"output_size": mode['size'], 'bit_depth': mode['bit_depth']}, main={"format": "RGB888", "size": leftsize}, controls={"ScalerCrop": crop, "FrameDurationLimits": (FrameTime, FrameTime)}, transform=Transform(hflip=True, vflip=True), queue=False)rconfig = rcam.create_video_configuration(sensor={"output_size": mode['size'], 'bit_depth': mode['bit_depth']}, main={"format": "RGB888", "size": rightsize}, controls={"ScalerCrop": crop, "FrameDurationLimits": (FrameTime, FrameTime)}, transform=Transform(hflip=True, vflip=True), )lcam.configure(lconfig)rcam.configure(rconfig)# Prepare to encode and output to an mp4 fileencoder = H264Encoder(10000000)output = FfmpegOutput(video_name)lcam.start()rcam.start()cam2_request = Nonercam.pre_callback = save_requestlcam.pre_callback = mergeviews# Short delay to allow AE and AWB to settle, and should also avoid recording unprocessed first frametime.sleep(1)# Start recording indefinitely until stopped manuallylcam.start_recording(encoder, output)# Infinite loop to keep recordingtry: while True: time.sleep(1)except KeyboardInterrupt: # Stop recording when interrupted (Ctrl + C) lcam.stop_recording()Statistics: Posted by MRV — Fri Oct 25, 2024 10:42 am