def on_notify(self, notification): """Handles recorder notifications Reacts to notifications: ``recording.should_start``: Starts a new recording session. fields: - 'session_name' change session name start with `/` to ingore the rec base dir and start from root instead. - `record_eye` boolean that indicates recording of the eyes, defaults to current setting - `rec_root_dir` full path to recording directory root, defaults to current setting ``recording.should_stop``: Stops current recording session Emits notifications: ``recording.started``: New recording session started ``recording.stopped``: Current recording session stopped Args: notification (dictionary): Notification dictionary """ # notification wants to be recorded if notification.get('record', False) and self.running: if 'timestamp' not in notification: logger.error( "Notification without timestamp will not be saved.") else: notification['topic'] = 'notify.' + notification['subject'] try: writer = self.pldata_writers['notify'] except KeyError: writer = PLData_Writer(self.rec_path, 'notify') self.pldata_writers['notify'] = writer writer.append(notification) elif notification['subject'] == 'recording.should_start': if self.running: logger.info('Recording already running!') else: self.record_eye = notification.get('record_eye', self.record_eye) if notification.get("session_name", ""): self.set_session_name(notification["session_name"]) if notifcation.get("rec_root_dir", ""): self.set_rec_root_dir(notification["rec_root_dir"]) self.start() elif notification['subject'] == 'recording.should_stop': if self.running: self.stop() else: logger.info('Recording already stopped!')
def on_notify(self, notification): """Handles recorder notifications Reacts to notifications: ``recording.should_start``: Starts a new recording session. fields: - 'session_name' change session name start with `/` to ingore the rec base dir and start from root instead. - `record_eye` boolean that indicates recording of the eyes, defaults to current setting ``recording.should_stop``: Stops current recording session Emits notifications: ``recording.started``: New recording session started ``recording.stopped``: Current recording session stopped Args: notification (dictionary): Notification dictionary """ # notification wants to be recorded if notification.get("record", False) and self.running: if "timestamp" not in notification: logger.error( "Notification without timestamp will not be saved.") notification["timestamp"] = self.g_pool.get_timestamp() # else: notification["topic"] = "notify." + notification["subject"] try: writer = self.pldata_writers["notify"] except KeyError: writer = PLData_Writer(self.rec_path, "notify") self.pldata_writers["notify"] = writer writer.append(notification) elif notification["subject"] == "recording.should_start": if self.running: logger.info("Recording already running!") else: self.record_eye = notification.get("record_eye", self.record_eye) if notification.get("session_name", ""): self.set_session_name(notification["session_name"]) self.start() elif notification["subject"] == "recording.should_stop": if self.running: self.stop() else: logger.info("Recording already stopped!")
def on_notify(self, notification): """Handles recorder notifications Reacts to notifications: ``recording.should_start``: Starts a new recording session. fields: - 'session_name' change session name start with `/` to ingore the rec base dir and start from root instead. - `record_eye` boolean that indicates recording of the eyes, defaults to current setting ``recording.should_stop``: Stops current recording session Emits notifications: ``recording.started``: New recording session started ``recording.stopped``: Current recording session stopped Args: notification (dictionary): Notification dictionary """ # notification wants to be recorded if notification.get("record", False) and self.running: if "timestamp" not in notification: logger.error("Notification without timestamp will not be saved.") else: notification["topic"] = "notify." + notification["subject"] try: writer = self.pldata_writers["notify"] except KeyError: writer = PLData_Writer(self.rec_path, "notify") self.pldata_writers["notify"] = writer writer.append(notification) elif notification["subject"] == "recording.should_start": if self.running: logger.info("Recording already running!") else: self.record_eye = notification.get("record_eye", self.record_eye) if notification.get("session_name", ""): self.set_session_name(notification["session_name"]) self.start() elif notification["subject"] == "recording.should_stop": if self.running: self.stop() else: logger.info("Recording already stopped!")
def start(self): self.start_time = time() start_time_synced = self.g_pool.get_timestamp() if isinstance(self.g_pool.capture, NDSI_Source): # If the user did not enable TimeSync, the timestamps will be way off and # the recording code will crash. We check the difference between the last # frame's time and the start_time_synced and if this does not match, we stop # the recording and show a warning instead. TIMESTAMP_ERROR_THRESHOLD = 5.0 frame = self.g_pool.capture._recent_frame if frame is None: logger.error( "Your connection does not seem to be stable enough for " "recording Pupil Mobile via WiFi. We recommend recording " "on the phone.") return if abs(frame.timestamp - start_time_synced) > TIMESTAMP_ERROR_THRESHOLD: logger.error( "Pupil Mobile stream is not in sync. Aborting recording." " Enable the Time Sync plugin and try again.") return session = os.path.join(self.rec_root_dir, self.session_name) try: os.makedirs(session, exist_ok=True) logger.debug( "Created new recordings session dir {}".format(session)) except OSError: logger.error( "Could not start recording. Session dir {} not writable.". format(session)) return self.pldata_writers = {} self.frame_count = 0 self.running = True self.menu.read_only = True recording_uuid = uuid.uuid4() # set up self incrementing folder within session folder counter = 0 while True: self.rec_path = os.path.join(session, "{:03d}/".format(counter)) try: os.mkdir(self.rec_path) logger.debug("Created new recording dir {}".format( self.rec_path)) break except FileExistsError: logger.debug( "We dont want to overwrite data, incrementing counter & trying to make new data folder" ) counter += 1 self.meta_info = RecordingInfoFile.create_empty_file(self.rec_path) self.meta_info.recording_software_name = ( RecordingInfoFile.RECORDING_SOFTWARE_NAME_PUPIL_CAPTURE) self.meta_info.recording_software_version = str(self.g_pool.version) self.meta_info.recording_name = self.session_name self.meta_info.start_time_synced_s = start_time_synced self.meta_info.start_time_system_s = self.start_time self.meta_info.recording_uuid = recording_uuid self.meta_info.system_info = get_system_info() self.video_path = os.path.join(self.rec_path, "world.mp4") if self.raw_jpeg and self.g_pool.capture.jpeg_support: self.writer = JPEG_Writer(self.video_path, start_time_synced) elif hasattr(self.g_pool.capture._recent_frame, "h264_buffer"): self.writer = H264Writer( self.video_path, self.g_pool.capture.frame_size[0], self.g_pool.capture.frame_size[1], int(self.g_pool.capture.frame_rate), ) else: self.writer = MPEG_Writer(self.video_path, start_time_synced) calibration_data_notification_classes = [ CalibrationSetupNotification, CalibrationResultNotification, ] writer = PLData_Writer(self.rec_path, "notify") for note_class in calibration_data_notification_classes: try: file_path = os.path.join(self.g_pool.user_dir, note_class.file_name()) note = note_class.from_dict(load_object(file_path)) note_dict = note.as_dict() note_dict["topic"] = "notify." + note_dict["subject"] writer.append(note_dict) except FileNotFoundError: continue self.pldata_writers["notify"] = writer if self.show_info_menu: self.open_info_menu() logger.info("Started Recording.") self.notify_all({ "subject": "recording.started", "rec_path": self.rec_path, "session_name": self.session_name, "record_eye": self.record_eye, "compression": self.raw_jpeg, "start_time_synced": float(start_time_synced), })
def start(self): session = os.path.join(self.rec_root_dir, self.session_name) try: os.makedirs(session, exist_ok=True) logger.debug("Created new recordings session dir {}".format(session)) except OSError: logger.error( "Could not start recording. Session dir {} not writable.".format( session ) ) return self.pldata_writers = {} self.frame_count = 0 self.running = True self.menu.read_only = True self.start_time = time() start_time_synced = self.g_pool.get_timestamp() recording_uuid = uuid.uuid4() # set up self incrementing folder within session folder counter = 0 while True: self.rec_path = os.path.join(session, "{:03d}/".format(counter)) try: os.mkdir(self.rec_path) logger.debug("Created new recording dir {}".format(self.rec_path)) break except: logger.debug( "We dont want to overwrite data, incrementing counter & trying to make new data folder" ) counter += 1 self.meta_info_path = os.path.join(self.rec_path, "info.csv") with open(self.meta_info_path, "w", newline="", encoding="utf-8") as csvfile: csv_utils.write_key_value_file( csvfile, { "Recording Name": self.session_name, "Start Date": strftime("%d.%m.%Y", localtime(self.start_time)), "Start Time": strftime("%H:%M:%S", localtime(self.start_time)), "Start Time (System)": self.start_time, "Start Time (Synced)": start_time_synced, "Recording UUID": recording_uuid, }, ) self.video_path = os.path.join(self.rec_path, "world.mp4") if self.raw_jpeg and self.g_pool.capture.jpeg_support: self.writer = JPEG_Writer(self.video_path, self.g_pool.capture.frame_rate) elif hasattr(self.g_pool.capture._recent_frame, "h264_buffer"): self.writer = H264Writer( self.video_path, self.g_pool.capture.frame_size[0], self.g_pool.capture.frame_size[1], int(self.g_pool.capture.frame_rate), ) else: self.writer = AV_Writer(self.video_path, fps=self.g_pool.capture.frame_rate) try: cal_pt_path = os.path.join(self.g_pool.user_dir, "user_calibration_data") cal_data = load_object(cal_pt_path) notification = {"subject": "calibration.calibration_data", "record": True} notification.update(cal_data) notification["topic"] = "notify." + notification["subject"] writer = PLData_Writer(self.rec_path, "notify") writer.append(notification) self.pldata_writers["notify"] = writer except FileNotFoundError: pass if self.show_info_menu: self.open_info_menu() logger.info("Started Recording.") self.notify_all( { "subject": "recording.started", "rec_path": self.rec_path, "session_name": self.session_name, "record_eye": self.record_eye, "compression": self.raw_jpeg, } )