AlexxIT / go2rtc

Ultimate camera streaming application with support RTSP, RTMP, HTTP-FLV, WebRTC, MSE, HLS, MP4, MJPEG, HomeKit, FFmpeg, etc.
https://github.com/AlexxIT/Blog
MIT License
7.06k stars 505 forks source link

Video Freezing Issue with WebRTC via WireGuard VPN #1358

Open barzag opened 2 months ago

barzag commented 2 months ago

Hello everyone,

I am experiencing an issue with configuring WebRTC over a WireGuard VPN, and I hope someone can help me resolve it.

Context I have a setup using Go2RTC to stream video via WebRTC. My Go2RTC server is locally accessible at the following address: 10.14.4.39:1984. The server is configured to receive RTSP streams from several Reolink cameras.

I want to access these video streams remotely using a WireGuard VPN. Here are the details of my configuration:

Go2RTC Configuration:

api:
  origin: '*'
hass:
  config: /config
log:
  format: text
rtsp:
  default_query: mp4
streams:
  reolink_camera_3:
  - ffmpeg:https://10.22.10.145/flv?port=1935&app=bcs&stream=channel0_main.bcs&user=admin&password=$$$$$$$$@nvhhC#video=copy#audio=copy#audio=opus
  reolink_camera_4:
  - ffmpeg:https://10.22.10.144/flv?port=1935&app=bcs&stream=channel0_main.bcs&user=admin&password=$$$$$$$@nvhhC#video=copy#audio=copy#audio=opus
  reolink_camera_5:
  - ffmpeg:https://10.22.10.148/flv?port=1935&app=bcs&stream=channel0_main.bcs&user=admin&password=$$$$$$$@nvhhC#video=copy#audio=copy#audio=opus
webrtc:
  candidates:
  - stun:8555

When I configure the client’s AllowedIPs to only the local subnet (10.14.4.0/24), the videos freeze after 35 seconds. However, with AllowedIPs set to 0.0.0.0/0, the videos do not freeze but are unstable and exhibit intermittent issues.

Additionally, this issue occurs only when using a cellular network; it does not occur when connected via Wi-Fi.

Why does the video freeze when AllowedIPs is limited to the local subnet? What adjustments should I make in the WireGuard client configuration to avoid this issue? Are there any additional checks or recommended tests to diagnose this problem? Thank you in advance for any help or suggestions you might have. Please feel free to ask for more information if needed.

AlexxIT commented 2 months ago

I think go2rtc doesn't get feedback from the browser, thinks there is no more connection and stops the stream. Configuring WebRTC to work properly across different subnets is a very complex task. For both participants in the transfer, the route must be clear in both directions.

barzag commented 2 months ago

Hi Alex, thank you for your response.

Both sites have routing systems in place that correspond to each other's local networks. To clarify, site 1 has the local network route for site 2, and vice versa. Therefore, routing between the two should be clear in both directions. Additionally, there are no firewall rules that could be blocking the different streams.

I also added the following lines to try to ensure the WebRTC stream stays local, but this hasn’t resolved the issue:

webrtc:
  candidates:
    - 10.14.4.39:8555 (go2rtc server)
    - 10.22.10.30:855 (Home Assistant server, which relays the WebRTC stream in a WebRTC card)
    - stun:8555

Do you have any other suggestions I could try to resolve this problem? Thank you again for your help.

AlexxIT commented 2 months ago

You should open WebRTC debugger in the browser and check there. Chrome has good one.

candidates only make sense for the first connection. As you say - the connection happens without any problems. However, candidates may not be used at all if go2rtc connects to the browser (like client to server).

barzag commented 2 months ago

The issue only occurs on the HA iOS app, while it doesn't appear on Windows. Do you have any idea what might be causing this? Is there a way to debug this on an iPhone?

Thank you again for your help!

https://github.com/user-attachments/assets/9154504c-f4ce-435b-98f4-89e799effc85

AlexxIT commented 2 months ago

I have theory that Safari doesn't support WebRTC over TCP. And support only UDP. But it's only theory.

You can check stream info in the go2rtc WebUI. Also you can enable trace log level for WebRTC module.

barzag commented 2 months ago

I tried Chrome and Firefox on iOS. The problem remains the same. The only solution is to allow all IP addresses in the WireGuard client configuration (0.0.0.0/0). However, when I try to switch between different cameras, the connection takes a long time to reestablish. I have to wait a good twenty seconds. It's really a headache :)

AlexxIT commented 2 months ago

iOS has only one browser. All others just a skin for WebView.

barzag commented 2 months ago

Okay, no apparent solution it seems?

AlexxIT commented 2 months ago

Just not use WebRTC. Select MSE

barzag commented 2 months ago

With the MSE option on the Frigate Lovelace card, the video stream does not load at all.

AlexxIT commented 2 months ago

Have you tried go2rtc WebUI or WebRTC custom card? I don't know if Frigate Lovelace card supports custom MSE modification from Apple. Also you should have iOS 17.1+.

barzag commented 2 months ago

I believe the issue stems from the fact that I’m using multiple subnets to view my streams. Let me explain: the Frigate machine is on the 10.14.4.0/24 subnet, while Home Assistant is on the 10.22.10.0/24 subnet. When I view my video stream directly through the Frigate app using a WireGuard connection, everything works smoothly without interruptions. However, as soon as I route the stream to Home Assistant (10.22.10.30) via the Lovelace card or any other method (classic image card, WebRTC, etc.), the stream becomes unstable. I’m not entirely familiar with how WebRTC functions in this setup, but the problem likely lies there. Do you have any suggestions?

I’m running iOS 18.

barzag commented 2 months ago

It seems impossible to maintain a WebRTC connection locally because when I route the entire network through WireGuard (0.0.0.0/0), there are no disconnections but some intermittent bugs. On the other hand, when I allow only local networks (10.22.10.0/24 and 10.14.4.0/24), there are no intermittent bugs, but the connection stops after 35 seconds and then restarts. Is there any way to force WebRTC traffic to stay strictly local and avoid using STUN, ICE, Google, etc.?

AlexxIT commented 2 months ago

WebRTC is always trying to connect in every way possible. Host connection has higher priority than STUN connection. If you don't use TURN - it's always a direct connection with no middleware (HomeAssistant, etc.)