So, I’ve been writing small Python script for capturing uncompressed video using Raspberry Pi 5 and camera module v2 with Picamera2 package.
Camera captures videoframes into a BytesIO() buffer, which I want to save as a file on disk.
After capturing short clip (approx. 170 MB because no compression applied). I write buffer to file object which is fast, but when I execute file.close() my program freezes for about 35 seconds.
The size of a file during this time is correct, I can open this file in another python process, the data is accessible so file with data is already there and no writing process undergo.
I tried opening file using with
and open
, used option buffering=200000000
, but to no avail.
Same very long time if I pass filename to start_recording() function.
Here is the code I use:
from picamera2 import Picamera2, Preview
from libcamera import controls, Transform
from picamera2.encoders import Encoder
from picamera2.outputs import FileOutput
from pprint import pprint
import threading
import time
import os
import sys
from PIL import Image
import numpy as np
import io
import time
def write_data(filename, buf):
t0 = time.time()
with open(filename, 'wb') as f:
f.write(buf.getbuffer())
buf.close()
print(time.time()-t0)
storage_path = "/media/rpi5/CAPTURE"
time.sleep(2)
for i in range(100):
if not os.path.isdir(f"{storage_path}/{str(i)}/"):
storage_path = storage_path+ f"/{str(i)}"
os.mkdir(storage_path)
break
path = storage_path
try:
os.mkdir(path)
except Exception as error:
print('Handling Exception')
if 'exists' not in error.args[1]:
sys.exit(1)
pass
with Picamera2() as camera:
config = camera.create_video_configuration(lores={'size':(320,240)}, display='lores')
config['main']['size'] = (1920,960)
config['lores']['size'] = (320, 240)
config['display'] = 'lores'
config['transform'] = Transform(vflip=1, hflip=1)
config['controls']['NoiseReductionMode'] = controls.draft.NoiseReductionModeEnum.Off
config['controls']['AeEnable'] = False
config['controls']['FrameRate'] = 5 # fps
config['controls']['ExposureTime'] = 50000
#10000us barely enough to capture inside the room
#100-200 us should be set for clouds
config['controls']['AnalogueGain'] = 1
encoder = Encoder()
camera.configure(config)
print('Begin capturing...')
camera.start_preview(Preview.QTGL)
camera.start()
metadata = camera.capture_metadata()
with open(path+'/metadata.txt','w') as mf:
pprint(metadata)
pprint(metadata, mf)
for i in range(1):
filename = path+'/vid%05d.vrgb'%i
buf = io.BytesIO()
camera.start_recording(encoder, FileOutput(buf))
time.sleep(5)
camera.stop_recording()
t0 = time.time()
with open(filename, 'wb') as f:
f.write(buf.getbuffer())
print(time.time()-t0)
buf.close()
camera.stop_preview()
SergeySh is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.