Beispiel #1
0
async def test_signaling_process() -> None:
    domain = Domain(name="test")
    webrtc = WebRTCConnection(node=domain)

    offer_payload = await webrtc._set_offer()
    offer_dict = json.loads(offer_payload)
    aiortc_session = object_from_string(offer_payload)

    assert "sdp" in offer_dict
    assert "type" in offer_dict
    assert offer_dict["type"] == "offer"
    assert isinstance(aiortc_session, RTCSessionDescription)

    answer_webrtc = WebRTCConnection(node=domain)
    answer_payload = await answer_webrtc._set_answer(payload=offer_payload)
    answer_dict = json.loads(answer_payload)
    aiortc_session = object_from_string(answer_payload)

    assert "sdp" in answer_dict
    assert "type" in answer_dict
    assert answer_dict["type"] == "answer"
    assert isinstance(aiortc_session, RTCSessionDescription)

    response = await webrtc._process_answer(payload=answer_payload)
    assert response is None
Beispiel #2
0
async def run(pc):
    session = ClientSession()

    async with session.ws_connect("ws://39.102.116.49:8080") as ws:
        async for msg in ws:
            if msg.type == WSMsgType.TEXT:
                data = json.loads(msg.data)

                if data["type"] == "offerOrAnswer":
                    await pc.setRemoteDescription(
                        object_from_string(json.dumps(data["msg"])))

                    if data["msg"]["type"] == "offer":
                        pc.addTrack(FlagVideoStreamTrack())
                        await pc.setLocalDescription(await pc.createAnswer())
                        await ws.send_str(
                            json.dumps({
                                "type":
                                "offerOrAnswer",
                                "msg":
                                json.loads(
                                    object_to_string(pc.localDescription)),
                            }))
                elif data["type"] == "candidate":
                    try:
                        await pc.addIceCandidate(
                            object_from_string(json.dumps(data["msg"])))
                    except:
                        pass
Beispiel #3
0
def host_room(room, username):
    queue = Queue()
    threading.Thread(target=get_messages_thread,
                     args=(queue, username)).start()
    rtc = RTCPeerConnection(rtcConfiguration)
    channel = Channel(rtc.createDataChannel("data", negotiated=True, id=0))

    offer = run(rtc.createOffer())
    run(rtc.setLocalDescription(offer))
    res = post("/api/host/%s" % room, {
        "room": room,
        "offer": object_to_string(offer)
    }, username)
    print("Got res %s" % res)
    run(rtc.setRemoteDescription(object_from_string(res["answer"])))
    for candidate in rtc.sctp.transport.transport.iceGatherer.getLocalCandidates(
    ):
        send_message(username, res["username"], "ice",
                     fix_candidate(object_to_string(candidate)))
    time.sleep(3)
    while not queue.empty():
        for message in queue.get():
            if message["type"] == "ice":
                print("Got candidate: %s" % message["data"])
                rtc.sctp.transport.transport.addRemoteCandidate(
                    object_from_string(fix_candidate2(message["data"])))
    rtc.sctp.transport.transport.addRemoteCandidate(None)

    return channel, rtc
    async def consume_signaling(self, pc, signaling):

        # Async keep-alive connection thread
        while self.available:
            sleep_time = 0
            if self._msg == "":
                await asyncio.sleep(sleep_time)
                continue

            obj = object_from_string(self._msg)

            if isinstance(obj, RTCSessionDescription):
                await pc.setRemoteDescription(obj)
                if obj.type == "offer":
                    # send answer
                    await pc.setLocalDescription(await pc.createAnswer())
                    local_description = object_to_string(pc.localDescription)

                    response = {
                        MSG_FIELD.TYPE: NODE_EVENTS.WEBRTC_ANSWER,
                        MSG_FIELD.FROM: self._origin,
                        MSG_FIELD.PAYLOAD: local_description,
                    }

                    forward_payload = {
                        MSG_FIELD.TYPE: GRID_EVENTS.FORWARD,
                        MSG_FIELD.DESTINATION: self._destination,
                        MSG_FIELD.CONTENT: response,
                    }
                    self._grid.send(json.dumps(forward_payload))
                    sleep_time = 10
            self._msg = ""
        raise Exception
Beispiel #5
0
    async def consume_signaling(self, pc, signaling):
        while True:
            if self._msg == "":
                await asyncio.sleep(5)
                continue

            obj = object_from_string(self._msg)

            if isinstance(obj, RTCSessionDescription):
                await pc.setRemoteDescription(obj)

                if obj.type == "offer":
                    # send answer
                    await pc.setLocalDescription(await pc.createAnswer())
                    local_description = object_to_string(pc.localDescription)

                    response = {
                        MSG_FIELD.TYPE: NODE_EVENTS.WEBRTC_ANSWER,
                        MSG_FIELD.FROM: self._origin,
                        MSG_FIELD.PAYLOAD: local_description,
                    }

                    forward_payload = {
                        MSG_FIELD.TYPE: GRID_EVENTS.FORWARD,
                        MSG_FIELD.DESTINATION: self._destination,
                        MSG_FIELD.CONTENT: response,
                    }
                    self._grid.send(json.dumps(forward_payload))
            elif isinstance(obj, RTCIceCandidate):
                pc.addIceCandidate(obj)
            elif obj is BYE:
                print("Exiting")
                break
            self._msg = ""
Beispiel #6
0
async def websocket_coroutine():
    session = aiohttp.ClientSession()
    async with session.ws_connect(WEBSOCKET_URI) as ws:
        print("websocket connected")
        request = json.dumps({
            "what": "call"
        })
        await ws.send_str(request)

        async for msg in ws:
            print(msg)
            if msg.type == aiohttp.WSMsgType.TEXT:
                params = json.loads(msg.data)
                print(params)
                if params["what"] == "offer":
                    print("offer received")
                    uv4l_sdp = object_from_string(params["data"])
                    await pc.setRemoteDescription(uv4l_sdp)
                    await pc.setLocalDescription(await pc.createAnswer())
                    local_sdp = object_to_string(pc.localDescription)
                    print(local_sdp)
                    print(type(local_sdp))
                    await ws.send_str(json.dumps({
                        "what": "answer",
                        "data": local_sdp
                    }))

                elif params['what'] == 'hangup':
                    print("hangup received")
                    await ws.close()
                    break
                else:
                    print(msg)
            elif msg.type == aiohttp.WSMsgType.ERROR:
                break
Beispiel #7
0
 async def receive(self):
     if self.__messages:
         message = self.__messages.pop(0)
     else:
         message = await self.websocket.recv()
         message = json.loads(message)['msg']
     print('<', message)
     return object_from_string(message)
Beispiel #8
0
 async def receive(self):
     message = self._webrtc_server.receive_message(self._room,
                                                   self.__peer_id)
     # if self._javascript_callable:
     #     print('ColabSignaling: sending message to Javascript peer:', message)
     # else:
     #     print('ColabSignaling: sending message to Python peer:', message)
     if message and type(message) == str and not self._javascript_callable:
         message = object_from_string(message)
     return message
Beispiel #9
0
    async def receive(self):
        if self.__messages:
            message = self.__messages.pop(0)
        else:
            message = self.recv_nowait()
            if message:
                message = json.loads(message)["msg"]

        if message:
            logger.debug("< " + message)
            return object_from_string(message)
Beispiel #10
0
    async def create_answer(self, offer):
        offer = object_from_string(offer)

        await self.pc.setRemoteDescription(offer)
        await self.pc.setLocalDescription(await self.pc.createAnswer())

        @self.pc.on("datachannel")
        def on_datachannel(channel):
            self.channel = channel

        return object_to_string(self.pc.localDescription)
Beispiel #11
0
 def send_sync(self, message):
     print('send:', message)
     if type(message) == str:
         message_json = json.loads(message)
         if 'candidate' in message_json:
             message_json['type'] = 'candidate'
             message_json["id"] = message_json["sdpMid"]
             message_json["label"] = message_json["sdpMLineIndex"]
             message = json.dumps(message_json)
             message = object_from_string(message)
     loop = asyncio.get_event_loop()
     return loop.run_until_complete(self.send(message))
 def test_candidate_from_string(self):
     candidate = object_from_string(
         '{"candidate": "candidate:0 1 UDP 2122252543 192.168.99.7 33543 typ host", "id": "audio", "label": 0, "type": "candidate"}')  # noqa
     self.assertEqual(candidate.component, 1)
     self.assertEqual(candidate.foundation, '0')
     self.assertEqual(candidate.ip, '192.168.99.7')
     self.assertEqual(candidate.port, 33543)
     self.assertEqual(candidate.priority, 2122252543)
     self.assertEqual(candidate.protocol, 'UDP')
     self.assertEqual(candidate.sdpMid, 'audio')
     self.assertEqual(candidate.sdpMLineIndex, 0)
     self.assertEqual(candidate.type, 'host')
Beispiel #13
0
async def WebRTCSignalingService(request):
    ws = web.WebSocketResponse()
    await ws.prepare(request)

    async for msg in ws:
        print(msg)
        if msg.type == aiohttp.WSMsgType.TEXT:
            params = json.loads(msg.data)
            print(type(params))
            print(params)

            if params["what"] == "call":
                print("call received")
                # prepare media
                pc.addTrack(VideoStreamTrack)
                await pc.setLocalDescription(await pc.createOffer())
                uv4l_sdp = object_to_string(pc.localDescription)
                print(type(uv4l_sdp))
                await ws.send_str(
                    json.dumps({
                        "what": "offer",
                        "data": uv4l_sdp
                    }))

            elif params["what"] == "answer":
                print("answer received")
                local_sdp = object_from_string(params["data"])
                await pc.setRemoteDescription(local_sdp)
                print('setRemoteDescription(<local_sdp>)')
                # await pc.setRemoteDescription(local_sdp)

            elif params["what"] == "addIceCandidate":
                print("addIceCandidate received")
            elif params['what'] == 'hangup':
                print("hangup received")
                await ws.close()
            else:
                await ws.send_json(msg.data + '\n received.')
        elif msg.type == aiohttp.WSMsgType.ERROR:
            print('ws connection closed with exception %s' % ws.exception())

    print('websocket connection closed')

    return ws
Beispiel #14
0
    async def consume_signaling(self, pc, signaling):
        """Consume signaling to go through all the webrtc connection protocol.

        Args:
            pc: Peer Connection.
            signaling: Webrtc signaling instance.
        Exception:
            ConnectionClosedException: Exception used to finish this connection
            and close this thread.
        """
        # Async keep-alive connection thread
        while self.available:
            sleep_time = 0
            if self._msg == "":
                await asyncio.sleep(sleep_time)
                continue

            obj = object_from_string(self._msg)

            if isinstance(obj, RTCSessionDescription):
                await pc.setRemoteDescription(obj)
                if obj.type == "offer":
                    # send answer
                    await pc.setLocalDescription(await pc.createAnswer())
                    local_description = object_to_string(pc.localDescription)

                    response = {
                        MSG_FIELD.TYPE: NODE_EVENTS.WEBRTC_ANSWER,
                        MSG_FIELD.FROM: self._origin,
                        MSG_FIELD.PAYLOAD: local_description,
                    }

                    forward_payload = {
                        MSG_FIELD.TYPE: GRID_EVENTS.FORWARD,
                        MSG_FIELD.DESTINATION: self._destination,
                        MSG_FIELD.CONTENT: response,
                    }
                    self._grid.send(json.dumps(forward_payload))
                    sleep_time = 10
            self._msg = ""
        raise Exception
Beispiel #15
0
    async def _process_answer(self, payload: str) -> Union[str, None]:
        # Converts payload received by
        # the other peer in aioRTC Object
        # instance.
        try:
            msg = object_from_string(payload)

            # Check if Object instance is a
            # description of RTC Session.
            if isinstance(msg, RTCSessionDescription):

                # Use the target's network address/metadata
                # to set the remote description of this peer.
                # This will basically say to this peer how to find/connect
                # with to other peer.
                await self.peer_connection.setRemoteDescription(msg)

                # If it's an offer message type,
                # generates your own local description
                # and send it back in order to tell
                # to the other peer how to find you.
                if msg.type == "offer":
                    # Set peer_connection to generate an offer message type.
                    await self.peer_connection.setLocalDescription(
                        await self.peer_connection.createAnswer())

                    # Generates the local description structure
                    # and serialize it to string afterwards.
                    local_description = object_to_string(
                        self.peer_connection.localDescription)

                    # Returns the answer peer's local description
                    return local_description
        except Exception as e:
            log = f"Got an exception in WebRTCConnection _process_answer. {e}"
            logger.error(log)
            raise e
        return None
Beispiel #16
0
 def test_bye_from_string(self):
     self.assertEqual(object_from_string('{"type": "bye"}'), BYE)
Beispiel #17
0
 async def set_answer(self, answer):
     answer = object_from_string(answer)
     await self.pc.setRemoteDescription(answer)