async def test_frame_rate(self): frame = numpy.random.rand(720, 1280, 3) frame = numpy.uint8(frame * 100) self.last_time = time.time() def video_frame_coroutine(): while True: yield frame self.received_frames = [] self.start_time = 0 def frame_consumer(frame): if len(self.received_frames) == 0: print('timer start') self.start_time = time.time() self.received_frames.append(frame) if len(self.received_frames) == 100: self.stop_time = time.time() print('timer stop') #print('received frame: ' + str(len(self.received_frames))) self.peer2 = Peer('ws://localhost:8080', peer_type='test', id='server2', frame_generator=video_frame_coroutine, frame_rate=10) self.peer = Peer('ws://localhost:8080', peer_type='media-server', id='server1', frame_consumer=frame_consumer) await self.peer.open() await self.peer2.open() async def peer2_actions(): await self.peer2.listen_connections() await self.peer2.accept_connection() print('connecting...') peer2_task = asyncio.create_task(peer2_actions()) peer1_task = asyncio.create_task(self.peer.connect_to('server2')) await asyncio.gather(peer1_task, peer2_task) print('connected!') async def wait_frames(): while len(self.received_frames) < 100: await asyncio.sleep(0.1) try: await asyncio.wait_for(wait_frames(), timeout=15.0) self.assertTrue(len(self.received_frames) >= 100) self.assertIsInstance(self.received_frames[0], numpy.ndarray) self.assertEqual(self.received_frames[0].shape, (720, 1280, 3)) time_100_frames = self.stop_time - self.start_time print(f'Time for 100 frames: {time_100_frames}') self.assertTrue(time_100_frames > 9 and time_100_frames < 11) except asyncio.TimeoutError: print('timeout!') raise finally: await self.peer.disconnect() await self.peer2.disconnect() await self.peer.close() await self.peer2.close()
def __init__(self, server_address, server_port, source, peer_id, peer_type='stream_capture', format=None, metadata=None, stream_manager_id=None, auto_connect=False, remotePeerId=None): self.id = peer_id self.metadata = metadata self.stream_manager_id = stream_manager_id self.remotePeerId = remotePeerId if auto_connect: self.remotePeerType = 'stream_manager' else: self.remotePeerType = None self._frame_handlers = [] def frame_consumer(frame): for handler in self._frame_handlers: handler(frame) self.peer = Peer(f'wss://{server_address}:{server_port}', id=peer_id, peer_type=peer_type, frame_consumer=frame_consumer, media_source=source, ssl_context=ssl_context, media_source_format=format) self.running = False
async def test_video_player(self): self.received_frames = [] def frame_consumer(frame): self.received_frames.append(frame) #print('received frame: ' + str(len(self.received_frames))) self.peer2 = Peer('ws://localhost:8080', peer_type='media-player', id='player1', media_source='./test/SampleVideo_1280x720_1mb.mp4', media_source_format='mp4') self.peer = Peer('ws://localhost:8080', peer_type='media-client', id='client1', frame_consumer=frame_consumer) await self.peer.open() await self.peer2.open() async def peer2_actions(): await self.peer2.listen_connections() await self.peer2.accept_connection() print('connecting...') peer2_task = asyncio.create_task(peer2_actions()) peer1_task = asyncio.create_task(self.peer.connect_to('player1')) await asyncio.gather(peer1_task, peer2_task) print('connected!') async def wait_frames(): while len(self.received_frames) < 130: await asyncio.sleep(0.1) try: print('Waiting video to complete...') # await asyncio.wait_for(wait_frames(), timeout=7.0) await self.peer2.disconnection_event.wait() self.assertTrue(len(self.received_frames) >= 130) except asyncio.TimeoutError: print('timeout!') print('Frames:', len(self.received_frames)) finally: await self.peer.disconnect() await self.peer2.disconnect() await self.peer.close() await self.peer2.close()
def setUp(self): self.peer = Peer('ws://localhost:8080', peer_type='media-server', id='server1') self.peer2 = Peer('ws://localhost:8080', peer_type='test', id='server2')
class TestPeer(unittest.TestCase): @classmethod def setUpClass(self): try: self.server = subprocess.Popen( ['node', './test/testServer.js'], stderr=subprocess.PIPE, stdout=subprocess.PIPE) except: print('Test server error!') raise try: print(self.server.communicate(timeout=1)) except subprocess.TimeoutExpired: print('nothing from server') # 156.148.132.107 @classmethod def tearDownClass(self): try: print('Getting messages from server...') outs, errs = self.server.communicate(timeout=1) print('Outs: ' + outs.decode('utf8') + '. Errs: ' + errs.decode('utf8')) except subprocess.TimeoutExpired: self.server.kill() print('Final messages from server...') outs, errs = self.server.communicate(timeout=1) print('Outs: ' + outs.decode('utf8') + '. Errs: ' + errs.decode('utf8')) except Exception as err: print(err) def setUp(self): self.peer = Peer('ws://*****:*****@unittest.skip("demonstrating skipping") @async_test async def test_server_connection(self): self.assertEqual(self.peer.readyState, PeerState.STARTING) await self.peer.open() self.assertEqual(self.peer.readyState, PeerState.ONLINE) await self.peer.close() self.assertEqual(self.peer.readyState, PeerState.CLOSED) @unittest.skip("demonstrating skipping") @async_test async def test_peers(self): await self.peer.open() peers = await self.peer.get_peers() self.assertIsInstance(peers, list) @unittest.skip("demonstrating skipping") @async_test async def test_connect(self): await self.peer.open() await self.peer2.open() async def peer2_actions(): print('listening...') try: await self.peer2.listen_connections() except asyncio.CancelledError: print('canceled!') self.peer2.disconnect() raise await asyncio.sleep(0.5) self.assertEqual(self.peer2.readyState, PeerState.CONNECTING) self.assertEqual(self.peer.readyState, PeerState.CONNECTING) print('receiving call...') await self.peer2.accept_connection() print('negotiating...') peer2_task = asyncio.create_task(peer2_actions()) print('calling...') peer1_task = asyncio.create_task(self.peer.connect_to('server2')) await peer1_task print('answering...') await asyncio.wait_for(peer2_task, 10) print('connected!') self.assertEqual(self.peer2.readyState, PeerState.CONNECTED) self.assertEqual(self.peer.readyState, PeerState.CONNECTED) await self.peer.disconnect() print(self.peer.readyState) self.assertEqual(self.peer.readyState, PeerState.ONLINE) await self.peer2.disconnect() @unittest.skip("demonstrating skipping") @async_test async def test_datachannel_poll(self): await self.peer.open() await self.peer2.open() async def peer2_actions(): await self.peer2.listen_connections() await self.peer2.accept_connection() peer2_task = asyncio.create_task(peer2_actions()) print('calling...') peer1_task = asyncio.create_task(self.peer.connect_to('server2')) try: await peer1_task print('answering...') await asyncio.wait_for(peer2_task, 10) print('connected!') await self.peer.send('ciao') data = await self.peer2.recv() self.assertEqual(data, 'ciao') await self.peer2.send({'foo': 'bar'}) data = await self.peer.recv() self.assertIsInstance(data, dict) self.assertEqual(data['foo'], 'bar') except Exception as err: print(err) raise finally: await self.peer.disconnect() await self.peer2.disconnect() await self.peer.close() await self.peer2.close() @unittest.skip("demonstrating skipping") @async_test async def test_datachannel_stream(self): await self.peer.open() await self.peer2.open() async def peer2_actions(): await self.peer2.listen_connections() await self.peer2.accept_connection() peer2_task = asyncio.create_task(peer2_actions()) print('calling...') peer1_task = asyncio.create_task(self.peer.connect_to('server2')) try: await peer1_task print('answering...') await asyncio.wait_for(peer2_task, 10) print('connected!') async def sender(): sent = 0 while sent < 10: await self.peer.send({'inc': 1}) sent += 1 await asyncio.sleep(0.01) self.count = 0 def on_data(data): self.count += data['inc'] self.count2 = 0 async def on_data_async(data): self.count2 += data['inc'] self.peer2.add_data_handler(on_data) self.peer2.add_data_handler(on_data_async) await asyncio.wait_for(sender(), timeout=1) await asyncio.sleep(0.2) self.assertEqual(self.count, 10) self.assertEqual(self.count2, 10) print('Data test OK') except Exception as err: print(err) raise finally: await self.peer.disconnect() await self.peer2.disconnect() await self.peer.close() await self.peer2.close() # @unittest.skip("demonstrating skipping") @async_test async def test_video_and_data(self): def video_frame_generator(): print('generator started') frames = 0 while True: frame = numpy.random.rand(720, 1280, 3) frame = numpy.uint8(frame * 100) frames += 1 #print('generating frame: ' + str(frames)) yield frame self.received_frames = [] def frame_consumer(frame): self.received_frames.append(frame) #print('received frame: ' + str(len(self.received_frames))) self.peer2 = Peer('ws://*****:*****@unittest.skip("demonstrating skipping") @async_test async def test_frame_rate(self): frame = numpy.random.rand(720, 1280, 3) frame = numpy.uint8(frame * 100) self.last_time = time.time() def video_frame_coroutine(): while True: yield frame self.received_frames = [] self.start_time = 0 def frame_consumer(frame): if len(self.received_frames) == 0: print('timer start') self.start_time = time.time() self.received_frames.append(frame) if len(self.received_frames) == 100: self.stop_time = time.time() print('timer stop') #print('received frame: ' + str(len(self.received_frames))) self.peer2 = Peer('ws://*****:*****@unittest.skip("demonstrating skipping") @async_test async def test_video_player(self): self.received_frames = [] def frame_consumer(frame): self.received_frames.append(frame) #print('received frame: ' + str(len(self.received_frames))) self.peer2 = Peer('ws://localhost:8080', peer_type='media-player', id='player1', media_source='./test/SampleVideo_1280x720_1mb.mp4', media_source_format='mp4') self.peer = Peer('ws://localhost:8080', peer_type='media-client', id='client1', frame_consumer=frame_consumer) await self.peer.open() await self.peer2.open() async def peer2_actions(): await self.peer2.listen_connections() await self.peer2.accept_connection() print('connecting...') peer2_task = asyncio.create_task(peer2_actions()) peer1_task = asyncio.create_task(self.peer.connect_to('player1')) await asyncio.gather(peer1_task, peer2_task) print('connected!') async def wait_frames(): while len(self.received_frames) < 130: await asyncio.sleep(0.1) try: print('Waiting video to complete...') # await asyncio.wait_for(wait_frames(), timeout=7.0) await self.peer2.disconnection_event.wait() self.assertTrue(len(self.received_frames) >= 130) except asyncio.TimeoutError: print('timeout!') print('Frames:', len(self.received_frames)) finally: await self.peer.disconnect() await self.peer2.disconnect() await self.peer.close() await self.peer2.close()
async def test_video_and_data(self): def video_frame_generator(): print('generator started') frames = 0 while True: frame = numpy.random.rand(720, 1280, 3) frame = numpy.uint8(frame * 100) frames += 1 #print('generating frame: ' + str(frames)) yield frame self.received_frames = [] def frame_consumer(frame): self.received_frames.append(frame) #print('received frame: ' + str(len(self.received_frames))) self.peer2 = Peer('ws://localhost:8080', peer_type='test', id='server2', frame_generator=video_frame_generator) self.peer = Peer('ws://localhost:8080', peer_type='media-server', id='server1', frame_consumer=frame_consumer) await self.peer.open() await self.peer2.open() self.sent = 0 async def sender(): frames = 0 while frames < 10: frames = len(self.received_frames) await self.peer.send({'credit': 1}) self.sent += 1 await asyncio.sleep(0.01) self.credits = 0 def on_data(data): self.credits += data['credit'] self.peer2.add_data_handler(on_data) async def peer2_actions(): await self.peer2.listen_connections() await self.peer2.accept_connection() print('connecting...') peer2_task = asyncio.create_task(peer2_actions()) peer1_task = asyncio.create_task(self.peer.connect_to('server2')) await asyncio.gather(peer1_task, peer2_task) print('connected!') sender_task = asyncio.create_task(sender()) async def wait_frames(): while len(self.received_frames) < 15: await asyncio.sleep(0.1) try: await asyncio.wait_for(wait_frames(), timeout=5.0) await sender_task self.assertTrue(len(self.received_frames) >= 15) self.assertIsInstance(self.received_frames[0], numpy.ndarray) self.assertEqual(self.received_frames[0].shape, (720, 1280, 3)) self.assertTrue(self.credits == self.sent) except asyncio.TimeoutError: print('timeout!') raise finally: await self.peer.disconnect() await self.peer2.disconnect() await self.peer.close() await self.peer2.close()
class DeepIO: """ The DeepIO class represents the WebRTC-based connection between the local application and the remote DEEP_Framework processing core. # Arguments server_address (str): URL or IP of the DEEP_Framework server. server_port (str): Port of the DEEP_Framework server. source (str): URL or path of the video source. peer_id (str): Peer unique identification string. Must be unique among all connected peers. It can be used by other clients to find and connect to this peer. peer_type (str): Peer type. It's used by other peers to know the role of the peer in the current application. Default 'stream_capture'. format (str): Format of the video source. Defaults to autodetect. metadata (str|dict): String or dictionary that describes the video source and its attributes. stream_manager_id (str): ID of the remote peer. If specified it will specifically connect to that peer. auto_connect (bool): If true it will automatically connect with the first stream_manager peer available otherwise it will wait for remote connections. Default `False`. """ def __init__(self, server_address, server_port, source, peer_id, peer_type='stream_capture', format=None, metadata=None, stream_manager_id=None, auto_connect=False, remotePeerId=None): self.id = peer_id self.metadata = metadata self.stream_manager_id = stream_manager_id self.remotePeerId = remotePeerId if auto_connect: self.remotePeerType = 'stream_manager' else: self.remotePeerType = None self._frame_handlers = [] def frame_consumer(frame): for handler in self._frame_handlers: handler(frame) self.peer = Peer(f'wss://{server_address}:{server_port}', id=peer_id, peer_type=peer_type, frame_consumer=frame_consumer, media_source=source, ssl_context=ssl_context, media_source_format=format) self.running = False async def _on_data(self, data): # logging.info(f'[{self.id}]: Remote message: {str(data)}') if data['type'] == 'data': acknowledge = { 'type': 'acknowledge', 'rec_time': data['rec_time'] } await self.peer.send(acknowledge) def add_data_handler(self, handler): """ Adds a function to the list of handlers to call whenever data is received. # Arguments handler (function|coroutine): A function or asyncio coroutine that will be called with the data object. """ self.peer.add_data_handler(handler) def add_frame_handler(self, handler): """ Adds a function to the list of handlers to call whenever a frame is received. # Arguments handler (function): A function that will be called with the last received frame. """ self._frame_handlers.append(handler) def send_metadata(self, metadata): """ Send the new metadata to the connected remote peer. # Arguments metadata (str|dict): String or dictionary that describes the video source and its attributes. # Returns asyncio.Task: Sending task. """ return asyncio.create_task(self.peer.send({'type': 'metadata', 'metadata': metadata})) async def start(self): await self.peer.open() self.peer.add_data_handler(self._on_data) try: while True: if self.stream_manager_id: await self.peer.connect_to(self.stream_manager_id) logging.info(f'connected to %s', self.stream_manager_id) elif self.remotePeerType: # List connected peers peers = await self.peer.get_peers() for peer in peers: if peer['type'] == self.remotePeerType and not peer['busy']: await self.peer.connect_to(peer['id']) self.stream_manager_id = peer['id'] logging.info(f'connected to {self.remotePeerType} with id: {self.stream_manager_id}') if self.remotePeerId: await self.peer.send({'type': 'source', 'peerId': self.remotePeerId}) else: await self.peer.send({'type': 'source', 'peerId': self.id}) break if self.stream_manager_id == None: await asyncio.sleep(1) continue else: logging.info(f'[{self.id}]: Waiting peer connections...') self.stream_manager_id = await self.peer.listen_connections() logging.info(f'[{self.id}]: Connection request from peer: {self.stream_manager_id}') await self.peer.accept_connection() await self.peer.send({'type': 'metadata', 'metadata': self.metadata}) while self.peer.readyState != PeerState.ONLINE: await asyncio.sleep(1) await asyncio.sleep(1) self.stream_manager_id = None except Exception as err: logging.error(f'[{self.id}]: Execution error: {err}') await self.peer.close() raise err async def stop(self): await self.peer.close() def run(self): """ Start the event loop of the DeepIO application """ if self.running: return self.running = True # run event loop try: loop = asyncio.get_event_loop() except: loop = asyncio.new_event_loop() try: loop.run_until_complete(self.start()) #asyncio.run(asyncio.gather(demo1.start(), demo2.start())) except KeyboardInterrupt: logging.info(' -> End signal') finally: # cleanup logging.info(' -> Cleaning...') loop.run_until_complete(self.stop())