Search code examples
pythonwebrtcstunturnaiortc

Webrtc on Python failing to change ICE connection state between peers


First, I want to mention that I am very new to WebRTC, so any advice would be very helpful.

Currently I am using aiortc library to build my own WebRTC app. Here is what I am trying to do.

I have 2 peers, one is web browser, which is written in javascript, and another one is python script, which is working as signaling server and peer at the same time. So If you access to my web page, you will send video frame to server and then the server will make modification of that then send it back.

So I finished testing my app on LAN environment and everything worked as I expected. But once I deployed my app to remote server (Google cloud run) , I encountered Ice connection state failing issue. And gets this log on remote server.

enter image description here

(I think it is due to disconnection between peers, not low memory problem. I tried with 16GB RAM and 4 cpus and still didn't work)

Then, I dig into more information, and found that TURN/STUN server is necessary to build WebRTC app over Internet. So I added google STUN server to my RTCPeerConnection like this. [{'urls': 'stun:stun.l.google.com:19302'}, {'urls': 'stun:stun1.l.google.com:19302'}, {'urls': 'stun:stun2.l.google.com:19302'}] (I added both side on javascript and python because both side is working as peer) Unfortunately, it still didn't work.

Now, I am planning to build my own TURN server, but I am afraid if TURN server wouldn't solve this problem. So I would like to have any advice from you since I am quite stuck within my situation.

p.s I have done SSL encryption.(So GetUserMedia is working fine)

Sdp details(Offer/Answer):

SDP

Offer

v=0
o=- 5230177579491984101 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0 1
a=extmap-allow-mixed
a=msid-semantic: WMS ysUYIqPhE2Pw06sREyMmzgtVnNPK2ojthkdN
m=video 61745 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101 102 121 127 120 125 107 108 109 35 36 124 119 123 118 114 115 116
c=IN IP4 58.226.167.160
a=rtcp:9 IN IP4 0.0.0.0
a=candidate:3423470964 1 udp 2122260223 172.21.32.1 61744 typ host generation 0 network-id 1
a=candidate:2367656776 1 udp 2122194687 192.168.0.9 61745 typ host generation 0 network-id 2
a=candidate:608181405 1 udp 1685987071 58.226.167.160 61745 typ srflx raddr 192.168.0.9 rport 61745 generation 0 network-id 2
a=candidate:2190342532 1 tcp 1518280447 172.21.32.1 9 typ host tcptype active generation 0 network-id 1
a=candidate:3281809336 1 tcp 1518214911 192.168.0.9 9 typ host tcptype active generation 0 network-id 2
a=ice-ufrag:OKgJ
a=ice-pwd:LvzsEaQlE4laD7JV5Eeq9Hp5
a=ice-options:trickle
a=fingerprint:sha-256 2E:68:34:A4:B4:97:FB:67:9C:8E:1B:B1:5A:5B:5B:3D:C7:8A:F3:6D:03:8E:00:AF:D4:CE:04:EB:DE:26:07:52
a=setup:actpass
a=mid:0
a=extmap:1 urn:ietf:params:rtp-hdrext:toffset
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:3 urn:3gpp:video-orientation
a=extmap:4 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=extmap:5 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay
a=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type
a=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-timing
a=extmap:8 http://www.webrtc.org/experiments/rtp-hdrext/color-space
a=extmap:9 urn:ietf:params:rtp-hdrext:sdes:mid
a=extmap:10 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
a=extmap:11 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id
a=sendrecv
a=msid:ysUYIqPhE2Pw06sREyMmzgtVnNPK2ojthkdN c85941e2-a9be-4501-9495-96900b07ffad
a=rtcp-mux
a=rtcp-rsize
a=rtpmap:96 VP8/90000
a=rtcp-fb:96 goog-remb
a=rtcp-fb:96 transport-cc
a=rtcp-fb:96 ccm fir
a=rtcp-fb:96 nack
a=rtcp-fb:96 nack pli
a=rtpmap:97 rtx/90000
a=fmtp:97 apt=96
a=rtpmap:98 VP9/90000
a=rtcp-fb:98 goog-remb
a=rtcp-fb:98 transport-cc
a=rtcp-fb:98 ccm fir
a=rtcp-fb:98 nack
a=rtcp-fb:98 nack pli
a=fmtp:98 profile-id=0
a=rtpmap:99 rtx/90000
a=fmtp:99 apt=98
a=rtpmap:100 VP9/90000
a=rtcp-fb:100 goog-remb
a=rtcp-fb:100 transport-cc
a=rtcp-fb:100 ccm fir
a=rtcp-fb:100 nack
a=rtcp-fb:100 nack pli
a=fmtp:100 profile-id=2
a=rtpmap:101 rtx/90000
a=fmtp:101 apt=100
a=rtpmap:102 H264/90000
a=rtcp-fb:102 goog-remb
a=rtcp-fb:102 transport-cc
a=rtcp-fb:102 ccm fir
a=rtcp-fb:102 nack
a=rtcp-fb:102 nack pli
a=fmtp:102 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f
a=rtpmap:121 rtx/90000
a=fmtp:121 apt=102
a=rtpmap:127 H264/90000
a=rtcp-fb:127 goog-remb
a=rtcp-fb:127 transport-cc
a=rtcp-fb:127 ccm fir
a=rtcp-fb:127 nack
a=rtcp-fb:127 nack pli
a=fmtp:127 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42001f
a=rtpmap:120 rtx/90000
a=fmtp:120 apt=127
a=rtpmap:125 H264/90000
a=rtcp-fb:125 goog-remb
a=rtcp-fb:125 transport-cc
a=rtcp-fb:125 ccm fir
a=rtcp-fb:125 nack
a=rtcp-fb:125 nack pli
a=fmtp:125 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f
a=rtpmap:107 rtx/90000
a=fmtp:107 apt=125
a=rtpmap:108 H264/90000
a=rtcp-fb:108 goog-remb
a=rtcp-fb:108 transport-cc
a=rtcp-fb:108 ccm fir
a=rtcp-fb:108 nack
a=rtcp-fb:108 nack pli
a=fmtp:108 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42e01f
a=rtpmap:109 rtx/90000
a=fmtp:109 apt=108
a=rtpmap:35 AV1/90000
a=rtcp-fb:35 goog-remb
a=rtcp-fb:35 transport-cc
a=rtcp-fb:35 ccm fir
a=rtcp-fb:35 nack
a=rtcp-fb:35 nack pli
a=rtpmap:36 rtx/90000
a=fmtp:36 apt=35
a=rtpmap:124 H264/90000
a=rtcp-fb:124 goog-remb
a=rtcp-fb:124 transport-cc
a=rtcp-fb:124 ccm fir
a=rtcp-fb:124 nack
a=rtcp-fb:124 nack pli
a=fmtp:124 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=4d001f
a=rtpmap:119 rtx/90000
a=fmtp:119 apt=124
a=rtpmap:123 H264/90000
a=rtcp-fb:123 goog-remb
a=rtcp-fb:123 transport-cc
a=rtcp-fb:123 ccm fir
a=rtcp-fb:123 nack
a=rtcp-fb:123 nack pli
a=fmtp:123 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=64001f
a=rtpmap:118 rtx/90000
a=fmtp:118 apt=123
a=rtpmap:114 red/90000
a=rtpmap:115 rtx/90000
a=fmtp:115 apt=114
a=rtpmap:116 ulpfec/90000
a=ssrc-group:FID 83240304 3172434380
a=ssrc:83240304 cname:Xzq/NWrP3xdzu8nV
a=ssrc:83240304 msid:ysUYIqPhE2Pw06sREyMmzgtVnNPK2ojthkdN c85941e2-a9be-4501-9495-96900b07ffad
a=ssrc:83240304 mslabel:ysUYIqPhE2Pw06sREyMmzgtVnNPK2ojthkdN
a=ssrc:83240304 label:c85941e2-a9be-4501-9495-96900b07ffad
a=ssrc:3172434380 cname:Xzq/NWrP3xdzu8nV
a=ssrc:3172434380 msid:ysUYIqPhE2Pw06sREyMmzgtVnNPK2ojthkdN c85941e2-a9be-4501-9495-96900b07ffad
a=ssrc:3172434380 mslabel:ysUYIqPhE2Pw06sREyMmzgtVnNPK2ojthkdN
a=ssrc:3172434380 label:c85941e2-a9be-4501-9495-96900b07ffad
m=application 61747 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 58.226.167.160
a=candidate:3423470964 1 udp 2122260223 172.21.32.1 61746 typ host generation 0 network-id 1
a=candidate:2367656776 1 udp 2122194687 192.168.0.9 61747 typ host generation 0 network-id 2
a=candidate:608181405 1 udp 1685987071 58.226.167.160 61747 typ srflx raddr 192.168.0.9 rport 61747 generation 0 network-id 2
a=candidate:2190342532 1 tcp 1518280447 172.21.32.1 9 typ host tcptype active generation 0 network-id 1
a=candidate:3281809336 1 tcp 1518214911 192.168.0.9 9 typ host tcptype active generation 0 network-id 2
a=ice-ufrag:OKgJ
a=ice-pwd:LvzsEaQlE4laD7JV5Eeq9Hp5
a=ice-options:trickle
a=fingerprint:sha-256 2E:68:34:A4:B4:97:FB:67:9C:8E:1B:B1:5A:5B:5B:3D:C7:8A:F3:6D:03:8E:00:AF:D4:CE:04:EB:DE:26:07:52
a=setup:actpass
a=mid:1
a=sctp-port:5000
a=max-message-size:262144

Answer

v=0
o=- 3848131437 3848131437 IN IP4 0.0.0.0
s=-
t=0 0
a=group:BUNDLE 0 1
a=msid-semantic:WMS *
m=video 28763 UDP/TLS/RTP/SAVPF 96 97 102 121 125 107
c=IN IP4 169.254.8.130
a=sendrecv
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:9 urn:ietf:params:rtp-hdrext:sdes:mid
a=mid:0
a=msid:3f8df169-d198-4d28-9c9f-3cea615bd255 feeee3b7-f9f4-467b-964d-0c0bc8912cc3
a=rtcp:9 IN IP4 0.0.0.0
a=rtcp-mux
a=ssrc-group:FID 3048830126 1240869403
a=ssrc:3048830126 cname:8a6f48ce-f4d0-4fe5-91a3-e93a93d956bc
a=ssrc:1240869403 cname:8a6f48ce-f4d0-4fe5-91a3-e93a93d956bc
a=rtpmap:96 VP8/90000
a=rtcp-fb:96 nack
a=rtcp-fb:96 nack pli
a=rtcp-fb:96 goog-remb
a=rtpmap:97 rtx/90000
a=fmtp:97 apt=96
a=rtpmap:102 H264/90000
a=rtcp-fb:102 nack
a=rtcp-fb:102 nack pli
a=rtcp-fb:102 goog-remb
a=fmtp:102 packetization-mode=1;level-asymmetry-allowed=1;profile-level-id=42001f
a=rtpmap:121 rtx/90000
a=fmtp:121 apt=102
a=rtpmap:125 H264/90000
a=rtcp-fb:125 nack
a=rtcp-fb:125 nack pli
a=rtcp-fb:125 goog-remb
a=fmtp:125 packetization-mode=1;level-asymmetry-allowed=1;profile-level-id=42e01f
a=rtpmap:107 rtx/90000
a=fmtp:107 apt=125
a=candidate:624b2a3ab44a1b38445b234d615e2427 1 udp 2130706431 169.254.8.130 28763 typ host
a=candidate:b896f1a79e2e085ff8c936c1fc1c4a41 1 udp 2130706431 169.254.8.1 44858 typ host
a=candidate:bb020fce7718988fec4f78d8662e18f5 1 udp 2130706431 fddf:3978:feb1:d745::c001 55908 typ host
a=end-of-candidates
a=ice-ufrag:nYmg
a=ice-pwd:MrQrQQ1jy2mN5ri1ithP4f
a=fingerprint:sha-256 DC:27:A7:AD:BC:92:71:EA:18:A4:CF:EF:A8:0A:1C:7E:46:1B:E2:A2:8B:13:0C:AF:8E:43:25:92:B7:64:C2:2E
a=setup:active
m=application 28763 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 169.254.8.130
a=mid:1
a=sctp-port:5000
a=max-message-size:65536
a=candidate:624b2a3ab44a1b38445b234d615e2427 1 udp 2130706431 169.254.8.130 28763 typ host
a=candidate:b896f1a79e2e085ff8c936c1fc1c4a41 1 udp 2130706431 169.254.8.1 44858 typ host
a=candidate:bb020fce7718988fec4f78d8662e18f5 1 udp 2130706431 fddf:3978:feb1:d745::c001 55908 typ host
a=end-of-candidates
a=ice-ufrag:nYmg
a=ice-pwd:MrQrQQ1jy2mN5ri1ithP4f
a=fingerprint:sha-256 DC:27:A7:AD:BC:92:71:EA:18:A4:CF:EF:A8:0A:1C:7E:46:1B:E2:A2:8B:13:0C:AF:8E:43:25:92:B7:64:C2:2E
a=setup:active

Solution

  • If everything work on local, and this ice server are set, verify that your gcloud server have the correct firewall for webrtc port (not only your signaling port, check the sdp/ice you exchange). also this Webrtc page allow you to check is a stun/turn work on your client

    You will not need stun on your python side, as it's a server its ip may be public (unless you don't want to). Stun allow to find your public ip and allow the port to remain open.

    On your server you need to open your signaling port (certainly the WS where you exchange the sdp) and the P2P port (candidate lines in the sdp), the media/data will go through this one. For each media (sdp m line) there are usually one used port.