def handle_SETUP(self, client_index, request): if self.client_status[client_index] != self.IDLE: return request_dict = rtsp.get_request_dict(request) seq = int(request_dict.get('CSeq')) if seq is None: return transport_info = request_dict.get('Transport') if not transport_info: return self.client_rtp_port[client_index], self.client_rtcp_port[client_index] = util.match_rtp_rtcp_port( transport_info) if not self.client_rtp_port[client_index] or not self.client_rtcp_port[client_index]: return path_tup = util.parse_path(request, self.server_root) self.client_video_filepath[client_index] = path.join(path_tup[0], path_tup[1] + '.ts') util.make_stream_file(self.client_video_filepath[client_index]) self.client_status[client_index] = self.READY response_dict = {'CSeq': str(seq), 'Transport': 'RTP/AVP;unicast;client_port=%d-%d;server_port=%d-%d' % (self.client_rtp_port[client_index], self.client_rtcp_port[client_index], self.server_rtp_port, self.server_rtcp_port), 'Session': str(self.client_session_id[client_index])} response = rtsp.generate_response(response_dict, type=rtsp.OK) self.client_rtsp_socket[client_index].send(response.encode())
def handle_OPTIONS(self, client_index, request): if self.client_status[client_index] != self.IDLE: return request_dict = rtsp.get_request_dict(request) seq = int(request_dict.get('CSeq')) if seq is None: return response_dict = {'CSeq': str(seq), 'Public': 'OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY'} response = rtsp.generate_response(response_dict, type=rtsp.OK) self.client_rtsp_socket[client_index].send(response.encode())
def handle_TEARDOWN(self, client_index, request): request_dict = rtsp.get_request_dict(request) seq = int(request_dict.get('CSeq')) session_id = int(request_dict.get('Session')) if seq is None or session_id != self.client_session_id[client_index]: return response_dict = {'CSeq': str(seq), 'Session': str(self.client_session_id[client_index])} response = rtsp.generate_response(response_dict, type=rtsp.OK) self.client_rtsp_socket[client_index].send(response.encode()) self.destroy_client(client_index)
def handle_PAUSE(self, client_index, request): if self.client_status[client_index] != self.PLAY: return request_dict = rtsp.get_request_dict(request) seq = int(request_dict.get('CSeq')) session_id = int(request_dict.get('Session')) if seq is None or session_id != self.client_session_id[client_index]: return self.client_play_event[client_index].clear() self.client_status[client_index] = self.READY response_dict = {'CSeq': str(seq), 'Session': str(self.client_session_id[client_index])} response = rtsp.generate_response(response_dict, type=rtsp.OK) self.client_rtsp_socket[client_index].send(response.encode())
def handle_DESCRIBE(self, client_index, request): if self.client_status[client_index] != self.IDLE: return request_dict = rtsp.get_request_dict(request) seq = int(request_dict.get('CSeq')) if seq is None: return control_sdp_dict = {'sdp_version': 0, 'user': '******', 'session_id': self.client_session_id[client_index], 'session_version': 1, 'network_type': 'IN', 'ip_type': 'IP4', 'ip': self.server_ip} ts_sdp_dict = {'port': 9832, 'protocol': 'RTP/AVP', 'rate': 90000, 'framerate': 25, 'network_type': 'IN', 'ip_type': 'IP4', 'ip': self.client_addr[client_index][0]} sdp = rtsp.generate_session_sdp(**control_sdp_dict)+ts.generate_media_sdp(**ts_sdp_dict) response_dict = {'CSeq': str(seq), 'Content-length': str(len(sdp)), 'Content-type': 'application/sdp'} response = rtsp.generate_response(response_dict, type=rtsp.OK, other=sdp) self.client_rtsp_socket[client_index].send(response.encode())
def handle_PLAY(self, client_index, request): # if self.client_status[client_index] != self.READY: # return request_dict = rtsp.get_request_dict(request) seq = int(request_dict.get('CSeq')) session_id = int(request_dict.get('Session')) if seq is None or session_id != self.client_session_id[client_index]: return speed = request_dict.get('Speed') if not (speed is None): try: self.client_play_speed[client_index] = float(speed) except: self.client_play_speed[client_index] = 1.0 if not self.client_rtp_thread[client_index]: if self.client_status[client_index] != self.READY: return # start stream video_filepath = self.client_video_filepath[client_index] if video_filepath: self.client_status[client_index] = self.PLAY response_dict = {'CSeq': str(seq), 'Session': str(self.client_session_id[client_index]), 'Range': 'npt=0.000-', 'Speed': str(self.client_play_speed[client_index])} duration = ts.get_video_duration(video_filepath) if duration != -1: duration = duration / 1000 # msec to sec self.client_video_duration[client_index] = duration response_dict['Range'] = 'npt=0.000-%.3f' % self.client_video_duration[client_index] response = rtsp.generate_response(response_dict, type=rtsp.OK) self.client_rtsp_socket[client_index].send(response.encode()) self.client_rtp_thread[client_index] = threading.Thread(target=self.stream, args=(client_index, video_filepath)) self.client_status[client_index] = self.PLAY self.client_play_event[client_index] = threading.Event() self.client_rtp_thread[client_index].start() self.client_rtcp_thread[client_index] = threading.Thread(target=self.control, args=(client_index,)) self.client_rtcp_thread[client_index].start() else: response_dict = {'CSeq': str(seq), 'Session': str(self.client_session_id[client_index]), 'Range': 'npt=now-', 'Speed': str(self.client_play_speed[client_index])} start_time, end_time = util.match_media_time(request) if start_time != 'now': # reposition stream if self.client_status[client_index] != self.READY: return # search for the start packet start_time = float(start_time) * 1000 start_time = (ts.search_reposition_packet(self.client_video_file[client_index], start_time)) / 1000 if self.client_video_duration[client_index]: response_dict['Range'] = 'npt=%.3f-%.3f' % (start_time, self.client_video_duration[client_index]) else: response_dict['Range'] = 'npt=%.3f-' % start_time elif self.client_video_duration[client_index]: # resume stream response_dict['Range'] = 'npt=now-%.3f' % self.client_video_duration[client_index] response = rtsp.generate_response(response_dict, type=rtsp.OK) self.client_rtsp_socket[client_index].send(response.encode()) self.client_status[client_index] = self.PLAY self.client_play_event[client_index].set()