How to set an answer as LocalDescription in aiortc (python)?

1.4k Views Asked by At

I'm trying to perform signaling using python websocket, then create peer2peer connection using aiortc, to achieve webRTC-based video streaming using pure python.

I have managed to send an offer from a peer to another and setRemoteDescription successfully.

client_offer_request = await websocket.recv()
offer_sdp = RTCSessionDescription(client_offer_request, type='offer')
await pc.setRemoteDescription(offer_sdp)

However, when I create answer and setLocalDescription,

# send answer
answer = await pc.createAnswer()
await pc.setLocalDescription(answer)

I get this exception.

await self.ws_handler(self, path)
  File "/xxxxx/WebRTC/websocket_server.py", line 45, in negotiate
    await pc.setLocalDescription(answer)
  File "/xxxxx/lib/python3.6/site-packages/aiortc/rtcpeerconnection.py", line 768, in setLocalDescription
    t._currentDirection = and_direction(t.direction, t._offerDirection)
  File "/xxxxx/lib/python3.6/site-packages/aiortc/rtcpeerconnection.py", line 247, in and_direction
    return sdp.DIRECTIONS[sdp.DIRECTIONS.index(a) & sdp.DIRECTIONS.index(b)]
ValueError: None is not in list

The code is simply like follows:

from aiortc import RTCIceCandidate, MediaStreamTrack, RTCPeerConnection, RTCSessionDescription
import asyncio, websockets

def negotiate():
    player = MediaPlayer('foo.mp4')
    pc = RTCPeerConnection()
    pc.addTrack(player.video)

    clientOffer = await websocket.recv()
    offer_sdp = RTCSessionDescription(clientOffer, type='offer')
    await pc.setRemoteDescription(offer_sdp)

    # send answer
    answer = await pc.createAnswer()
    await pc.setLocalDescription(answer)


start_server = websockets.serve(negotiate, 'localhost', 8765)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
1

There are 1 best solutions below

0
On BEST ANSWER

I have resolved the issue. Since the initiative peer sends an offer which is json string like:

{'sdp': 'v=0\r\no=- 3841969261 3841969261 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=group:BUNDLE 0\r\na=msid-semantic:WMS *\r\nm=video 34067 UDP/TLS/RTP/SAVPF 97 98 99 100 101 102\r\nc=IN \na=sendrecv\r\na=extmap:1 urn:ietf:params:rtp-hdrext:sdes:mid\r\na=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\na=mid:0\r\na=\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=rtcp-mux\r\na=ssrc-group: 124673822\r\na=\r\na=rtpmap:97 VP8/90000\r\na=rtcp-fb:97 nack\r\na=rtcp-fb:97 nack pli\r\na=rtcp-fb:97 goog-remb\r\na=rtpmap:98 rtx/90000\r\na=fmtp:98 apt=97\r\na=rtpmap:99 H264/90000\r\na=rtcp-fb:99 nack\r\na=rtcp-fb:99 nack pli\r\na=rtcp-fb:99 goog-remb\r\na=fmtp:99 packetization-mode=1;level-asymmetry-allowed=1;profile-level-id=42001f\r\na=rtpmap:100 rtx/90000\r\na=fmtp:100 apt=99\r\na=rtpmap:101 H264/90000\r\na=rtcp-fb:101 nack\r\na=rtcp-fb:101 nack pli\r\na=rtcp-fb:101 goog-remb\r\na=fmtp:101 packetization-mode=1;level-asymmetry-allowed=1;profile-level-id=42e01f\r\na=rtpmap:102 rtx/90000\r\na=fmtp:102 apt=101\r\r\n', 'type': 'offer'} 

After receiving such a json string, the receiving peer has to parse it as json and create SDP instance accordingly:

client_offer_request = await websocket.recv()
offer = json.loads(client_offer_request)
offer_sdp = RTCSessionDescription(offer["sdp"], offer["type"])

As such, the issue is orginally from parsing the offer and has nothing to do with setLocalDescription