Good afternoon sir,
I have a question about multi camera svo recording using zed2i camera.
My final goal is record svo file with 2 camera at the same time.
My code consists of three modules.
- main.py
- camera_logging.py
- utils.py
When I run the main code,
[ZED][ERROR] [ZED] Cannot start camera stream. Make sure your camera is not already used by another process or blocked by firewall.
The above error occurs.
Can you tell me what is wrong with my code?
main.py
'''
main module
'''
from loguru import logger
from camera_logging import CamRecorder
import multiprocessing
def create_process():
cam1 = CamRecorder(cam_serial_nr="36824395", output_folder= "C:/Users/MSDL-DESK-02/Desktop/camera1", file_prefix = "cam1")
cam2 = CamRecorder(cam_serial_nr="36568851", output_folder= "C:/Users/MSDL-DESK-02/Desktop/camera2", file_prefix = "cam2")
logger.debug("Start recording")
cam1.start_recording()
cam2.start_recording()
@logger.catch
def main():
p1 = multiprocessing.Process(target=create_process)
p1.start()
p1.join()
if __name__ == "__main__":
logger.add("logs/{time}.log", rotation="100 MB",level="INFO")
# logger.add(sys.stdout, level="INFO")
main()
camera_logging.py
'''
camera_logging.py module
'''
import pyzed.sl as sl
from signal import signal, SIGINT
from loguru import logger
from pathlib import Path
from utils import check_path,svo_path
from time import sleep
class CamRecorder:
def __init__(self,cam_serial_nr:str = "",rec_duration_s:int=60,output_folder:Path = "C:/Users/MSDL-DESK-02/Desktop",file_prefix:str = "cam1") -> None:
if cam_serial_nr:
self.cam_serial_nr = cam_serial_nr
print("serial_num:",self.cam_serial_nr)
self.cam = sl.Camera(self.cam_serial_nr)
else:
logger.info("No camera serial number provided, using first camera found")
self.cam = sl.Camera()
print(self.cam)
pass
self.output_path = check_path(output_folder)
self.file_prefix = file_prefix
self.rec_duration_s = rec_duration_s
self.signal = signal(SIGINT, self.handler) # signal handler for ctrl-c
self.init = sl.InitParameters()
self.init.camera_resolution = sl.RESOLUTION.HD2K
self.init.depth_mode = sl.DEPTH_MODE.NEURAL
self.init.camera_fps = 15
self.init.coordinate_units = sl.UNIT.MILLIMETER
self.init.camera_disable_self_calib = True
self.init.sdk_verbose = True
self.status = self.cam.open(self.init)
self.run = 0
if self.status != sl.ERROR_CODE.SUCCESS:
logger.error(repr(self.status))
exit(1)
logger.debug("Camera opened")
def handler(self,signal_received, frame):
"""handler for ctrl-c to stop recording"""
logger.info("SIGINT or CTRL-C detected. Exiting gracefully")
self.cam.disable_recording()
self.cam.close()
self.run = 0
def start_recording(self):
"""Start recording SVO file"""
logger.info("SVO is Recording, use Ctrl-C to stop.")
path = str(svo_path(self.output_path,self.file_prefix))
recording_param = sl.RecordingParameters(path, sl.SVO_COMPRESSION_MODE.H265)
logger.debug(f"{recording_param.video_filename}")
try:
err = self.cam.enable_recording(recording_param)
except:
logger.error("Error in enable_recording")
if err != sl.ERROR_CODE.SUCCESS:
logger.error("Failed to start recording")
exit(1)
logger.debug(f"Recording duration is {self.rec_duration_s} seconds")
runtime = sl.RuntimeParameters()
frames_recorded = 0
self.run = 1
fps = self.cam.get_camera_information().camera_fps
# run until ctrl-c or stop_recording is called
while self.run:
if self.cam.grab(runtime) == sl.ERROR_CODE.SUCCESS :
frames_recorded += 1
duration = frames_recorded / fps
if duration > self.rec_duration_s:
logger.debug(f"Recording duration reached, save current recording to {recording_param.video_filename}")
self.cam.disable_recording()#stop recording
sleep(0.1) #give camera time to close recording
recording_param.video_filename = svo_path(self.output_path,self.file_prefix)
self.cam.enable_recording(recording_param) #restart recording
frames_recorded = 0 #reset counter
#done recording
self.cam.disable_recording()
self.cam.close()
def stop_recording(self):
self.cam.disable_recording()
self.run = 0
return True
def reconnect_cam(self):
try:
self.cam.close()
sleep(0.1)
self.cam.open(self.init)
return True
except:
return False
def is_recording(self):
return self.cam.is_recording_enabled()
utils.py
'''
utils module
'''
from pathlib import Path
from datetime import datetime
import os
from loguru import logger as lo
def check_path(path:str= "")-> Path:
"""Check if path exists, if not raise FileNotFoundError"""
lo.debug(f"Checking path {path}")
if path:
path = Path(path)
if path.exists():
return Path(path)
else:
raise FileNotFoundError(f"Path {path} does not exist.")
else:
raise ValueError("Path cannot be empty.")
def dateandtime()-> str:
"""Return current date and time as string"""
return datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
def svo_path(folder:str , prefix:str)-> str:
"""Return path to SVO file"""
return str(os.path.join(folder,f"{prefix}_{dateandtime()}.svo"))
best regards,
Yoon