go2rtc icon indicating copy to clipboard operation
go2rtc copied to clipboard

Help with WebRTC configuration

Open azerty9971 opened this issue 1 year ago • 12 comments

Hello, I'm trying to write an echo script to fetch the stream of my camera via WebRTC.

I have the following details returned by the API I'm calling:

{ "result":{ "audio_attributes":{ "call_mode":[ 1, 2 ], "hardware_capability":[ 1, 2 ] }, "auth":"AUTH_REDACTED", "id":"bf868d7b9a0e88ad5axl9h", "moto_id":"signaling14896", "p2p_config":{ "auth":"AUTH_REDACTED", "ices":[ { "urls":"stun:18.158.206.187:3478" }, { "credential":"CRED_REDACTED", "ttl":36000, "urls":"turn:35.207.170.65:3478", "username":"abc:def" } ], "moto_id":"signaling14896" }, "protocol_version":"2.2", "skill":"{"webrtc":115,"audios":[{"channels":1,"dataBit":16,"codecType":101,"sampleRate":8000}],"videos":[{"streamType":2,"profileId":"","width":1920,"codecType":2,"sampleRate":90000,"height":1080},{"streamType":4,"width":640,"codecType":2,"sampleRate":90000,"height":360}]}", "support_webrtc_record":true, "supports_webrtc":true, "vedio_clarity":4, "vedio_claritys":[ 2, 4 ] }, "success":true, "t":1725893602947, "tid":"42b2cf9d6ebb11efb77736033862a1ba" }

Could you provide me with an GO2RTC stream config that would work with this information? I'm sorry but I couldn't find it myself...

Thanks in advance!! Azerty

azerty9971 avatar Sep 09 '24 15:09 azerty9971

This is not related to any known protocol.

AlexxIT avatar Sep 10 '24 04:09 AlexxIT

It should be part at least of the WebRTC protocol. What is the bare minimum needed to initiate a WebRTC connection with go2rtc?

azerty9971 avatar Sep 10 '24 04:09 azerty9971

Minimum for any WebRTC connection (for any software) is SDP exchange.

AlexxIT avatar Sep 10 '24 04:09 AlexxIT

Ok I'll do some research to understand how to do that.

Big thanks for your help!!

azerty9971 avatar Sep 10 '24 04:09 azerty9971

Hello, I've progressed on this matter and now I'm facing a strange issue.

1- What I'm doing: I'm trying to do the SDP exchange over HTTP(S) using the following go2rtc config line: webrtc:http://192.168.20.102:8123/api/xtend_tuya/webrtc?source=tuya_iot&device_id=bff2c99c5ad1c4256dlzgd

This POST gives me back the following results in cURL:

> POST /api/xtend_tuya/webrtc?source=tuya_iot&device_id=bff2c99c5ad1c4256dlzgd HTTP/1.1
> Host: 192.168.20.102:8123
> User-Agent: curl/8.5.0
> Accept: */*
> Content-Type: application/sdp
> Accept-Encoding: gzip
> Content-Length: 2923
> 
< HTTP/1.1 201 Created
< Content-Type: application/sdp; charset=utf-8
< Referrer-Policy: no-referrer
< X-Content-Type-Options: nosniff
< Server: 
< X-Frame-Options: SAMEORIGIN
< Content-Length: 388
< Date: Thu, 12 Sep 2024 05:31:10 GMT
< 
v=0
o=- 1726122665 1 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE
a=msid-semantic: WMS 2ZIg2cAV8RDIqobNHUIt
a=candidate:1257241454 1 UDP 2130706431 192.168.20.151 5000 typ host
a=candidate:869115421 1 UDP 2130706431 80.200.167.105 5000 typ host
a=candidate:91605448 1 UDP 1694498815 80.200.167.105 5000 typ srflx
a=candidate:1408307761 1 UDP 16777215 35.207.170.65 50517 typ relay

I'm guessing this should be a correct SDP answer (if not feel free to tell me what I missed :) )

2- The issue The issue is that when doing this from GO2RTC, I'm getting back the following error message: streams: sdp: syntax error at pos 172: " "

Do you have an idea of what I could be doing wrong?

Thanks in advance for your help!! Azerty

azerty9971 avatar Sep 12 '24 04:09 azerty9971

Show full SDP, so I can check problems at 172 line. You can do it in PM message if there is something private.

AlexxIT avatar Sep 12 '24 06:09 AlexxIT

Actually in the mean time I realized what is happening, the MQTT queue of Tuya is returning a bad value and this causes the issue, sorry for the wasted time :'(

azerty9971 avatar Sep 12 '24 06:09 azerty9971

Actually, now that I fixed it I have a real error that I can't figure out without your help:

Full SDP Exchange: SDP OFFER:

v=0
o=- 4438863994408732280 1726124849 IN IP4 0.0.0.0
s=-
t=0 0
a=msid-semantic:WMS*
a=fingerprint:sha-256 85:D7:40:DA:18:32:97:E5:6E:FF:1E:82:C9:15:EF:7A:41:5E:36:94:59:0F:30:14:99:F3:65:EA:CD:86:B7:64
a=extmap-allow-mixed
a=group:BUNDLE 0 1
m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 100
c=IN IP4 0.0.0.0
a=setup:actpass
a=mid:0
a=ice-ufrag:sRfHdVpsiWsDtins
a=ice-pwd:VBSvIRYVvgWooKvcncBlfrduCOWRyVIE
a=rtcp-mux
a=rtcp-rsize
a=rtpmap:96 H264/90000
a=fmtp:96 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f
a=rtcp-fb:96 goog-remb
a=rtcp-fb:96 ccm fir
a=rtcp-fb:96 nack
a=rtcp-fb:96 nack pli
a=rtcp-fb:96 nack
a=rtcp-fb:96 nack pli
a=rtcp-fb:96 transport-cc
a=rtpmap:97 H264/90000
a=fmtp:97 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f
a=rtcp-fb:97 goog-remb
a=rtcp-fb:97 ccm fir
a=rtcp-fb:97 nack
a=rtcp-fb:97 nack pli
a=rtcp-fb:97 nack
a=rtcp-fb:97 nack pli
a=rtcp-fb:97 transport-cc
a=rtpmap:98 H264/90000
a=fmtp:98 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=640032
a=rtcp-fb:98 goog-remb
a=rtcp-fb:98 ccm fir
a=rtcp-fb:98 nack
a=rtcp-fb:98 nack pli
a=rtcp-fb:98 nack
a=rtcp-fb:98 nack pli
a=rtcp-fb:98 transport-cc
a=rtpmap:100 H265/90000
a=rtcp-fb:100 goog-remb
a=rtcp-fb:100 ccm fir
a=rtcp-fb:100 nack
a=rtcp-fb:100 nack pli
a=rtcp-fb:100 nack
a=rtcp-fb:100 nack pli
a=rtcp-fb:100 transport-cc
a=extmap:1 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=recvonly
a=candidate:678254585 1 udp 2130706431 192.168.20.101 43051 typ host
a=candidate:678254585 2 udp 2130706431 192.168.20.101 43051 typ host
a=candidate:3639404234 1 udp 1694498815 80.200.167.105 54623 typ srflx raddr 0.0.0.0 rport 54623
a=candidate:3639404234 2 udp 1694498815 80.200.167.105 54623 typ srflx raddr 0.0.0.0 rport 54623
a=candidate:1930724222 1 udp 2130706431 2a02:a03f:be4d:9800:be24:11ff:fe64:4f53 52231 typ host
a=candidate:1930724222 2 udp 2130706431 2a02:a03f:be4d:9800:be24:11ff:fe64:4f53 52231 typ host
a=candidate:439373535 1 udp 1694498815 2a02:a03f:be4d:9800:be24:11ff:fe64:4f53 37648 typ srflx raddr :: rport 37648
a=candidate:439373535 2 udp 1694498815 2a02:a03f:be4d:9800:be24:11ff:fe64:4f53 37648 typ srflx raddr :: rport 37648
a=end-of-candidates
m=audio 9 UDP/TLS/RTP/SAVPF 101 0 8
c=IN IP4 0.0.0.0
a=setup:actpass
a=mid:1
a=ice-ufrag:sRfHdVpsiWsDtins
a=ice-pwd:VBSvIRYVvgWooKvcncBlfrduCOWRyVIE
a=rtcp-mux
a=rtcp-rsize
a=rtpmap:101 opus/48000/2
a=fmtp:101 minptime=10;useinbandfec=1
a=rtcp-fb:101 transport-cc
a=rtpmap:0 PCMU/8000
a=rtcp-fb:0 transport-cc
a=rtpmap:8 PCMA/8000
a=rtcp-fb:8 transport-cc
a=extmap:1 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=recvonly

SDP answer:

v=0
o=- 1726128449 1 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0 1
a=msid-semantic: WMS GZNfuXRv90d9hmUakG8X
m=video 9 UDP/TLS/RTP/SAVPF 96
c=IN IP4 0.0
m=audio 9 UDP/TLS/RTP/SAVPF 0
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:wIo2
a=ice-pwd:n5a1lZCQgOGkmpUL6Za24hHk
a=ice-options:trickle
a=fingerprint:sha-256 fd:08:dd:ab:d5:da:a9:ab:86:fd:f0:68:ba:ae:32:6a:cf:5e:ce:06:10:5e:ee:5c:97:3d:41:e4:87:ff:55:a9
a=setup:active
a=mid:1
a=sendrecv
a=msid:GZNfuXRv90d9hmUakG8X saXosJodMPf7wpWcBmKxbpHfMpiQWzB
a=rtcp-mux
a=rtpmap:0 PCMU/8000
a=ssrc:963508320 cname:bff2c99c5ad1c4256dlzgd
a=candidate:823097476 1 UDP 2130706431 192.168.20.151 5000 typ host
a=candidate:1306657357 1 UDP 2130706431 80.200.167.105 5000 typ host
a=candidate:1924558505 1 UDP 1694498815 80.200.167.105 5000 typ srflx
a=candidate:21649429 1 UDP 16777215 35.207.170.65 55068 typ relay 

The error that I'm having is:

streams: payload type not found

Do you have an idea of what I'm doing wrong?

Thanks in advance!! Azerty

azerty9971 avatar Sep 12 '24 07:09 azerty9971

This is wrong SDP. The video section does not describe the codec. Have no direction.

m=video 9 UDP/TLS/RTP/SAVPF 96
c=IN IP4 0.0

AlexxIT avatar Sep 12 '24 10:09 AlexxIT

Hello @AlexxIT, I've made quite some progress on this but I'm not able to make it work with go2rtc. I think the issue comes from the SDP offer that go2rtc sends to my api.

1- What I'm trying to do I'm trying to integrate Tuya cameras with go2rtc to have them in Frigate and Home Assistant. For this I have a custom integration in HA that exposes some APIs that you can use

2- Some data using another client (https://github.com/meetecho/simple-whep-client): Using the client hereabove, I'm managing to get the following SDP exchange: From WHEP client:

v=0
o=- 4000728066433669984 0 IN IP4 0.0.0.0
s=-
t=0 0
a=ice-options:trickle
a=group:BUNDLE audio0 video1
m=audio 9 UDP/TLS/RTP/SAVPF 0
c=IN IP4 0.0.0.0
a=setup:actpass
a=ice-ufrag:iBEmX6ebQRx4NkexK3YuylDkMf2whBif
a=ice-pwd:0fq34Tyh93lXTTy/PikFWLEAwYpQR2q+
a=rtcp-mux
a=rtcp-rsize
a=recvonly
a=rtpmap:0 PCMU/8000
a=rtcp-fb:0 transport-cc
a=mid:audio0
a=fingerprint:sha-256 C4:E2:FA:03:50:CF:E3:50:AB:4D:BF:6B:46:C7:9D:A2:BC:43:5B:CF:12:99:CA:D2:FB:0B:06:2E:4B:65:C8:B2
a=rtcp-mux-only
a=candidate:1 1 UDP 2015363327 2a02:a03f:be4d:9800:7e83:34ff:febe:fcdc 51024 typ host
a=candidate:2 1 TCP 1015021823 2a02:a03f:be4d:9800:7e83:34ff:febe:fcdc 9 typ host tcptype active
a=candidate:3 1 TCP 1010827519 2a02:a03f:be4d:9800:7e83:34ff:febe:fcdc 35045 typ host tcptype passive
a=candidate:4 1 UDP 2015363583 192.168.20.2 56266 typ host
a=candidate:5 1 TCP 1015022079 192.168.20.2 9 typ host tcptype active
a=candidate:6 1 TCP 1010827775 192.168.20.2 56269 typ host tcptype passive
a=candidate:7 1 UDP 2015363839 192.168.102.2 43867 typ host
a=candidate:8 1 TCP 1015022335 192.168.102.2 9 typ host tcptype active
a=candidate:9 1 TCP 1010828031 192.168.102.2 49089 typ host tcptype passive
a=candidate:10 1 UDP 2015364095 fe80::7e83:34ff:febe:fcdc 56080 typ host
a=candidate:11 1 TCP 1015022591 fe80::7e83:34ff:febe:fcdc 9 typ host tcptype active
a=candidate:12 1 TCP 1010828287 fe80::7e83:34ff:febe:fcdc 54181 typ host tcptype passive
a=candidate:13 1 UDP 2015364351 fc00:102::2 50098 typ host
a=candidate:14 1 TCP 1015022847 fc00:102::2 9 typ host tcptype active
a=candidate:15 1 TCP 1010828543 fc00:102::2 59441 typ host tcptype passive
a=candidate:16 1 UDP 1763705343 91.181.67.238 56266 typ srflx raddr 192.168.20.2 rport 56266
a=candidate:17 1 TCP 876610047 91.181.67.238 56269 typ srflx raddr 192.168.20.2 rport 56269 tcptype passive
a=end-of-candidates
m=video 0 UDP/TLS/RTP/SAVPF 102
c=IN IP4 0.0.0.0
a=setup:actpass
a=ice-ufrag:iBEmX6ebQRx4NkexK3YuylDkMf2whBif
a=ice-pwd:0fq34Tyh93lXTTy/PikFWLEAwYpQR2q+
a=bundle-only
a=rtcp-mux
a=rtcp-rsize
a=recvonly
a=rtpmap:102 H264/90000
a=rtcp-fb:102 nack pli
a=rtcp-fb:102 ccm fir
a=rtcp-fb:102 transport-cc
a=mid:video1
a=fingerprint:sha-256 C4:E2:FA:03:50:CF:E3:50:AB:4D:BF:6B:46:C7:9D:A2:BC:43:5B:CF:12:99:CA:D2:FB:0B:06:2E:4B:65:C8:B2
a=rtcp-mux-only
a=candidate:1 1 UDP 2015363327 2a02:a03f:be4d:9800:7e83:34ff:febe:fcdc 51024 typ host
a=candidate:2 1 TCP 1015021823 2a02:a03f:be4d:9800:7e83:34ff:febe:fcdc 9 typ host tcptype active
a=candidate:3 1 TCP 1010827519 2a02:a03f:be4d:9800:7e83:34ff:febe:fcdc 35045 typ host tcptype passive
a=candidate:4 1 UDP 2015363583 192.168.20.2 56266 typ host
a=candidate:5 1 TCP 1015022079 192.168.20.2 9 typ host tcptype active
a=candidate:6 1 TCP 1010827775 192.168.20.2 56269 typ host tcptype passive
a=candidate:7 1 UDP 2015363839 192.168.102.2 43867 typ host
a=candidate:8 1 TCP 1015022335 192.168.102.2 9 typ host tcptype active
a=candidate:9 1 TCP 1010828031 192.168.102.2 49089 typ host tcptype passive
a=candidate:10 1 UDP 2015364095 fe80::7e83:34ff:febe:fcdc 56080 typ host
a=candidate:11 1 TCP 1015022591 fe80::7e83:34ff:febe:fcdc 9 typ host tcptype active
a=candidate:12 1 TCP 1010828287 fe80::7e83:34ff:febe:fcdc 54181 typ host tcptype passive
a=candidate:13 1 UDP 2015364351 fc00:102::2 50098 typ host
a=candidate:14 1 TCP 1015022847 fc00:102::2 9 typ host tcptype active
a=candidate:15 1 TCP 1010828543 fc00:102::2 59441 typ host tcptype passive
a=candidate:16 1 UDP 1763705343 91.181.67.238 56266 typ srflx raddr 192.168.20.2 rport 56266
a=candidate:17 1 TCP 876610047 91.181.67.238 56269 typ srflx raddr 192.168.20.2 rport 56269 tcptype passive
a=end-of-candidates

Answer from Tuya:

v=0
o=- 1726513409 1 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE audio0 video1
a=msid-semantic: WMS 116
m=audio 9 UDP/TLS/RTP/SAVPF 0
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:qOrE
a=ice-pwd:bxJpHCGNFmMf9mMfOTpS1lUH
a=ice-options:trickle
a=fingerprint:sha-256 00:04:7e:c4:7d:0f:96:9e:9e:89:b3:a6:c5:26:87:9f:16:4f:20:c0:39:32:73:42:0c:69:9f:fd:93:4a:06:0d
a=setup:active
a=mid:audio0
a=sendrecv
a=msid:116 Aq51DxDosXb9jpVwZrbibyNxPBPQwrf
a=rtcp-mux
a=rtpmap:0 PCMU/8000
a=ssrc:948433768 cname:bff2c99c5ad1c4256dlzgd
m=video 9 UDP/TLS/RTP/SAVPF 102
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:qOrE
a=ice-pwd:bxJpHCGNFmMf9mMfOTpS1lUH
a=ice-options:trickle
a=fingerprint:sha-256 00:04:7e:c4:7d:0f:96:9e:9e:89:b3:a6:c5:26:87:9f:16:4f:20:c0:39:32:73:42:0c:69:9f:fd:93:4a:06:0d
a=setup:active
a=mid:video1
a=sendonly
a=msid:116 4gl5tgJfYoGgX3BRc01KZxfWKqvlklQ
a=rtcp-mux
a=rtpmap:102 H264/90000
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=ssrc:1736665098 cname:bff2c99c5ad1c4256dlzgd

This looks like a valid SDP exchange to me (if not please tell me :))

3- Some more data: I think the Tuya cloud expects to have H264/90000 as a proposed format for video and PCMU/8000 for audio. That specific camera supports 2 way audio and has 2 channels, this is all described in the config sent back by the cloud (doc here: https://developer.tuya.com/en/docs/iot/webrtc?id=Kacsd4x2hl0se#title-8-Get%20WebRTC%20configurations) {'audio_attributes': {'call_mode': [1, 2], 'hardware_capability': [1, 2]}, 'auth': 'REDACTED', 'id': 'bff2c99c5ad1c4256dlzgd', 'moto_id': 'signaling14901', 'p2p_config': {'auth': 'Zyc7A781aprV7qkLhINXOemfQ+nP+SGabmlhDYblLrg=', 'ices': '[{"urls":"stun:18.192.7.75:3478"},{"credential":"REDACTED","ttl":36000,"urls":"turn:35.207.116.126:3478","username":"1726545804:bff2c99c5ad1c4256dlzgd"}]', 'moto_id': 'signaling14901'}, 'protocol_version': '2.2', 'skill': '{"webrtc":115,"audios":[{"channels":1,"dataBit":16,"codecType":101,"sampleRate":8000}],"videos":[{"streamType":2,"profileId":"","width":1920,"codecType":2,"sampleRate":90000,"height":1080},{"streamType":4,"width":640,"codecType":2,"sampleRate":90000,"height":360}]}', 'support_webrtc_record': True, 'supports_webrtc': True, 'vedio_clarity': 4, 'vedio_claritys': [2, 4]}

I'm able to get all of these data using the following test script:

#!/bin/sh
ICE=`exec curl -fsSL -H "Authorization: Bearer GO2RTC" "https://home-test.soe-server.com/api/xtend_tuya/webrtc_get_ice_servers?device_id=bfe42ffd72240e648b5hpi&session_id=${1}&format=SimpleWHEP"`
echo "${ICE}"
./whep-client \
-u "https://home-test.soe-server.com/api/xtend_tuya/webrtc_sdp_exchange?device_id=bfe42ffd72240e648b5hpi&session_id=${1}" \
-A "application/x-rtp,media=audio,encoding-name=PCMU,clock-rate=8000,payload=0" \
-V "application/x-rtp,media=video,encoding-name=H264,clock-rate=90000,payload=102" \
-t GO2RTC \
-n \
${ICE}

curl -fsSL -H "Authorization: Bearer GO2RTC" "https://home-test.soe-server.com/api/xtend_tuya/webrtc_debug?session_id=${1}"

This script has hardcoded credentials that should work on your side too (the Authorization: Bearer GO2RTC is for now hardcoded to let anyone call the APIs for WebRTC on my test instance of HA)

4- Available API: For testing, you can use the following APIs. For your testing, you can use any session ID (I use an incremental number) per session (so ICE fetching + SDP exchange). The only device_id available on this instance is bfe42ffd72240e648b5hpi

4.1- Get ICE servers https://home-test.soe-server.com/api/xtend_tuya/webrtc_get_ice_servers?device_id=DEVICE_ID&session_id=SESSION_ID Example call: curl -fsSL -H "Authorization: Bearer GO2RTC" "https://home-test.soe-server.com/api/xtend_tuya/webrtc_get_ice_servers?device_id=bfe42ffd72240e648b5hpi&session_id=120" Example result: [{"urls":"stun:18.192.87.31:3478"},{"credential":"TldEWtKH1J2hiVsK0ZXEhvK5JIw=","ttl":36000,"urls":"turn:35.207.116.126:3478","username":"1726548991:bfe42ffd72240e648b5hpi"}]

4.2- Make SDP Exchange: https://home-test.soe-server.com/api/xtend_tuya/webrtc_sdp_exchange?device_id=DEVICE_ID&session_id=SESSION_ID Example call (script using the simple WHEP client above):

#!/bin/sh
ICE=`exec curl -fsSL -H "Authorization: Bearer GO2RTC" "https://home-test.soe-server.com/api/xtend_tuya/webrtc_get_ice_servers?device_id=bfe42ffd72240e648b5hpi&session_id=${1}&format=SimpleWHEP"`
echo "${ICE}"
./whep-client \
-u "https://home-test.soe-server.com/api/xtend_tuya/webrtc_sdp_exchange?device_id=bfe42ffd72240e648b5hpi&session_id=${1}" \
-A "application/x-rtp,media=audio,encoding-name=PCMU,clock-rate=8000,payload=0" \
-V "application/x-rtp,media=video,encoding-name=H264,clock-rate=90000,payload=102" \
-t GO2RTC \
-n \
-l 7 \
${ICE}

curl -fsSL -H "Authorization: Bearer GO2RTC" "https://home-test.soe-server.com/api/xtend_tuya/webrtc_debug?session_id=${1}"

call the script by providing the session ID as first parameter: ./test.sh 120

The result should show the full SDP exchange:

[From TUYA]Config:
{'audio_attributes': {'call_mode': [1, 2], 'hardware_capability': [1, 2]}, 'auth': 'Zyc7A781aprV7qkLhINXOemfQ+nP+SGabmlhDYblLrg=', 'id': 'bfe42ffd72240e648b5hpi', 'moto_id': 'signaling14901', 'p2p_config': {'auth': 'Zyc7A781aprV7qkLhINXOemfQ+nP+SGabmlhDYblLrg=', 'ices': '[{"urls":"stun:18.192.7.75:3478"},{"credential":"fHzGTz/tye5X6hs06jARStN+1Hw=","ttl":36000,"urls":"turn:35.207.116.126:3478","username":"1726548426:bfe42ffd72240e648b5hpi"}]', 'moto_id': 'signaling14901'}, 'protocol_version': '2.2', 'skill': '{"webrtc":115,"audios":[{"channels":1,"dataBit":16,"codecType":101,"sampleRate":8000}],"videos":[{"streamType":2,"profileId":"","width":1920,"codecType":2,"sampleRate":90000,"height":1080},{"streamType":4,"width":640,"codecType":2,"sampleRate":90000,"height":360}]}', 'support_webrtc_record': True, 'supports_webrtc': True, 'vedio_clarity': 4, 'vedio_claritys': [2, 4]}
[From client]Original Offer
v=0
o=- 8099852833827446935 0 IN IP4 0.0.0.0
s=-
t=0 0
a=ice-options:trickle
a=group:BUNDLE audio0 video1
m=audio 9 UDP/TLS/RTP/SAVPF 0
c=IN IP4 0.0.0.0
a=setup:actpass
a=ice-ufrag:r7qk0VWpl/OVq3Hryuo/B/mRv0UgBH8h
a=ice-pwd:UemzKjz1wLn9Fe12tyHyUkM9GZTmEyc+
a=rtcp-mux
a=rtcp-rsize
a=recvonly
a=rtpmap:0 PCMU/8000
a=rtcp-fb:0 transport-cc
a=mid:audio0
a=fingerprint:sha-256 BA:AC:59:74:C2:A9:46:B3:03:D7:D6:90:98:E7:E0:88:C9:48:F6:3C:53:DA:D9:32:FD:66:C7:E3:57:69:AC:6A
a=rtcp-mux-only
a=candidate:1 1 UDP 2015363327 2a02:a03f:be4d:9800:7e83:34ff:febe:fcdc 41957 typ host
a=candidate:2 1 TCP 1015021823 2a02:a03f:be4d:9800:7e83:34ff:febe:fcdc 9 typ host tcptype active
a=candidate:3 1 TCP 1010827519 2a02:a03f:be4d:9800:7e83:34ff:febe:fcdc 51065 typ host tcptype passive
a=candidate:4 1 UDP 2015363583 192.168.20.2 43983 typ host
a=candidate:5 1 TCP 1015022079 192.168.20.2 9 typ host tcptype active
a=candidate:6 1 TCP 1010827775 192.168.20.2 43463 typ host tcptype passive
a=candidate:7 1 UDP 2015363839 192.168.102.2 34441 typ host
a=candidate:8 1 TCP 1015022335 192.168.102.2 9 typ host tcptype active
a=candidate:9 1 TCP 1010828031 192.168.102.2 33981 typ host tcptype passive
a=candidate:10 1 UDP 2015364095 fe80::7e83:34ff:febe:fcdc 33004 typ host
a=candidate:11 1 TCP 1015022591 fe80::7e83:34ff:febe:fcdc 9 typ host tcptype active
a=candidate:12 1 TCP 1010828287 fe80::7e83:34ff:febe:fcdc 39289 typ host tcptype passive
a=candidate:13 1 UDP 2015364351 fc00:102::2 53518 typ host
a=candidate:14 1 TCP 1015022847 fc00:102::2 9 typ host tcptype active
a=candidate:15 1 TCP 1010828543 fc00:102::2 42029 typ host tcptype passive
a=candidate:16 1 UDP 1763705343 91.181.67.238 43983 typ srflx raddr 192.168.20.2 rport 43983
a=candidate:17 1 TCP 876610047 91.181.67.238 43463 typ srflx raddr 192.168.20.2 rport 43463 tcptype passive
a=end-of-candidates
m=video 0 UDP/TLS/RTP/SAVPF 102
c=IN IP4 0.0.0.0
a=setup:actpass
a=ice-ufrag:r7qk0VWpl/OVq3Hryuo/B/mRv0UgBH8h
a=ice-pwd:UemzKjz1wLn9Fe12tyHyUkM9GZTmEyc+
a=bundle-only
a=rtcp-mux
a=rtcp-rsize
a=recvonly
a=rtpmap:102 H264/90000
a=rtcp-fb:102 nack pli
a=rtcp-fb:102 ccm fir
a=rtcp-fb:102 transport-cc
a=mid:video1
a=fingerprint:sha-256 BA:AC:59:74:C2:A9:46:B3:03:D7:D6:90:98:E7:E0:88:C9:48:F6:3C:53:DA:D9:32:FD:66:C7:E3:57:69:AC:6A
a=rtcp-mux-only
a=candidate:1 1 UDP 2015363327 2a02:a03f:be4d:9800:7e83:34ff:febe:fcdc 41957 typ host
a=candidate:2 1 TCP 1015021823 2a02:a03f:be4d:9800:7
[From client]Offer
v=0
o=- 8099852833827446935 0 IN IP4 0.0.0.0
s=-
t=0 0
a=ice-options:trickle
a=group:BUNDLE audio0 video1
m=audio 9 UDP/TLS/RTP/SAVPF 0
c=IN IP4 0.0.0.0
a=setup:actpass
a=ice-ufrag:r7qk0VWpl/OVq3Hryuo/B/mRv0UgBH8h
a=ice-pwd:UemzKjz1wLn9Fe12tyHyUkM9GZTmEyc+
a=rtcp-mux
a=rtcp-rsize
a=recvonly
a=rtpmap:0 PCMU/8000
a=rtcp-fb:0 transport-cc
a=mid:audio0
a=fingerprint:sha-256 BA:AC:59:74:C2:A9:46:B3:03:D7:D6:90:98:E7:E0:88:C9:48:F6:3C:53:DA:D9:32:FD:66:C7:E3:57:69:AC:6A
a=rtcp-mux-only
m=video 0 UDP/TLS/RTP/SAVPF 102
c=IN IP4 0.0.0.0
a=setup:actpass
a=ice-ufrag:r7qk0VWpl/OVq3Hryuo/B/mRv0UgBH8h
a=ice-pwd:UemzKjz1wLn9Fe12tyHyUkM9GZTmEyc+
a=bundle-only
a=rtcp-mux
a=rtcp-rsize
a=recvonly
a=rtpmap:102 H264/90000
a=rtcp-fb:102 nack pli
a=rtcp-fb:102 ccm fir
a=rtcp-fb:102 transport-cc
a=mid:video1
a=fingerprint:sha-256 BA:AC:59:74:C2:A9:46:B3:03:D7:D6:90:98:E7:E0:88:C9:48:F6:3C:53:DA:D9:32:FD:66:C7:E3:57:69:AC:6A
a=rtcp-mux-only
a=candidate:2 1 TCP 1015021823 2a02:a03f:be4d:9800:7
[From TUYA]Answer:
v=0
o=- 1726516030 1 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE audio0 video1
a=msid-semantic: WMS 119
m=audio 9 UDP/TLS/RTP/SAVPF 0
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:BmlJ
a=ice-pwd:Rc5AWVRiVEe1ywG74VKreBAJ
a=ice-options:trickle
a=fingerprint:sha-256 84:15:ab:da:63:73:13:a7:6c:95:ea:01:8f:bd:30:22:da:90:0c:0b:ac:aa:ef:0d:1e:28:57:6f:78:a8:af:d1
a=setup:active
a=mid:audio0
a=sendrecv
a=msid:119 RpNcZ8t0iz8FUYvxmZxiVDpYg7PIGXa
a=rtcp-mux
a=rtpmap:0 PCMU/8000
a=ssrc:438037673 cname:bfe42ffd72240e648b5hpi
m=video 9 UDP/TLS/RTP/SAVPF 102
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:BmlJ
a=ice-pwd:Rc5AWVRiVEe1ywG74VKreBAJ
a=ice-options:trickle
a=fingerprint:sha-256 84:15:ab:da:63:73:13:a7:6c:95:ea:01:8f:bd:30:22:da:90:0c:0b:ac:aa:ef:0d:1e:28:57:6f:78:a8:af:d1
a=setup:active
a=mid:video1
a=sendonly
a=msid:119 hMxJv5DunA22caxZKUW2yhqULvteCRE
a=rtcp-mux
a=rtpmap:102 H264/90000
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=ssrc:997126725 cname:bfe42ffd72240e648b5hpi

4.3- Show exchanges that happened during the session (used in script here-above): https://home-test.soe-server.com/api/xtend_tuya/webrtc_debug?session_id=SESSION_ID Example call: curl -fsSL -H "Authorization: Bearer GO2RTC" "https://home-test.soe-server.com/api/xtend_tuya/webrtc_debug?session_id=120" Example result: Same as the script above

5- Tuya specification According to Tuya's documentation, their ICE servers should be used in the SDP exchange, that is the reason why you have an API to get those ICE servers. Please note that if you make too many calls in a short span of time the Tuya Cloud tends to not respond anymore to SDP offers... In that case you'll have to wait for 10 minutes before retrying. Also, it looks like all the candidates have to be sent in the offer, ICE trickeling doesn't seem to work nicely with Tuya.

6- What you can help me with If you could help me with the go2rtc side of the implementation that would be great (I don't know anything in GO :/). What I'd love for you to do is to make it so that from go2rtc, these API are called and a WebRTC session is initiated. I think you have all the tools to do it (if not don't hesitate to ask me and I'll implement the missing API). Those API actually implement the following standard: https://www.ietf.org/archive/id/draft-ietf-wish-whip-16.html#name-introduction

I hope that you'll be able to help me with this, this is in theory the last line to do before we have support for Tuya cameras in go2rtc :).

Have an awesome day, Azerty

azerty9971 avatar Sep 16 '24 19:09 azerty9971

I need time to research this

AlexxIT avatar Sep 20 '24 14:09 AlexxIT

Updated the comment with the new device ID (which should now be stable so that you can test if you want :)).

Do you have any update on this? In the mean time I've tried to be as compliant as I could with the WISH WHEP protocol (https://www.ietf.org/archive/id/draft-ietf-wish-whep-02.html#name-introduction) but I'm still getting an error from GO2RTC :'(

Thanks in advance, Azerty

azerty9971 avatar Oct 22 '24 08:10 azerty9971