Skip to content

Frequently Asked Questions (FAQ)

tsightler edited this page May 10, 2022 · 19 revisions

Video Streaming

Q) Why do streams keep running for ~5 minutes after viewing them in Home Assistant?
A) Home Assistant keeps streams running in the background for ~5 minutes even when they are no longer viewed and, even if you stop the stream, Home Assistant will continue to reconnect until the 5 minute timeout. You can work around this by using the RTSPtoWebRTC component which has a 30 second timeout, but has other negative side effects like being difficult to use when outside of your network.

Q) Streams keep starting all the time even when I'm not viewing anything
A) In Home Assistant, do not use the "Preload Stream" option and make sure the Camera View setting in the Picture Glance card is set to "auto" instead of "live". If you use the "live" setting, the card will attempt to start streams in the background for faster startup when you bring up the card. This is fine for local cameras but, because Ring cameras do not send motion events during streams, having streams running all the time will cause motion events to be missed and, since all streaming goes through Ring servers on the Internet, you will use a lot of bandwidth as well.

There have also been reports of certain components connecting to live streams with when no password is set on the RTSP server, I've not personally seen this behavior but multiple users have sent log examples showing "something" connecting to the RTSP server which triggers the stream to start. The simplest way to solve this is to set a livestream username/password so that services which automatically discover RTSP endpoints cannot connect and start streams.

Q) Why does the live stream stop after ~10 minutes even if I'm still viewing?
A) Ring enforces a time limit on active live streams and terminates them, typically after approximately 10 minutes, although sometimes significantly less and sometimes a little more. Currently, you'll need to refresh to manually restart the stream but it is NOT recommended to attempt to stream 24 hours. Ring has hinted that continuous live streaming is something they are working on, but, for now, the code honors the exiting limits and does not just immediately reconnect to the stream unless there is a new request from a frontend client.

Q) Why is the stream delayed/lagged?
A) The code path for streaming is quite optimized and typically adds less than one second of latency, however, Home Assistant uses the LL-HLS protocol for streaming in the web browser which splits the existing stream into segments for delivery over HTTP/HTTPS. While HLS streaming is extremely reliable and widely compatible with various web browsers and network setups, it typically adds 3-5 seconds of delay which is serviceable for live viewing in many cases, but not really ideal. Unfortunately, because of the way LL-HLS segments the stream for delivery over HTTP/HTTPS, it can lead to an increase in artifacts and video stuttering, see the question below on video artifact/stuttering for more details on possible mitigations for this behavior.

For the lowest latency viewing possible, the best solution for Home Assistant is to use the RTSPtoWebRTC integration. This integration overrides the Home Assistant frontend default use of LL-HLS and instead uses WebRTC, which leverages the native streaming capability available in modern web browsers. The RTSPtoWebRTC integration requires either the RTSPtoWebRTC or RTSPtoWeb addon to be installed as well. The RTSPtoWebRTC addon supports audio, while the RTSPtoWeb component is considered more reliable and robust, but currently is video only. Testing has shown the RTSPtoWebRTC integration in concert with the RTSPtoWebRTC addon to provide the best front-end streaming experience with fast startup, low latency (1-2 seconds) and smooth display, however, this comes with one big negative, current versions work only on when both client and server are on the same local network. Hopefully this will be addressed in future versions.

Other options that offer low-latency viewing are the use an external media player capable of RTSP playback. VLC works well, but note that it buffers 1 second of video by default, although on fast networks you can tweak this to as low as 0 milliseconds to reduce the delay even further.

Q) Why do I have video artifacts and/or stuttering in the stream?
A) There are three likely sources of artifacts/stuttering and I'll outline each of these below: The first and most common issue is that Ring streams include a significant number of minor encoding anomalies, especially in the first 5-10 seconds of the stream. I initially thought this was a bug in stream handling pipeline but further investigation showed that the same anomalies exist in the video recording files downloaded directly from Ring servers, so it clearly indicates the error is in the initial stream encoding from the camera. These anomalies are overall minor and go largely unnoticed in media players that decode the H264 stream directly, however, they are amplified by the Home Assistant stream component which uses specific markers to split the RTP stream into the required HLS segments and this is even more troublesome for LL-HLS, which further chunks the streams into even smaller parts. The following settings have been found to minimize (not eliminate) the artifacts while keeping most of the benefit of the LL-HLS protocol (only a small increase in latency over the defaults):

stream:
  ll_hls: true
  segment_duration: 2.9
  part_duration: 1.45

The second issue mostly impacts the live stream which uses WebRTC to stream encrypted RTP over UDP. WebRTC is normally handled natively by the web browser, however, ring-mqtt and ring-client-api (the API layer that makes ring-mqtt possible) is written in Javascript and runs in NodeJS, which, unfortunately, has no native WebRTC implementation. Instead, ring-client-api uses WeRIFT (WebRTC Implementation for TypeScript) which means that the entire RTP stream is processed in Javascript code before being piped via FFmpeg to the RTSP server. While NodeJS is quite fast for running an interpreted language like JavaScript, it's still not exactly the most efficient for real-time stream processing that requires per-packet decryption meaning significant amount of CPU is used per-stream.

While Intel CPUs seem to be able to keep up fairly easily, the story is not as good for low-power ARM CPUs, like those in devices such as the Raspberry Pi, which generally run NodeJS at 25% of the speed of even decade old Intel CPUs. Because of this, these systems sometimesstruggle to process the stream without dropping packets, especially during initial stream startup. While I have put significant effort into optimizing the processing pipeline, including implementation a thread pool that attempts to balancing the load of processing multiple video streams across the available CPU cores, it's still very difficult for these lower end CPUs to keep up with the data rates.

Having a good CPU and a solid networking setup that does not drop UDP packets is critical to reliable and artifact free function of the live stream. If you have multiple cameras, or a system with limited CPU/RAM (RPi3 for example) then it will be difficult to support more than a handful of streams concurrently. Testing shows that an RPi3 struggles to support more than 2-3 concurrent streams without significant artifacts while an RPi4 can handle 4-5 concurrent streams before artifacts become a major issue. Intel based machines can handle ~3-4 live streams per-core, although this can vary significantly based on the processor type. These numbers assume that the load on the CPU from other components is minimal. Another way to look at it, once CPU load approaches 70%, artifacts begin to appear more frequently.

A third issue, which really is part of the second issue, is the limited size of the default UDP buffers in Linux which are usually only about 200KB. Even if WeRIFT can mostly keep up with the stream, small bursts of CPU activity can cause a delay in processing and, due to the small buffer size, packets end up being dropped before they are processed into the WeRIFT media pipeline. On lower end processors increasing the buffer size to something more reasonable like 2-4MB can make dramatic difference in stream reliability, especially with multiple concurrent streams. Unfortunately, since ring-mqtt is commonly run inside a container, it's not possible for the code to automatically increase these buffers as they must be increased on the host OS.

When running a Docker or manual install you can simply increase net.core.rmem_max/rmem_default values on the host OS using sysctl.conf or other supported methods for the given Linux distribution. This is more complex for those using the addon with Home Assistant OS, which doesn't even allow SSH access to the actual host OS by default. However, if you want to improve your video quality in this case it is possible to follow [these instructions] (https://developers.home-assistant.io/docs/operating-system/debugging/) to enable full SSH access to the host. Once rool level ssh to the host OS is possible (must be the real debug/developer console root, not the SSH console provided by some addons) you can then perform the following steps:

# cd /etc/udev/rules.d
# vi 99-local.rules

Copy and paste the following:

ACTION=="add", SUBSYSTEM=="net", RUN+="/bin/sh -c 'sysctl -w net.core.rmem_max=2097152'"
ACTION=="add", SUBSYSTEM=="net", RUN+="/bin/sh -c 'sysctl -w net.core.rmem_default=2097152'"

Save the file (:wq) and reboot the host, log back in and verify that /proc/sys/net/core/rmem_max/default are set to 2097152 (2MB) instead of the default (~200KB). This implements the update of UDP buffers as a UDEV rule because /etc/udev/rules.d is one of the few mount points that is persistent within Home Assistant OS and thus the changes made this way should survive reboots and future OS updates.

Q) Why do I see high memory usage?
A) Support for live streaming uses rtsp-simple-server, which is a binary process running in addition to the normal node process used by ring-mqtt. When idle, this process uses minimal memory (typically <20MB). However, each active stream has at least one FFmpeg process to read the incoming stream and publish it to the server. Total memory usage is typically about 25-30MB per each active stream on top of the base memory usage of the addon. Also, when using Home Assistant, the Home Assistant core memory usage will also increase somewhat for each stream. The worker thread pool needed for WebRTC support in 5.x uses additional memory as well. Typical memory usage should be between 250-350MB when running 5-6 streams.

Q) Why are there no motion events while live streaming?
A) This is a limitation of Ring cameras as they do not detect/send motion events while a stream/recording is active. The code itself has no limitations in this regard.

Q) Why do I have so many recordings on my Ring App?
A) If you have a Ring Protect subscription then all "live streams" are actually recording sessions as well, so every time you start a live view of your camera you will see a recording in the Ring app.