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

WebRTC through WAN while client is on the same LAN #681

Open
7floor opened this issue Oct 11, 2023 · 19 comments · Fixed by blakeblackshear/frigate#8469
Open

WebRTC through WAN while client is on the same LAN #681

7floor opened this issue Oct 11, 2023 · 19 comments · Fixed by blakeblackshear/frigate#8469
Labels
bug Something isn't working
Milestone

Comments

@7floor
Copy link

7floor commented Oct 11, 2023

Environment: HomeAssistant on RPI4 64 bit, HASSIO addon Frigate (Full Access) 0.12.1

Since some version of go2rtc, when client is on same LAN as HA, in some cases WebRTC candidate is chosen of type srflx which causes traffic to go through WAN interface back and forth. This really bad for my 4G connection with limited traffic.

go2rtc versions checked: 1.2.0, 1.6.2, 1.7.1

v1.2.0 (bundled with addon) works correctly, i.e. while client on same LAN as HA, the host candidate is always chosen, both for Chrome on wired desktop and for HA Companion app on Android phone (WiFi)

v1.6.2 and 1.7.1 (placed one by one to config directory) - issue is the same for both. For wired desktop with Chrome, srflx candidate is chosen, and all traffic goes through WAN interface. Surprisingly, HA Companion App still works throug LAN.

My config:

mqtt:
  host: homeassistant.local
  user: ***
  password: ***

ffmpeg:
  hwaccel_args: preset-rpi-64-h264

detectors:
  cpu1:
    type: cpu
    num_threads: 3

objects:
  track:
    - person
    - car
    - cat
    - dog

record:
  enabled: true
  retain:
    days: 14
    mode: motion

snapshots:
  enabled: true

go2rtc:
  streams:
    rtsp_outdoor_hq:
      - rtsp://***:***@192.168.2.201:554/cam/realmonitor?channel=1&subtype=0
    rtsp_outdoor_lq:
      - rtsp://***:***@192.168.2.201:554/cam/realmonitor?channel=1&subtype=1

cameras:
  outdoor:
    ffmpeg:
      inputs:
        - path: rtsp://localhost:8554/rtsp_outdoor_hq
          input_args: preset-rtsp-restream
          roles:
            - record
        - path: rtsp://localhost:8554/rtsp_outdoor_lq
          input_args: preset-rtsp-restream
          roles:
            - detect
    live:
      stream_name: rtsp_outdoor_lq
    detect:
      width: 640
      height: 480
    motion:
      mask:
        - 640,0,640,225,252,0
    zones:
      driveway:
        coordinates: 150,480,640,480,640,327,398,125,44,224
      gate:
        coordinates: 248,480,109,480,29,241,78,230
@AlexxIT AlexxIT added the question Further information is requested label Oct 12, 2023
@AlexxIT
Copy link
Owner

AlexxIT commented Oct 12, 2023

You need to open chrome://webrtc-internals/ before webrtc connection start and show candidates tables for old and new versions. You can send them in PM, if you want.

@7floor
Copy link
Author

7floor commented Oct 12, 2023

Please check in attachment.
My LAN is 192.168.2.0/24, homeassistant is 192.168.2.3, client PC is 192.168.2.101
My external WAN IP in this particular session is 46.56.186.235

WebRTC Internals.zip

@7floor
Copy link
Author

7floor commented Oct 16, 2023

Sorry for bothering Alex, but any ideas on my issue?

@AlexxIT
Copy link
Owner

AlexxIT commented Oct 17, 2023

Can check this on next week

@AlexxIT AlexxIT added bug Something isn't working and removed question Further information is requested labels Oct 31, 2023
@AlexxIT AlexxIT added this to the v1.8.2 milestone Oct 31, 2023
@AlexxIT
Copy link
Owner

AlexxIT commented Oct 31, 2023

I can't see the candidates section in your config. Did you remove it when you posted to github?
https://docs.frigate.video/configuration/live#webrtc-extra-configuration

@7floor
Copy link
Author

7floor commented Oct 31, 2023

I have no such section in frigate.yaml at all.

But when I check go2rtc dashboard at http://192.168.2.3:5000/live/webrtc/editor.html, I see the actual config go2rtc is using, and it has the same for all versions as follows:

<<<non-relevant lines skipped>>>
webrtc:
  candidates:
  - 192.168.2.3:8555
  - stun:8555

@AlexxIT
Copy link
Owner

AlexxIT commented Oct 31, 2023

OK. This is a problem. Both candidates have the same priority. I will think for the solution.

@AlexxIT
Copy link
Owner

AlexxIT commented Nov 4, 2023

@AlexxIT AlexxIT closed this as completed Nov 4, 2023
@7floor
Copy link
Author

7floor commented Nov 4, 2023

No luck, it didn't help - still through WAN IP in my setup. Details attached.
LAN IPs 192.168.2.101 browser, 192.168.2.3 homeassistant; WAN IP 95.47.61.240

In log, I've noticed there's candidate advertisement as 2918e18d-56b7-4900-a25d-eb1fc2b86956.local - which is Chrome's way to obfuscate IPs of local candidates. Can this be a problem? Found this on topic: https://groups.google.com/g/discuss-webrtc/c/4Yggl6ZzqZk/m/nV24XkXXAQAJ?pli=1 and https://bloggeek.me/psa-mdns-and-local-ice-candidates-are-coming/
These are pretty old though, and do not explain how it was working with go2rtc 1.2.0

I'm absolutely not into topic, so please excuse my probably naive assumptions.

details.zip

@AlexxIT AlexxIT reopened this Nov 5, 2023
@AlexxIT
Copy link
Owner

AlexxIT commented Nov 5, 2023

You need to add to your config:

go2rtc:
  webrtc:
    listen: ":8555"

@7floor
Copy link
Author

7floor commented Nov 5, 2023

Added to frigate config as you suggesting:

go2rtc:
  log:
    #level: trace
  webrtc:
    listen: ":8555"
  ffmpeg:
    esp32cam: "-avoid_negative_ts make_zero -fflags nobuffer -flags low_delay -strict experimental -fflags +genpts+discardcorrupt -i {input}"
  streams:
    outdoor_hq:
      - rtsp://*****
    outdoor_lq:
      - ffmpeg:rtsp://*****#video=h264#width=704#height=528#raw=-pix_fmt yuv420p
    indoor:
      - ffmpeg:http://*****#input=esp32cam#video=h264#raw=-pix_fmt yuv420p -vf scale=1024:768,drawtext=text='%{{localtime}}':x=(w-tw)-w/25:y=h/25:fontsize=h/25:fontcolor=white:shadowx=2:shadowy=2

And that's didn't change anything.
The final config (seen at go2rtc dashboard on port 5000) doesn't have it:

api:
  origin: '*'
ffmpeg:
  esp32cam: -avoid_negative_ts make_zero -fflags nobuffer -flags low_delay -strict
    experimental -fflags +genpts+discardcorrupt -i {input}
  rtsp: -fflags nobuffer -flags low_delay -stimeout 5000000 -user_agent go2rtc/ffmpeg
    -rtsp_transport tcp -i {input}
log:
  format: text
rtsp:
  default_query: mp4
streams:
  indoor:
  - ffmpeg:http://*****#input=esp32cam#video=h264#raw=-pix_fmt yuv420p
    -vf scale=1024:768,drawtext=text='%{localtime}':x=(w-tw)-w/25:y=h/25:fontsize=h/25:fontcolor=white:shadowx=2:shadowy=2
  outdoor_hq:
  - rtsp://*****
  outdoor_lq:
  - ffmpeg:rtsp://*****#video=h264#width=704#height=528#raw=-pix_fmt
    yuv420p
webrtc:
  candidates:
  - 192.168.2.3:8555
  - stun:8555

The log is like this (note WebRTC port was provided by supervisor):

2023-11-05 07:57:47.347970242  [INFO] Preparing go2rtc config...
2023-11-05 07:57:47.528518694  [INFO] Got IP address from supervisor: 192.168.2.3
2023-11-05 07:57:47.671867401  [INFO] Got WebRTC port from supervisor: 8555
2023-11-05 07:57:48.486777350  [WARN] Using go2rtc binary from '/config/go2rtc' instead of the embedded one
2023-11-05 07:57:48.486791423  [INFO] Starting go2rtc...
2023-11-05 07:57:48.713450290  10:57:48.713 INF go2rtc version 1.8.2 linux/arm64
2023-11-05 07:57:48.715114297  10:57:48.714 INF [api] listen addr=:1984
2023-11-05 07:57:48.716836172  10:57:48.716 INF [rtsp] listen addr=:8554
2023-11-05 07:57:48.717953152  10:57:48.717 INF [webrtc] listen addr=:8555
2023-11-05 07:57:57.391853647  [INFO] Starting go2rtc healthcheck service...

The final config and log of go2rtc output was the same regardless if I include into frigate config this:

go2rtc:
  webrtc:
    listen: ":8555"

The webrtc-internals still shows WAN IP local/remote candidates pair chosen.

@7floor
Copy link
Author

7floor commented Nov 5, 2023

@NickM-27 I've looked into your PR above, and I think there's a mistake. It reads:

# go2rtc should listen on 5000 tcp & udp by default
if not go2rtc_config["webrtc"].get("listen"):
    go2rtc_config["webrtc"]["listen"] = ":5000"

While webrtc should listen to :8555

@NickM-27
Copy link
Contributor

NickM-27 commented Nov 5, 2023

Oh yes that would explain it, it was an early morning for me 🤦🏻‍♂️

@7floor
Copy link
Author

7floor commented Nov 5, 2023

@NickM-27 @AlexxIT

So I made some more experiments and here's my findings.

First, explicitly adding listen address to config really helped (I added listen: ":8555"), and since then candidates pair is being chosen correctly, i.e. direct LAN IPs of client and server.

But there are some things that seem questionnable to me:

  1. for some reason, Frigate does not pass thru this setting from frigate.yaml even if I specify it there. To do so, I had to edit final config at go2rtc dashboard via http://192.168.2.3:5000/live/webrtc/editor.html then hit Save & Restart button.

  2. go2rtc documentation states, that "by default, WebRTC uses both TCP and UDP on port 8555 for connections" and "you can change the port in YAML config" (here https://github.com/AlexxIT/go2rtc#module-webrtc). Why one has to explicitly specify the default to make it work?

  3. both with and without explicit declaration of listen: ":8555", the log of go2rtc always says it uses :8555, like it assumes that default as described in docs.

2023-11-05 18:24:13.603073358  21:24:13.602 INF go2rtc version 1.8.2 linux/arm64
2023-11-05 18:24:13.604595887  21:24:13.604 INF [api] listen addr=:1984
2023-11-05 18:24:13.606876311  21:24:13.606 INF [rtsp] listen addr=:8554
2023-11-05 18:24:13.607770999  21:24:13.607 INF [webrtc] listen addr=:8555
  1. But despite what says documentation and log (2 and 3 above), it only works when this default was specified explicitly. It looks pretty weird to me.

@NickM-27
Copy link
Contributor

NickM-27 commented Nov 5, 2023

  1. This may be because you're not setting candidates and the entire config is overwritten.
  2. Yeah the default has changed it seems.
  3. Not in my experience, by default I see the log says :8555/tcp

@7floor
Copy link
Author

7floor commented Nov 5, 2023

@NickM-27 just restarted and got:

2023-11-05 19:05:29.376296165  [INFO] Preparing go2rtc config...
2023-11-05 19:05:29.554253848  [INFO] Got IP address from supervisor: 192.168.2.3
2023-11-05 19:05:29.698484840  [INFO] Got WebRTC port from supervisor: 8555
2023-11-05 19:05:30.512639263  [WARN] Using go2rtc binary from '/config/go2rtc' instead of the embedded one
2023-11-05 19:05:30.512653578  [INFO] Starting go2rtc...
2023-11-05 19:05:30.722148656  22:05:30.721 INF go2rtc version 1.8.2 linux/arm64
2023-11-05 19:05:30.724315061  22:05:30.724 INF [api] listen addr=:1984
2023-11-05 19:05:30.726318616  22:05:30.726 INF [rtsp] listen addr=:8554
2023-11-05 19:05:30.727904290  22:05:30.727 INF [webrtc] listen addr=:8555
2023-11-05 19:05:39.395204978  [INFO] Starting go2rtc healthcheck service...

@7floor
Copy link
Author

7floor commented Nov 5, 2023

@NickM-27

  1. This may be because you're not setting candidates and the entire config is overwritten.

Ahhh, big thanks for that hint! Explicitly specified default candidates and now config was transferred well, along with listen parameter, so for now, my problem is solved.

@AlexxIT But ideally, those defaults have to be sorted at the go2rtc side as well, since they're documented already

@AlexxIT
Copy link
Owner

AlexxIT commented Nov 6, 2023

Defaults was changed with v1.3. But docs not.
I think fixed TCP port and random UDP port works better. But Frigate can't using random UDP port because it has closed network for container.

@7floor
Copy link
Author

7floor commented Nov 6, 2023

I would say then, that there was nothing wrong with the go2rtc as such, except that defaults changed and so documentation and its startup log (where it still writes :8555) became out of sync from actual logic since then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants