Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tuya webrtc support #1379

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open

Add tuya webrtc support #1379

wants to merge 15 commits into from

Conversation

romasku
Copy link

@romasku romasku commented Oct 1, 2024

Hello,

I ported https://github.com/tuya/webrtc-demo-go to go2rtc to add direct support for Tuya cameras.
It worked for me (I could see the video feed through the go2rtc web interface), but I'm a complete newbie to Golang, so I need help to make this code clean enough. Please guide me, I'll try to do my best.

Also, another major problem I encountered is that ICE sessions should be pion.ICERoleControlled even though it's incorrect according to the standard. So I had to hack my way around this issue using SDPTypePranswer. Do you have any suggestions on how to handle this situation properly?

I guess these issues are related:

@felipecrs
Copy link
Contributor

felipecrs commented Oct 1, 2024

This is awesome!

@romasku, perhaps you can also add your new source instructions/information to the README?

I want to give it a try.

@romasku
Copy link
Author

romasku commented Oct 1, 2024

@felipecrs I've updated Readme to include an example, it's the same parameters as for Tuya's demo.

@felipecrs
Copy link
Contributor

@romasku it works! Awesome!

One issue though, it only works the first time. If I stop the stream and try to access it again, it fails with:

image

To make it work again, I have to restart go2rtc.

@felipecrs
Copy link
Contributor

@pergolafabio I think you should try your famous pet feeder against this.

@pergolafabio
Copy link

Hmm, looks interesting, though, I never got the camera stream working with that webrtc-demo-go app...

I have now a working stream through the tuna cloud integration... But gonna try this one indeed!!

@pergolafabio
Copy link

is there an easy way to test this as an addon? or better wait to get merged in master?

@felipecrs
Copy link
Contributor

felipecrs commented Oct 1, 2024

In my case I cloned the repo and built the executable, and ran it in my machine, not in HA.

@pergolafabio
Copy link

pergolafabio commented Oct 1, 2024

hmm, build the binary too, add the stream url with correct params, but i got black screen, and this is my log:

23:13:49.160 INF go2rtc platform=windows/amd64 revision=a33d95b version=1.9.4
23:13:49.161 INF config path="C:\\Users\\Fabio.Pergola\\Downloads\\go2rtc_win64\\go2rtc.yaml"
23:13:49.163 INF [rtsp] listen addr=:8554
23:13:49.163 INF [api] listen addr=:1984
23:13:49.164 INF [webrtc] listen addr=:8555/tcp
2024/10/01 23:14:03 motoID: signaling14905
2024/10/01 23:14:03 auth: TfjsIc12CtKPGct6AYbGK7dqbY+c81unIkFoUoOc9PU=
2024/10/01 23:14:03 iceServers: [{"urls":"stun:18.158.206.187:3478"},{"urls":"turn:35.207.98.228:3478","username":"XXXX","credential":"XXXX="}]
2024/10/01 23:14:03 hubConfig: {Url:ssl://m1.tuyaeu.com:8883 ClientID:cloud_new2873f36e604fe93f644cbaba1b79cba3 Username:XXXXX Password:XXXXX SinkTopic:{IPC:/av/moto/moto_id/u/{device_id}} SourceSink:{IPC:/av/u/new551640cb44874dddaca860827477e6e1} ExpireTime:7200}
2024/10/01 23:14:03 publish topic: /av/moto/signaling14905/u/XXXX
2024/10/01 23:14:03 subscribe topic: /av/u/new551640cb44874dddaca860827477e6e1
2024/10/01 23:14:03 cloud_new2873f36e604fe93f644cbaba1b79cba3 connect to mqtt success
2024/10/01 23:14:03 subscribe mqtt topic success
pc INFO: 2024/10/01 23:14:06 signaling state changed to have-local-offer
ice DEBUG: 23:14:06.150831 gather.go:465: Failed to resolve STUN host: 35.207.98.228:3478: address 35.207.98.228: no suitable address found
ice DEBUG: 23:14:06.150831 gather.go:465: Failed to resolve STUN host: 18.158.206.187:3478: address 18.158.206.187: no suitable address found
turnc DEBUG: 23:14:06.150831 client.go:119: Resolved TURN server 35.207.98.228:3478 to 35.207.98.228:3478
turnc DEBUG: 23:14:06.236825 udp_conn.go:66: Initial lifetime: 600 seconds
turnc DEBUG: 23:14:06.237930 udp_conn.go:81: Started refresh allocation timer
turnc DEBUG: 23:14:06.237930 udp_conn.go:84: Started refresh permission timer
2024/10/01 23:14:06 mqtt recv message, session: ISaQfL, type: answer, from: XXXX, to: new551640cb44874dddaca860827477e6e1
pc INFO: 2024/10/01 23:14:06 signaling state changed to have-remote-pranswer
pc INFO: 2024/10/01 23:14:06 signaling state changed to stable
ice DEBUG: 23:14:06.249914 agent.go:404: Started agent: isControlling? true, remoteUfrag: "VAcUwwcRdfjANvLS", remotePwd: "WoEPSwjUeDSJpwbryLEJIAMLOpAZtTiY"
ice INFO: 2024/10/01 23:14:06 Setting new connection state: Checking
pc INFO: 2024/10/01 23:14:06 ICE connection state changed: checking
pc INFO: 2024/10/01 23:14:06 peer connection state changed: connecting
ice INFO: 2024/10/01 23:14:06 Failed to send packet: write udp 172.20.176.1:54267->3.69.54.194:64054: wsasendto: A socket operation was attempted to an unreachable network.
ice INFO: 2024/10/01 23:14:06 Failed to send packet: write udp 172.30.112.1:54271->3.69.54.194:64054: wsasendto: A socket operation was attempted to an unreachable network.
turnc DEBUG: 23:14:06.324947 udp_conn.go:438: Channel binding successful: 3.69.54.194:64054 16384
ice INFO: 2024/10/01 23:14:06 Setting new connection state: Connected
pc INFO: 2024/10/01 23:14:06 ICE connection state changed: connected
dtls DEBUG: 23:14:06.545126 conn.go:775: CipherSuite not initialized, queuing packet
dtls DEBUG: 23:14:06.545446 conn.go:697: received packet of next epoch, queuing packet
pc INFO: 2024/10/01 23:14:06 peer connection state changed: connected
pc WARNING: 2024/10/01 23:14:06 Failed to start manager: ICETransport can only be called in ICETransportStateNew
pc INFO: 2024/10/01 23:14:06 signaling state changed to have-remote-offer
ice DEBUG: 23:14:07.072625 agent.go:404: Started agent: isControlling? false, remoteUfrag: "HCoj", remotePwd: "ajSyhCr03e7BuRLlsI/E1gAu"
ice INFO: 2024/10/01 23:14:07 Setting new connection state: Checking
ice WARNING: 2024/10/01 23:14:07 Failed to ping without candidate pairs. Connection is not possible yet.
pc INFO: 2024/10/01 23:14:07 signaling state changed to stable
pc INFO: 2024/10/01 23:14:07 ICE connection state changed: checking
pc INFO: 2024/10/01 23:14:07 peer connection state changed: connecting
ice DEBUG: 23:14:07.073715 gather.go:183: GetConn by ufrag: pbAimpGDLuGsFpOb
ice INFO: 2024/10/01 23:14:07 Failed to send packet: write udp 172.20.176.1:54275->141.135.170.247:59656: wsasendto: A socket operation was attempted to an unreachable network.
ice DEBUG: 23:14:07.074681 gather.go:465: Failed to resolve STUN host: stun.l.google.com:19302: lookup stun.l.google.com: getaddrinfow: The requested name is valid, but no data of the requested type was found.
ice INFO: 2024/10/01 23:14:07 Failed to send packet: write udp 172.20.176.1:54275->141.135.170.247:59656: wsasendto: A socket operation was attempted to an unreachable network.
ice DEBUG: 23:14:07.075900 gather.go:183: GetConn by ufrag: pbAimpGDLuGsFpOb
ice INFO: 2024/10/01 23:14:07 Failed to send packet: write udp 172.20.176.1:54275->141.135.170.247:59656: wsasendto: A socket operation was attempted to an unreachable network.
ice INFO: 2024/10/01 23:14:07 Failed to send packet: write udp 172.30.112.1:54277->141.135.170.247:59656: wsasendto: A socket operation was attempted to an unreachable network.
ice INFO: 2024/10/01 23:14:07 Failed to send packet: write udp 172.20.176.1:54275->141.135.170.247:59656: wsasendto: A socket operation was attempted to an unreachable network.
ice INFO: 2024/10/01 23:14:07 Failed to send packet: write udp 172.30.112.1:54277->141.135.170.247:59656: wsasendto: A socket operation was attempted to an unreachable network.
ice DEBUG: 23:14:07.077744 gather.go:183: GetConn by ufrag: pbAimpGDLuGsFpOb
ice INFO: 2024/10/01 23:14:07 Failed to send packet: write udp 172.20.176.1:54275->141.135.170.247:59656: wsasendto: A socket operation was attempted to an unreachable network.
ice INFO: 2024/10/01 23:14:07 Failed to send packet: write udp 172.30.112.1:54277->141.135.170.247:59656: wsasendto: A socket operation was attempted to an unreachable network.
ice DEBUG: 23:14:07.078951 agent.go:1145: Adding a new peer-reflexive candidate: 172.20.176.1:59656
ice DEBUG: 23:14:07.078951 gather.go:183: GetConn by ufrag: pbAimpGDLuGsFpOb
ice INFO: 2024/10/01 23:14:07 Failed to send packet: write udp 172.20.176.1:54275->141.135.170.247:59656: wsasendto: A socket operation was attempted to an unreachable network.
ice INFO: 2024/10/01 23:14:07 Failed to send packet: write udp 172.30.112.1:54277->141.135.170.247:59656: wsasendto: A socket operation was attempted to an unreachable network.
ice INFO: 2024/10/01 23:14:07 Failed to send packet: write udp 172.30.112.1:54277->172.20.176.1:59656: wsasendto: A socket operation was attempted to an unreachable network.
ice INFO: 2024/10/01 23:14:07 Setting new connection state: Connected
pc INFO: 2024/10/01 23:14:07 ICE connection state changed: connected
ice DEBUG: 23:14:07.080769 gather.go:183: GetConn by ufrag: pbAimpGDLuGsFpOb
pc INFO: 2024/10/01 23:14:07 peer connection state changed: connected
pc DEBUG: 23:14:07.149402 peerconnection.go:466: got new track: &{mu:{w:{state:0 sema:0} writerSem:0 readerSem:0 readerCount:{_:{} v:0} readerWait:{_:{} v:0}} id:video streamID:WetvF0FpaPPzzDLXUB65I0WXFfmWxiOMv6K8 payloadType:96 kind:2 ssrc:1628712413 rtxSsrc:0 codec:{RTPCodecCapability:{MimeType:video/H264 ClockRate:90000 Channels:0 SDPFmtpLine:level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f RTCPFeedback:[{Type:goog-remb Parameter:} {Type:ccm Parameter:fir} {Type:nack Parameter:} {Type:nack Parameter:pli} {Type:nack Parameter:} {Type:nack Parameter:pli} {Type:transport-cc Parameter:}]} PayloadType:96 statsID:} params:{HeaderExtensions:[] Codecs:[{RTPCodecCapability:{MimeType:video/H264 ClockRate:90000 Channels:0 SDPFmtpLine:level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f RTCPFeedback:[{Type:goog-remb Parameter:} {Type:ccm Parameter:fir} {Type:nack Parameter:} {Type:nack Parameter:pli} {Type:nack Parameter:} {Type:nack Parameter:pli} {Type:transport-cc Parameter:}]} PayloadType:96 statsID:}]} rid: receiver:0xc00024c3f0 peeked:[128 96 12 182 13 199 214 71 97 20 45 221 64 1 12 1 255 255 1 64 0 0 3 0 144 0 0 3 0 0 3 0 120 188 9] peekedAttributes:map[0:0xc00068a320]}
srtp INFO: 2024/10/01 23:14:07 srtp ssrc=1628712413 index=3254: duplicated packet
srtp INFO: 2024/10/01 23:14:07 srtp ssrc=1628712413 index=3255: duplicated packet
...................
srtp INFO: 2024/10/01 23:14:07 srtp ssrc=1628712413 index=3306: duplicated packet
srtp INFO: 2024/10/01 23:14:07 srtp ssrc=1628712413 index=3307: duplicated packet
pc DEBUG: 23:14:07.182172 peerconnection.go:466: got new track: &{mu:{w:{state:0 sema:0} writerSem:0 readerSem:0 readerCount:{_:{} v:0} readerWait:{_:{} v:0}} id:audio streamID:WetvF0FpaPPzzDLXUB65I0WXFfmWxiOMv6K8 payloadType:0 kind:1 ssrc:3462549208 rtxSsrc:0 codec:{RTPCodecCapability:{MimeType: ClockRate:0 Channels:0 SDPFmtpLine: RTCPFeedback:[]} PayloadType:0 statsID:} params:{HeaderExtensions:[] Codecs:[]} rid: receiver:0xc00024c360 peeked:[128 128 241 60 202 24 110 216 206 98 78 216 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254] peekedAttributes:map[0:0xc000504e10]}
srtp INFO: 2024/10/01 23:14:07 srtp ssrc=1628712413 index=3308: duplicated packet
................
srtp INFO: 2024/10/01 23:14:07 srtp ssrc=1628712413 index=3329: duplicated packet
srtp INFO: 2024/10/01 23:14:07 srtp ssrc=1628712413 index=3330: duplicated packet
ice DEBUG: 23:14:07.274269 agent.go:1145: Adding a new peer-reflexive candidate: 172.30.112.1:59656
ice DEBUG: 23:14:07.335998 agent.go:1145: Adding a new peer-reflexive candidate: 192.168.0.186:59656
pc WARNING: 2024/10/01 23:14:12 Incoming unhandled RTCP ssrc(767835711), OnTrack will not be fired

@pergolafabio
Copy link

i also see this below, but restarting go2rtc doesnt help

image

@felipecrs
Copy link
Contributor

@pergolafabio, try a different Tuya camera if you have, just in case. It also didn't work for one of mine.

@pergolafabio
Copy link

i only have one :)

@felipecrs
Copy link
Contributor

felipecrs commented Oct 1, 2024

i only have one :)

Lucky you!!! Tuya is trash 😅

@pergolafabio
Copy link

Hey @romasku , i see you added a new commit, is that helpfull for me? i have some issues getting the stream, see the logs above...

thnx for looking into it!

@romasku
Copy link
Author

romasku commented Oct 2, 2024

Hi, I've fixed the "uid not exist" issue (hopefully). Also, the current code uses global variables (the same as the original Tuya code), which can lead to issues if you try to open multiple streams at once. I'll try to work on this part later.

@pergolafabio
I see in your logs pc DEBUG: 23:14:07.149402 peerconnection.go:466: got new track:, this means that go2rtc was able to connect and acquire video and audio streams. This can be an issue with the go2rtc -> your browser connection (maybe I introduced some bug), or your device just streams a black screen via WebRTC. Can you please check, maybe the audio works?

@pergolafabio
Copy link

hmm, i was testing on http , since i just used the compiled binary, is https maybe needed? for the browser?
i check also audio

@romasku
Copy link
Author

romasku commented Oct 2, 2024

If you use localhost as hostname, then https is not required. I'm testing via http://localhost:1984/ . But for other hostnames https is indeed required, AFAIK.

@pergolafabio
Copy link

ok, i check later
i have the HA Tuya Cloud integration active, to display the camera feed in HA, should i stop that one, maybe it doesnt allow multiple streams?

@pergolafabio
Copy link

btw, i remember testing the webrtc-demo-go app , i never got that working either, also black screen
so i wonder how the Tuya Cloud integration is working? isnt that the same api ?

@romasku
Copy link
Author

romasku commented Oct 2, 2024

As I see from logs, go2rtc got access to some stream data, so the issue should be either that the stream is corrupt or unable to go to your end device. So it shouldn't be a conflict with HA Tuya Cloud (I had both running at the same time for my camera). But you can try checking it.

HA Tuya Cloud uses RTSP stream (AFAIK), so it is a different API. But you can check if this official Tuya web app works: https://protect-eu.ismartlife.me/login (maybe select a different region), as it uses WebRTC the same way as the webrtc-demo-go app.

@pergolafabio
Copy link

pergolafabio commented Oct 2, 2024

Tested that link, and i see the stream there, so thats already a good sign :-)
it also means, i can use multiple streams.....
when activating that link, chrome asked me to allow the mic access

@pergolafabio
Copy link

tested again, with new version, i dont hear any audio either, strange that the other link does work?
what can i do to investigate?

11:12:05.672 INF go2rtc platform=windows/amd64 revision=a0b9883 version=1.9.4
11:12:05.673 INF config path="C:\\Users\\Fabio.Pergola\\Downloads\\go2rtc_win64\\go2rtc.yaml"
11:12:05.674 INF [rtsp] listen addr=:8554
11:12:05.674 INF [api] listen addr=:1984
11:12:05.674 INF [webrtc] listen addr=:8555/tcp
2024/10/02 11:12:17 motoID: signaling14905
2024/10/02 11:12:17 auth: TfjsIc12CtKPGct6AYbGK7dqbY+c81unIkFoUoOc9PU=
2024/10/02 11:12:17 iceServers: [{"urls":"stun:18.158.206.187:3478"},{"urls":"turn:35.207.98.228:3478","username":"XXX:XXXX","credential":"XXXX"}]
2024/10/02 11:12:17 hubConfig: {Url:ssl://m1.tuyaeu.com:8883 ClientID:cloud_new0813ec0142bc23dd01eec3ae633a59b5 Username:XXXX Password:XXXX SinkTopic:{IPC:/av/moto/moto_id/u/{device_id}} SourceSink:{IPC:/av/u/new551640cb44874dddaca860827477e6e1} ExpireTime:7200}
2024/10/02 11:12:17 publish topic: /av/moto/signaling14905/u/XXX
2024/10/02 11:12:17 subscribe topic: /av/u/new551640cb44874dddaca860827477e6e1
2024/10/02 11:12:17 cloud_new0813ec0142bc23dd01eec3ae633a59b5 connect to mqtt success
2024/10/02 11:12:17 subscribe mqtt topic success
pc INFO: 2024/10/02 11:12:19 signaling state changed to have-local-offer
ice DEBUG: 11:12:19.743698 gather.go:465: Failed to resolve STUN host: 35.207.116.126:3478: address 35.207.116.126: no suitable address found
turnc DEBUG: 11:12:19.743698 client.go:119: Resolved TURN server 35.207.116.126:3478 to 35.207.116.126:3478
ice DEBUG: 11:12:19.743698 gather.go:465: Failed to resolve STUN host: 18.192.7.75:3478: address 18.192.7.75: no suitable address found
turnc DEBUG: 11:12:19.829801 udp_conn.go:66: Initial lifetime: 600 seconds
turnc DEBUG: 11:12:19.829801 udp_conn.go:81: Started refresh allocation timer
turnc DEBUG: 11:12:19.829801 udp_conn.go:84: Started refresh permission timer
2024/10/02 11:12:19 mqtt recv message, session: tg9Ypw, type: answer, from: XXX, to: new551640cb44874dddaca860827477e6e1
pc INFO: 2024/10/02 11:12:19 signaling state changed to have-remote-pranswer
pc INFO: 2024/10/02 11:12:19 signaling state changed to stable
ice DEBUG: 11:12:19.843487 agent.go:404: Started agent: isControlling? true, remoteUfrag: "GOURKYyORblpAFps", remotePwd: "CggvToOJMSBzEXLuzCLtIsNulXCJzqGb"
ice INFO: 2024/10/02 11:12:19 Setting new connection state: Checking
pc INFO: 2024/10/02 11:12:19 ICE connection state changed: checking
pc INFO: 2024/10/02 11:12:19 peer connection state changed: connecting
ice INFO: 2024/10/02 11:12:19 Failed to send packet: write udp 172.20.176.1:64761->3.78.173.153:60829: wsasendto: A socket operation was attempted to an unreachable network.
ice INFO: 2024/10/02 11:12:19 Failed to send packet: write udp 172.30.112.1:64765->3.78.173.153:60829: wsasendto: A socket operation was attempted to an unreachable network.
turnc DEBUG: 11:12:19.927396 udp_conn.go:438: Channel binding successful: 3.78.173.153:60829 16384
ice INFO: 2024/10/02 11:12:20 Setting new connection state: Connected
pc INFO: 2024/10/02 11:12:20 ICE connection state changed: connected
dtls DEBUG: 11:12:20.163601 conn.go:775: CipherSuite not initialized, queuing packet
dtls DEBUG: 11:12:20.163601 conn.go:697: received packet of next epoch, queuing packet
pc INFO: 2024/10/02 11:12:20 peer connection state changed: connected
pc WARNING: 2024/10/02 11:12:20 Failed to start manager: ICETransport can only be called in ICETransportStateNew
pc INFO: 2024/10/02 11:12:20 signaling state changed to have-remote-offer
ice DEBUG: 11:12:20.562200 agent.go:404: Started agent: isControlling? false, remoteUfrag: "Aw9y", remotePwd: "tDB/DuuG26LhgVTyflRnvm2E"
pc INFO: 2024/10/02 11:12:20 signaling state changed to stable
ice INFO: 2024/10/02 11:12:20 Setting new connection state: Checking
ice WARNING: 2024/10/02 11:12:20 Failed to ping without candidate pairs. Connection is not possible yet.
pc INFO: 2024/10/02 11:12:20 ICE connection state changed: checking
pc INFO: 2024/10/02 11:12:20 peer connection state changed: connecting
ice DEBUG: 11:12:20.564258 gather.go:183: GetConn by ufrag: rWTDduhKhzPbMXsp
ice INFO: 2024/10/02 11:12:20 Ignoring remote candidate with tcpType active: tcp4 host 172.30.112.1:9
ice INFO: 2024/10/02 11:12:20 Ignoring remote candidate with tcpType active: tcp4 host 172.20.176.1:9
ice INFO: 2024/10/02 11:12:20 Ignoring remote candidate with tcpType active: tcp4 host 192.168.0.186:9
ice DEBUG: 11:12:20.564761 gather.go:465: Failed to resolve STUN host: stun.l.google.com:19302: lookup stun.l.google.com: getaddrinfow: The requested name is valid, but no data of the requested type was found.
ice INFO: 2024/10/02 11:12:20 Ignoring remote candidate with tcpType active: tcp6 host [fd77:ad1d:c209:a392:a5d0:e2e2:4482:7548]:9
ice INFO: 2024/10/02 11:12:20 Failed to send packet: write udp 172.20.176.1:64769->172.30.112.1:50061: wsasendto: A socket operation was attempted to an unreachable network.
ice INFO: 2024/10/02 11:12:20 Ignoring remote candidate with tcpType active: tcp6 host [fd77:ad1d:c209:a392:d4cf:df85:3456:66f4]:9
ice INFO: 2024/10/02 11:12:20 Failed to send packet: write udp 172.20.176.1:64769->141.135.170.247:50063: wsasendto: A socket operation was attempted to an unreachable network.
ice INFO: 2024/10/02 11:12:20 Failed to send packet: write udp 172.20.176.1:64769->192.168.0.186:50063: wsasendto: A socket operation was attempted to an unreachable network.
ice DEBUG: 11:12:20.567135 gather.go:183: GetConn by ufrag: rWTDduhKhzPbMXsp
ice INFO: 2024/10/02 11:12:20 Failed to send packet: write udp 172.20.176.1:64769->172.30.112.1:50061: wsasendto: A socket operation was attempted to an unreachable network.
ice INFO: 2024/10/02 11:12:20 Failed to send packet: write udp 172.20.176.1:64769->141.135.170.247:50063: wsasendto: A socket operation was attempted to an unreachable network.
ice INFO: 2024/10/02 11:12:20 Failed to send packet: write udp 172.20.176.1:64769->192.168.0.186:50063: wsasendto: A socket operation was attempted to an unreachable network.
ice INFO: 2024/10/02 11:12:20 Setting new connection state: Connected
ice DEBUG: 11:12:20.568161 gather.go:183: GetConn by ufrag: rWTDduhKhzPbMXsp
pc INFO: 2024/10/02 11:12:20 ICE connection state changed: connected
ice DEBUG: 11:12:20.568763 gather.go:183: GetConn by ufrag: rWTDduhKhzPbMXsp
ice DEBUG: 11:12:20.568821 gather.go:183: GetConn by ufrag: rWTDduhKhzPbMXsp
pc INFO: 2024/10/02 11:12:20 peer connection state changed: connected
pc DEBUG: 11:12:23.187473 peerconnection.go:466: got new track: &{mu:{w:{state:0 sema:0} writerSem:0 readerSem:0 readerCount:{_:{} v:0} readerWait:{_:{} v:0}} id:video streamID:1DRbr3ieYf6BMJMqrhWPzYcbTWjb5n60Xs34 payloadType:96 kind:2 ssrc:4130812713 rtxSsrc:0 codec:{RTPCodecCapability:{MimeType:video/H264 ClockRate:90000 Channels:0 SDPFmtpLine:level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f RTCPFeedback:[{Type:goog-remb Parameter:} {Type:ccm Parameter:fir} {Type:nack Parameter:} {Type:nack Parameter:pli} {Type:nack Parameter:} {Type:nack Parameter:pli} {Type:transport-cc Parameter:}]} PayloadType:96 statsID:} params:{HeaderExtensions:[] Codecs:[{RTPCodecCapability:{MimeType:video/H264 ClockRate:90000 Channels:0 SDPFmtpLine:level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f RTCPFeedback:[{Type:goog-remb Parameter:} {Type:ccm Parameter:fir} {Type:nack Parameter:} {Type:nack Parameter:pli} {Type:nack Parameter:} {Type:nack Parameter:pli} {Type:transport-cc Parameter:}]} PayloadType:96 statsID:}]} rid: receiver:0xc0000ba360 peeked:[128 96 44 25 160 102 193 104 246 55 51 41 66 1 1 1 64 0 0 3 0 144 0 0 3 0 0 3 0 120 160 3 192 128 16 229 158 251 145 40 94 2 148 20 20 23 132 0 0 3 0 4 0 0 3 0 40 190 16 8 32] peekedAttributes:map[0:0xc00007d220]}
srtp INFO: 2024/10/02 11:12:23 srtp ssrc=4130812713 index=11289: duplicated packet
srtp INFO: 2024/10/02 11:12:23 srtp ssrc=4130812713 index=11290: duplicated packet
srtp INFO: 2024/10/02 11:12:23 srtp ssrc=4130812713 index=11291: duplicated packet
................
srtp INFO: 2024/10/02 11:12:23 srtp ssrc=4130812713 index=11336: duplicated packet
srtp INFO: 2024/10/02 11:12:23 srtp ssrc=4130812713 index=11337: duplicated packet
srtp INFO: 2024/10/02 11:12:23 srtp ssrc=4130812713 index=11338: duplicated packet
srtp INFO: 2024/10/02 11:12:23 srtp ssrc=4130812713 index=11339: duplicated packet
srtp INFO: 2024/10/02 11:12:23 srtp ssrc=4130812713 index=11336: duplicated packet
pc DEBUG: 11:12:23.221258 peerconnection.go:466: got new track: &{mu:{w:{state:0 sema:0} writerSem:0 readerSem:0 readerCount:{_:{} v:0} readerWait:{_:{} v:0}} id:audio streamID:1DRbr3ieYf6BMJMqrhWPzYcbTWjb5n60Xs34 payloadType:0 kind:1 ssrc:802255331 rtxSsrc:0 codec:{RTPCodecCapability:{MimeType: ClockRate:0 Channels:0 SDPFmtpLine: RTCPFeedback:[]} PayloadType:0 statsID:} params:{HeaderExtensions:[] Codecs:[]} rid: receiver:0xc0000ba2d0 peeked:[128 128 200 235 208 47 95 158 47 209 113 227 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254 254] peekedAttributes:map[0:0xc0000b65a0]}
srtp INFO: 2024/10/02 11:12:23 srtp ssrc=4130812713 index=11337: duplicated packet
srtp INFO: 2024/10/02 11:12:23 srtp ssrc=4130812713 index=11338: duplicated packet
srtp INFO: 2024/10/02 11:12:23 srtp ssrc=4130812713 index=11339: duplicated packet
srtp INFO: 2024/10/02 11:12:23 srtp ssrc=4130812713 index=11336: duplicated packet
srtp INFO: 2024/10/02 11:12:23 srtp ssrc=4130812713 index=11337: duplicated packet
...........
srtp INFO: 2024/10/02 11:12:23 srtp ssrc=4130812713 index=11352: duplicated packet
srtp INFO: 2024/10/02 11:12:23 srtp ssrc=4130812713 index=11349: duplicated packet
srtp INFO: 2024/10/02 11:12:23 srtp ssrc=4130812713 index=11350: duplicated packet
srtp INFO: 2024/10/02 11:12:23 srtp ssrc=4130812713 index=11351: duplicated packet
srtp INFO: 2024/10/02 11:12:23 srtp ssrc=4130812713 index=11352: duplicated packet
pc WARNING: 2024/10/02 11:12:28 Incoming unhandled RTCP ssrc(3202850753), OnTrack will not be fired

@felipecrs
Copy link
Contributor

@AlexxIT
Copy link
Owner

AlexxIT commented Oct 6, 2024

Thanks! As I remember, paho.mqtt is a very heavy lib. I will check and not accept this if the app increases in size significantly.

@pergolafabio
Copy link

hey @romasku , is this maybe related?

pion/webrtc#1021

@felipecrs
Copy link
Contributor

@AlexxIT, for your information, I tried compiling both master and this PR, and this is the comparison:

[4.0K]  go2rtc-master
├── [4.4M]  go2rtc_linux_amd64
├── [3.5M]  go2rtc_linux_arm
├── [3.6M]  go2rtc_linux_arm64
├── [3.5M]  go2rtc_linux_armv6
├── [4.0M]  go2rtc_linux_i386
├── [3.4M]  go2rtc_linux_mipsel
├── [5.6M]  go2rtc_mac_amd64.zip
├── [5.2M]  go2rtc_mac_arm64.zip
├── [5.3M]  go2rtc_win32.zip
├── [5.6M]  go2rtc_win64.zip
└── [5.1M]  go2rtc_win_arm64.zip
[4.0K]  go2rtc-tuya
├── [4.6M]  go2rtc_linux_amd64
├── [3.6M]  go2rtc_linux_arm
├── [3.7M]  go2rtc_linux_arm64
├── [3.6M]  go2rtc_linux_armv6
├── [4.1M]  go2rtc_linux_i386
├── [3.5M]  go2rtc_linux_mipsel
├── [5.8M]  go2rtc_mac_amd64.zip
├── [5.4M]  go2rtc_mac_arm64.zip
├── [5.5M]  go2rtc_win32.zip
├── [5.8M]  go2rtc_win64.zip
└── [5.2M]  go2rtc_win_arm64.zip

The uncompressed binaries:

[ 14M]  go2rtc_linux_amd64-master
[ 15M]  go2rtc_linux_amd64-tuya

If that's too big, maybe you'll have a need for paho.mqtt in the future, and then maybe this PR could be viable.

@AlexxIT
Copy link
Owner

AlexxIT commented Oct 28, 2024

These are unexpectedly good results. Anyway, I'll look into this PR when I have time.

t.mqttDispatch(rmqtt)
}

// 分发从mqtt服务器接受到的消息
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should cleanup these comments in Chinese. Or at least translate them, if they are important.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, sorry, I originally planned to cleanup it, but missed it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use copilot or chatgpt to help you translate this

@AlexxIT AlexxIT removed the doubt label Feb 18, 2025
@felipecrs
Copy link
Contributor

@romasku really good job, this PR will be a game changer for some people, which will allow to better use existing hardware instead of throwing them away and buying new ones. I would never recommend people buy Tuya-based cameras or doorbells, but most of the time it's too late: they already bought.

Please signal here once you are done cleaning it up and testing it, and you believe it's ready for @AlexxIT to review it.

@felipecrs
Copy link
Contributor

felipecrs commented Feb 19, 2025

There's also this, in case you are willing to implement it in the same PR. :)

@romasku, another thing to take into consideration is the stream quality. IIRC, you can select the quality (SD/HD) when requesting the WebRTC configs.

Perhaps you can make it a query parameter as well?

But I'd see no problem if you prefer to leave it for a future PR.

@romasku
Copy link
Author

romasku commented Feb 20, 2025

Sure, I'll re-check my code more thoroughly this weekend and then ping for a review.

However, I have to mention that this will likely be a half-measure for some devices. On my device, Tuya's own panel only provides only SD-quality video with no support for two-way audio. I had to hack and replace the camera firmware itself to make it work with Home Assistant.

Regarding quality selection—since my device only has SD quality available via Tuya's WebRTC, I can't properly test it, so I'll have to leave it out.

@felipecrs
Copy link
Contributor

Got it. It makes sense. And yeah, not all Tuya devices support WebRTC properly. Unfortunately, we have to live with it.

@pergolafabio
Copy link

hi @romasku , i tried again, but i still see a black screen, what i notice, when i press on info, it gives me :

{
  "producers": [
    {
      "id": 17,
      "format_name": "webrtc/tuya",
      "protocol": "ws+udp",
      "remote_addr": "3.69.200.30:50729 host",
      "url": "https://openapi.tuyaeu.com",
      "medias": [
        "video, recvonly, H264",
        "audio, recvonly, PCMU/8000",
        "audio, sendonly, PCMU/8000, PCMA/8000, L16, PCML"
      ],
      "receivers": [
        {
          "id": 18,
          "codec": {
            "codec_name": "h264",
            "codec_type": "video"

But when testing on this page: https://protect-eu.ismartlife.me/playback
it gives me h265 as codec?

image

@pergolafabio
Copy link

for the moment i still use @felipecrs his hack: https://github.com/felipecrs/get-tuya-webrtc-configs/blob/master/get_tuya_stream_url.sh

that one works, i also i the stream, it uses h265 , so maybe the codec is the issue? how can i force/test using h265 ?

{
  "producers": [
    {
      "id": 190875,
      "format_name": "rtsp",
      "protocol": "rtsp+tcp",
      "remote_addr": "3.78.173.153:443",
      "url": "rtsps://echo:[email protected]:443/v1/xxxx/xxxx?signInfo=xxxxx",
      "sdp": "v=0\r\no=- 1740133637755257 1 IN IP4 wework-5-eu.stream.iot-11.com\r\ns=tuya stream\r\ni=video stream\r\nt=0 0\r\na=tool:Tuya stream media v1.0.0.1\r\na=type:broadcast\r\na=control:*\r\na=range:npt=0-\r\na=x-qt-text-nam:tuya stream\r\na=x-qt-text-inf:video stream\r\nm=video 0 RTP/AVP 95\r\na=rtpmap:95 H265/90000\r\na=range:npt=now-\r\na=control:track0\r\nm=audio 0 RTP/AVP 97\r\nc=IN IP4 0.0.0.0\r\na=rtpmap:97 PCMU/8000/1\r\na=range:npt=now-\r\na=control:track1\r\n",
      "user_agent": "go2rtc/1.9.8",
      "medias": [
        "video, recvonly, H265",
        "audio, recvonly, PCMU/8000"

@felipecrs
Copy link
Contributor

I don't think it's a "hack", lol. I think it's the proper way.

BTW here is the new version of that tool: https://github.com/felipecrs/hass-expose-camera-stream-source/blob/master/README.md (scroll to the end).

@felipecrs
Copy link
Contributor

@pergolafabio, if your camera codec is H265 then it won't support WebRTC indeed.

@pergolafabio
Copy link

yeah, i was already using that .py file, you recreated it, dont remember why :-)
ah ok , so h265 is my issue then with webrtc? no way to overcome this? seems only support on safari?

image

@felipecrs
Copy link
Contributor

Yeah. For now at least. But Chrome has a launch option to enable H265 nowadays.

@pergolafabio
Copy link

pergolafabio commented Feb 21, 2025

i tried below, but still same :-(

chrome.exe --enable-features=PlatformHEVCEncoderSupport,WebRtcAllowH265Receive,WebRtcAllowH265Send --force-fieldtrials=WebRTC-Video-H26xPacketBuffer/Enabled

its still forced to h264 probably

@felipecrs
Copy link
Contributor

Maybe we can explore your case after, but I would say this PR should not wait for it to be merged.

@romasku
Copy link
Author

romasku commented Feb 23, 2025

@felipecrs @AlexxIT
I've finished preparing the PR for review, so please review. I’ve tried my best to write good code, but this PR is my first and only experience with Golang, so please point out any newbie mistakes I may have made.

@romasku
Copy link
Author

romasku commented Feb 23, 2025

Also, Tuya finally fixed their site, and now I can properly select HD/SD, so I managed to reverse it. #resolution_id=0 should enable HD quality on devices that support this setting.

Moreover, I had some success with 2-way audio, but unfortunately, it works in the playground demo project but not in go2rtc. If I manage to get it working, I'll open a separate PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants