[docs]classRTCServer(VideoStreamTrack):"""This Obj it's responsible to create the VideoStream for the WebRTCServer """def__init__(self,image_buffer_manager,):"""Initialize the RTCServer Parameters ---------- image_buffer_manager : ImageBufferManager """super().__init__()self.frame=Noneself.buffer_manager=image_buffer_manager
[docs]asyncdefrecv(self):"""Return a VideoFrame to be used in the WebRTC Server The frame will be created using the image stored in the shared memory Returns ------- frame : VideoFrame """pts,time_base=awaitself.next_timestamp()width,height,image=self.buffer_manager.get_current_frame()if(self.frameisNoneorself.frame.planes[0].width!=widthorself.frame.planes[0].height!=height):ifCYTHON_AVAILABLE:self.frame=FuryVideoFrame(width,height,"rgb24")self.image=imageifnotCYTHON_AVAILABLE:# if the buffer it's already flipped# self.frame.planes[0].update(self.image)self.image=np.frombuffer(self.image,"uint8")[0:width*height*3].reshape((height,width,3))self.image=np.flipud(self.image)self.frame=VideoFrame.from_ndarray(self.image)else:self.frame.update_from_buffer(self.image)self.frame.pts=ptsself.frame.time_base=time_basereturnself.frame
[docs]defrelease(self):"""Release the RTCServer"""try:ifself.streamisNone:returnself.stream.release()self.stream=NoneexceptAttributeError:pass
[docs]@warn_on_args_to_kwargs()defweb_server_raw_array(*,image_buffers=None,info_buffer=None,queue_head_tail_buffer=None,queue_buffer=None,port=8000,host="localhost",provides_mjpeg=True,provides_webrtc=True,ms_jpeg=16,run_app=True,):"""This will create a streaming webserver running on the given port and host using RawArrays. Parameters ---------- image_buffers : list of buffers A list of buffers with each one containing a frame. info_buffer : buffer A buffer with the information about the current frame to be streamed and the respective sizes queue_head_tail_buffer : buffer If buffer is passed than this Obj will read a a already created RawArray. queue_buffer : buffer If queue_buffer is passed than this Obj will read a a already created RawArray containing the user interactions events stored in the queue_buffer. port : int, optional Port to be used by the aiohttp server host : str, optional, default localhost host to be used by the aiohttp server provides_mjpeg : bool, default True If a MJPEG streaming should be available. If True you can consume that through host:port/video/mjpeg or if you want to interact you can consume that through your browser http://host:port?encoding=mjpeg provides_webrtc : bool, default True If a WebRTC streaming should be available. http://host:port ms_jpeg : float, optional This it's used only if the MJPEG will be used. The ms_jpeg represents the amount of milliseconds between to consecutive calls of the jpeg encoding. run_app : bool, default True This will run the aiohttp application. The False condition is used just to be able to test the server. """image_buffer_manager=RawArrayImageBufferManager(image_buffers=image_buffers,info_buffer=info_buffer)rtc_server=Nonecreate_webrtc=provides_webrtcandWEBRTC_AVAILABLEifcreate_webrtc:rtc_server=RTCServer(image_buffer_manager)else:provides_mjpeg=Truecircular_queue=Noneifqueue_bufferisnotNone:circular_queue=ArrayCircularQueue(dimension=_CQUEUE.dimension,head_tail_buffer=queue_head_tail_buffer,buffer=queue_buffer,)app_fury=get_app(rtc_server=rtc_server,circular_queue=circular_queue,image_buffer_manager=image_buffer_manager,provides_mjpeg=provides_mjpeg,)ifrun_app:web.run_app(app_fury,host=host,port=port,ssl_context=None)ifrtc_serverisnotNone:rtc_server.release()ifcircular_queueisnotNone:circular_queue.cleanup()image_buffer_manager.cleanup()
[docs]@warn_on_args_to_kwargs()defweb_server(*,image_buffer_names=None,info_buffer_name=None,queue_head_tail_buffer_name=None,queue_buffer_name=None,port=8000,host="localhost",provides_mjpeg=True,provides_webrtc=True,avoid_unlink_shared_mem=True,ms_jpeg=16,run_app=True,):"""This will create a streaming webserver running on the given port and host using SharedMemory. Parameters ---------- image_buffers_name : list of str A list of buffers with each one containing a frame. info_buffer_name : str A buffer with the information about the current frame to be streamed and the respective sizes queue_head_tail_buffer_name : str, optional If buffer is passed than this Obj will read a a already created RawArray. buffer_name : str, optional If queue_buffer is passed than this Obj will read a a already created RawArray containing the user interactions events stored in the queue_buffer. port : int, optional Port to be used by the aiohttp server host : str, optional, default localhost host to be used by the aiohttp server provides_mjpeg : bool, default True If a MJPEG streaming should be available. If True you can consume that through host:port/video/mjpeg or if you want to interact you can consume that through your browser http://host:port?encoding=mjpeg provides_webrtc : bool, default True If a WebRTC streaming should be available. http://host:port avoid_unlink_shared_mem : bool, default False If True, then this will apply a monkey-patch solution to a python>=3.8 core bug ms_jpeg : float, optional This it's used only if the MJPEG will be used. The ms_jpeg represents the amount of milliseconds between to consecutive calls of the jpeg encoding. run_app : bool, default True This will run the aiohttp application. The False condition is used just to be able to test the server. """ifavoid_unlink_shared_memandPY_VERSION_8:remove_shm_from_resource_tracker()image_buffer_manager=SharedMemImageBufferManager(image_buffer_names=image_buffer_names,info_buffer_name=info_buffer_name)rtc_server=Nonecreate_webrtc=provides_webrtcandWEBRTC_AVAILABLEifcreate_webrtc:rtc_server=RTCServer(image_buffer_manager)else:provides_mjpeg=Truecircular_queue=Noneifqueue_buffer_nameisnotNone:circular_queue=SharedMemCircularQueue(dimension=_CQUEUE.dimension,buffer_name=queue_buffer_name,head_tail_buffer_name=queue_head_tail_buffer_name,)app_fury=get_app(rtc_server=rtc_server,circular_queue=circular_queue,image_buffer_manager=image_buffer_manager,provides_mjpeg=provides_mjpeg,)ifrun_app:web.run_app(app_fury,host=host,port=port,ssl_context=None)ifrtc_serverisnotNone:rtc_server.release()ifcircular_queueisnotNone:circular_queue.cleanup()image_buffer_manager.cleanup()