class Image_recorder: def __init__(self, media): self.writer = None self.media = media self.config = Configuration() self.file_name = None self.index = 0 def start(self, shape, path=None, fps=30): # TODO manage multiple record # manage only one record at time if self.writer: self.stop() if not path: path = "%s" % (self.config.get_path_save_record()) if not path: path = "./" elif "/" not in path: path = "%s%s" % (self.config.get_path_save_record(), path) if os.path.isfile(path): log.print_function(logger.error, "File already exist %s" % path) return False if not os.path.isdir(path): try: os.makedirs(path) except: pass self.file_name = path logger.info("Start record on path: %s", path) self.media.add_observer(self.write) self.writer = self.write return True def next_filename(self): path = os.path.join(self.file_name, str(self.index).zfill(10) + '.png') self.index += 1 return path def write(self, image): cv2.imwrite(self.next_filename(), image) def get_file_name(self): if not self.file_name: return "" return self.file_name def stop(self): logger.info("Close record on path: %s", self.file_name) self.file_name = None if not self.writer: return False self.media.remove_observer(self.write) self.writer = None return True
class Video_recorder: def __init__(self, media): self.writer = None self.media = media self.config = Configuration() self.file_name = None def start(self, shape, path=None, fps=30): # TODO manage multiple record # manage only one record at time if self.writer: self.stop() add_format_name = False if path: # exception, if not contain /, maybe it's just a filename if "/" not in path: name = "%s%s.avi" % (self.config.get_path_save_record(), path) else: # TODO need to add extension when giving all path with filename? name = path if os.path.isdir(path): add_format_name = True else: add_format_name = True # TODO mkdir if directory name = self.config.get_path_save_record() if add_format_name: name += "%s.avi" % time.strftime("%Y_%m_%d_%H_%M_%S", time.gmtime()) if os.path.isfile(name): log.print_function(logger.error, "File already exist %s" % name) return False self.file_name = name logger.info("Start record on path: %s", name) fps = 8 # fourcc = cv.CV_FOURCC('D','I','V','X') # fourcc = cv.CV_FOURCC('F', 'L', 'V', '1') # fourcc = cv.CV_FOURCC('V', 'P', '8', '0') # not work # fourcc = cv.CV_FOURCC('M', 'J', 'P', 'G') # fourcc = cv.CV_FOURCC('D', 'I', 'B', ' ') # Uncompressed RGB, 24 or 32 bit - not working linux fourcc = cv.CV_FOURCC('I', 'Y', 'U', 'V') # Uncompressed YUV, 4:2:0 chroma subsampled , same of 'I420' self.writer = cv2.VideoWriter(filename=name, fourcc=fourcc, fps=fps, frameSize=shape, isColor=1) self.writer.open(name, fourcc, fps, shape, 1) self.media.add_observer(self.writer.write) return True def get_file_name(self): if not self.file_name: return "" return self.file_name def stop(self): logger.info("Close record on path: %s", self.file_name) self.file_name = None if not self.writer: return False self.media.remove_observer(self.writer.write) del self.writer self.writer = None return True
class ImageRecorder: def __init__(self, media): self.writer = None self.media = media self.config = Configuration() self.file_name = None self.index = 0 self.compress = 0 def start(self, shape, path=None, fps=30, compress=0): # TODO manage multiple record # manage only one record at time if self.writer: self.stop() if not path: path = "%s" % (self.config.get_path_save_record()) if not path: path = "./" elif "/" not in path: path = "%s%s" % (self.config.get_path_save_record(), path) if os.path.isfile(path): log.print_function(logger.error, "File already exist %s" % path) return False self.compress = compress if not os.path.isdir(path): try: os.makedirs(path) except: pass self.file_name = path logger.info("Start record on path: %s", path) self.media.add_observer(self.write) self.writer = self.write return True def next_filename(self): path = os.path.join(self.file_name, str(self.index).zfill(10) + '.png') self.index += 1 return path def write(self, image): compress = int(self.compress * 0.09) params = [cv2.cv.CV_IMWRITE_PNG_COMPRESSION, compress] cv2.imwrite(self.next_filename(), image, params) def get_file_name(self): if not self.file_name: return "" return self.file_name def stop(self): logger.info("Close record on path: %s", self.file_name) self.file_name = None if not self.writer: return False self.media.remove_observer(self.write) self.writer = None return True
class VideoRecorder: def __init__(self, media): self.writer = None self.media = media self.config = Configuration() self.file_name = None self.process = None # create a semaphore to protect when closing ffmpeg self.sem = Semaphore(1) def start(self, shape, path=None, fps=30, compress=0): # TODO manage multiple record # manage only one record at time if self.process: self.stop() add_format_name = False if path: # exception, if not contain /, maybe it's just a filename if "/" not in path: name = "%s%s.avi" % (self.config.get_path_save_record(), path) else: # TODO need to add extension when giving all path with # filename? name = path if os.path.isdir(path): add_format_name = True else: add_format_name = True # TODO mkdir if directory name = self.config.get_path_save_record() if add_format_name: name += "%s.avi" % time.strftime( "%Y_%m_%d_%H_%M_%S", time.gmtime()) if os.path.isfile(name): log.print_function(logger.error, "File already exist %s" % name) return False self.file_name = name logger.info("Start record on path: %s", name) # 1 is best quality, 36 is worse qscale = compress * 0.35 + 1 self.process = Popen( ['ffmpeg', '-y', '-f', 'image2pipe', '-vcodec', 'mjpeg', '-r', '24', '-i', '-', '-vcodec', 'mpeg4', '-qscale', "%s" % qscale, '-r', '24', name], stdin=PIPE) self.media.add_observer(self.add_image) return True def add_image(self, image): # take sem with blocking self.sem.acquire(True) # check if process is active after the sem if self.process is None: self.sem.release() return # convert image to rgb in image2 image2 = np.asarray(image, dtype="uint8") cv2.cvtColor(image, cv.CV_BGR2RGB, image2) # convert in PIL image img = Image.fromarray(image2, 'RGB') # Save it in ffmpeg process img.save(self.process.stdin, 'JPEG') self.sem.release() def get_file_name(self): return self.file_name if self.file_name else "" def stop(self): logger.info("Close record on path: %s", self.file_name) self.file_name = None if not self.process: return False self.media.remove_observer(self.add_image) self.sem.acquire(True) self.process.stdin.close() self.process.wait() self.process = None self.sem.release() return True