def _init(self, agent_id, keepalive_endpoint, self_request_endpoint, max_recorder): self._agent_id = agent_id self._keepalive_endpoint = keepalive_endpoint self._keepalive_client = RecordAgentKeepaliveClient(keepalive_endpoint) self._self_request_endpoint = self_request_endpoint self._max_recorder = max_recorder self._tasks = {} self._greenlet_funcs.append(self._keepalive_greenlet)
class RecordAgentManager(BaseManager): def _init(self, agent_id, keepalive_endpoint, self_request_endpoint, max_recorder): self._agent_id = agent_id self._keepalive_endpoint = keepalive_endpoint self._keepalive_client = RecordAgentKeepaliveClient(keepalive_endpoint) self._self_request_endpoint = self_request_endpoint self._max_recorder = max_recorder self._tasks = {} self._greenlet_funcs.append(self._keepalive_greenlet) def start_record(self, session_id, project_name, camera_id, stream_url, upload_cbk_url, prerecord_seconds): log.info('Try to start record session <{0}> of project <{1}> camera <{2}> on {3}'.format( session_id, project_name, camera_id, stream_url) ) try: if not Load.is_available(self.working_load): log.warn('Working load is full, not able to take more record job') return {'result': 'error', 'load': self.working_load} if session_id in self._tasks: log.warn('Record session {0} already started'.format(session_id)) return {'result': 'ok', 'load': self.working_load} record_proc = self._start_recorder(session_id, project_name, camera_id, stream_url, upload_cbk_url, prerecord_seconds) self._tasks[session_id] = { 'stream_url': stream_url, 'upload_cbk_url': upload_cbk_url, 'proc': record_proc, } log.info('Record session {0} started successfully'.format(session_id)) return {'result': 'ok', 'load': self.working_load} except Exception: log.exception('Failed to start record session {0}'.format(session_id)) return {'result': 'error', 'load': self.working_load} def stop_record(self, session_id): log.info('Try to stop record session {0}'.format(session_id)) session = self._tasks.pop(session_id, None) if session: self._stop_recorder(session['proc']) pass log.info('Record session {0} stopped successfully'.format(session_id)) else: log.warn('No such session {0} exists'.format(session_id)) return {'result': 'ok', 'load': self.working_load} def _start_recorder(self, session_id, project_name, camera_id, src_url, upload_cbk_url, prerecord_seconds): upload_cbk_url = 'ivr' + upload_cbk_url.strip()[upload_cbk_url.find('://'):] cmd = ( 'ffmpeg_ivr', '-log_rotate', 'ffmpeg_ivr_{0}_{1}.log:5242880:10'.format(project_name, camera_id), '-xerror', '-input_io_timeout', '10000', '-i', src_url, '-codec', 'copy', '-bsf:v', 'h264_mp4toannexb', '-f', 'cseg', '-cseg_cache_time', STRING(prerecord_seconds), '-cseg_time', '10', '-cseg_flags', 'nonblock', upload_cbk_url ) log.info('New process {0}'.format(' '.join(cmd))) record_proc = ProcWatcher( cmd, age_time=24*60*60, error_restart_interval=60 ) record_proc.start() return record_proc def _stop_recorder(self, record_proc): record_proc.stop() def _keepalive_greenlet(self): while True: try: self._keepalive_client.keepalive( self._agent_id, self._self_request_endpoint, self.working_load, [session_id for session_id in self._tasks]) except Exception: log.exception('Failed to keepalive to {0}'.format(self._keepalive_endpoint)) finally: time.sleep(20) @property def working_load(self): return len(self._tasks)*100/self._max_recorder if self._max_recorder else 0