private@homelab: ~/latest
local-first guides · privacy-aware · no noisy tracking
private@homelab:~$ cat guides/article.md
· ·
7–11 minutes
read

Xiaomi Camera go2rtc Setup: Local RTSP Without the Cloud

How go2rtc's native Xiaomi source pulls Mi/Mijia camera video onto your LAN, what still touches Xiaomi's servers, and which models actually work.

Aqara devices in this cluster are the easy case. Zigbee, a hub, and Zigbee2MQTT or ZHA, and you’re mostly done with the cloud. Xiaomi and Mijia-branded cameras are a different animal entirely. There’s no Zigbee radio in a Mi camera. They talk a proprietary P2P streaming protocol back to Xiaomi’s servers, and until recently the only way to get video off that path without the Mi Home or Xiaomi Home app was rooting an old Xiaofang unit and flashing custom firmware.

That changed with go2rtc’s native Xiaomi source. I’ve been curious about this since it showed up in the project’s compatibility issue, and after going through the documentation and cross-checking it against the community tracking thread, I think it’s the missing piece for anyone who owns current-generation Xiaomi cameras and doesn’t want to keep the vendor app installed.

I want to be upfront about scope. This is a software-and-protocol walkthrough drafted from go2rtc’s own documentation and its GitHub issue tracker, not a screenshot-by-screenshot record from my own camera. Model-specific behavior and the exact first-run login screens still need hands-on confirmation against a cs2-family camera on the test bench, and I’ve flagged those points in the text. The mechanism itself (the URL format, the protocol split, the privacy nuance) is documented well enough to write up now.

What go2rtc’s Xiaomi source actually is

go2rtc is the streaming gateway written by AlexxIT that ships built into Home Assistant’s camera platform in current HA versions. Most people know it as the thing quietly handling RTSP-to-WebRTC conversion for their existing cameras. What’s less well known is that it also ships a dedicated Xiaomi protocol handler, not generic RTSP support.

That distinction matters. Xiaomi cameras don’t expose a standard RTSP endpoint. go2rtc’s Xiaomi module reimplements enough of Xiaomi’s proprietary P2P streaming protocol to pull the video stream directly, then re-serves it as RTSP or WebRTC to whatever consumes it downstream.

go2rtc documents the stream source as a URL in its config, in this format:

xiaomi://{account_id}:{region}@{camera_ip}?did={device_id}&model={model_code}

For example:

xiaomi://1234567890:cn@192.168.1.123?did=9876543210&model=isa.camera.hlc7

account_id and region (cn, de, us, etc., matching wherever the camera was originally registered in the Mi Home app) come from logging into go2rtc’s own WebUI with your Xiaomi account. did is the camera’s device ID, and model is Xiaomi’s internal model code. Two optional params are worth knowing, per the README: subtype (a quality selector, e.g. sd/hd/auto or a numeric level) and channel to select the second lens on dual-lens models.

I’m describing the URL format and the login requirement as go2rtc’s README documents them. I haven’t reproduced the exact first-run WebUI screens here, because that’s the part I want to confirm hands-on before presenting it as a step-by-step click path.

The honest privacy picture

Here’s the part I think the marketing-adjacent “no cloud” framing usually skips, and it’s worth stating plainly rather than glossing over. Setting this up requires logging into go2rtc’s WebUI with real Mi Home account credentials, region-matched to the camera, and that first login may trigger email or SMS verification or a CAPTCHA.

After that initial setup, go2rtc’s own documentation says it plainly. Each connection to the camera needs internet access to obtain an encryption key, but the actual video connection to the camera is local only. In practice that means the stream itself never leaves your LAN, but there’s a brief round-trip to Xiaomi’s servers per session to get the key needed to decrypt it.

That’s a meaningfully different posture from an air-gapped local-only device, and it’s the reason I’d frame this as “local video, cloud-brokered key” rather than “no cloud.” If your goal is to avoid Xiaomi ever seeing your footage, this delivers that. If your goal is zero contact with Xiaomi’s infrastructure, it doesn’t, and I haven’t found anything in go2rtc’s documentation suggesting that’s on a roadmap.

If you want the fuller picture of what Xiaomi’s cloud sees from the app-and-account side, I’ve looked at what data the Xiaomi Home integration actually sends and what “local” really means in Xiaomi’s official Home Assistant integration separately. The same pattern shows up: “local” usually means local data path with a cloud dependency somewhere in the setup or key-exchange step, not a full air gap.

Model compatibility: which cameras actually work

go2rtc’s Xiaomi support splits into two source formats, and which one your camera lands on matters more than the URL syntax does.

The newer format — xiaomi/mess, using the cs2 protocol (with cs2+tcp and cs2+udp variants) — is the reliable path. It covers most cameras from roughly 2020 onward, handles H.264 and HEVC, and is the one the maintainer’s README treats as the default recommendation when a camera supports it.

The older format — xiaomi/legacy, using the tutk protocol — covers models from around 2017-2019. The go2rtc maintainer’s own README is blunt about this path, describing tutk as barely functional. I’m taking that at face value rather than softening it, because it’s the project author saying so about their own code.

For which specific models fall where, the project keeps a community-maintained compatibility thread at github.com/AlexxIT/go2rtc/issues/1982. Most 2020-and-newer cameras land on the reliable cs2 path, a number of older models fall on the shakier legacy tutk path, and a few are confirmed not to work at all. The maintainer’s general guidance is that anything released after 2020 has decent odds of working even if it isn’t individually listed yet.

Worth knowing: that list is community-maintained and changes as people test new models and file issues. Treat it as a living reference to check at setup time, not a fixed spec sheet. The models confirmed today may differ from what’s confirmed by the time you read this.

Setup walkthrough (best-effort from documentation)

The rough shape of the process, per go2rtc’s README:

  1. Run go2rtc, either the bundled version inside Home Assistant’s camera platform, or a standalone Docker/binary install if you’re not on HA.
  2. Open go2rtc’s WebUI and authenticate with your Mi Home account, selecting the correct region for where the camera was registered.
  3. Locate the camera’s did (device ID) and confirm its model code, then add a xiaomi:// stream entry to go2rtc’s config using the format above.
  4. Point Home Assistant, Frigate, or another consumer at the resulting stream.

go2rtc’s README documents the URL format and the login requirement but not a screen-by-screen UI walkthrough, so the steps above are the shape of the process rather than a click path I’ve verified on a live camera.

If the WebUI login doesn’t surface a camera’s did cleanly, a widely used companion tool is PiotrMachowski’s Xiaomi Cloud Tokens Extractor (github.com/PiotrMachowski/Xiaomi-cloud-tokens-extractor), which pulls device IDs and local IPs straight from your Mi account. It isn’t a required step, and it’s the same tool many Home Assistant users already know from setting up Miio-based Xiaomi devices, so it’s a reasonable fallback if the obvious path doesn’t surface what you need.

Where the stream goes next

Once go2rtc is serving the camera as RTSP or WebRTC, it drops into any of the usual places: Home Assistant’s camera dashboard directly, Frigate for local object detection, Scrypted, or go2rtc’s own HomeKit bridge for Apple ecosystem viewing. None of these need the Mi Home or Xiaomi Home app open, or even installed, on a daily-use device.

The same go2rtc Xiaomi stream can also be pointed at a NAS-based NVR instead of an HA or Frigate box. This comes up regularly in Chinese-language smart-home communities, usually aimed at getting off Xiaomi’s paid cloud-storage tiers by routing the stream into a self-hosted NVR (EasyNVR and similar) running on an FNOS or Feiniu NAS. It’s the same underlying mechanism aimed at a different destination: instead of Home Assistant or Frigate, the stream lands on a NAS for local recording and retention. If you already run a NAS, that’s a reasonable alternative to a dedicated HA/Frigate box for storage duty.

If you’re putting a camera on your network for local-only use, it’s worth segmenting it onto its own IoT VLAN — though, as the privacy section above notes, go2rtc still needs an outbound path to Xiaomi’s servers for the per-session key, so a total outbound block will stop streams from ever starting. Putting Aqara and Xiaomi gear on an IoT VLAN covers the firewall and mDNS details for a segmented-but-reachable setup.

FAQ

Does this mean the video never touches Xiaomi’s servers?
The video stream itself stays local once it’s flowing. But each session needs a brief internet round-trip to Xiaomi’s servers to fetch an encryption key. Local video, cloud-brokered key. Not fully air-gapped.

Which Xiaomi/Mijia camera models work with go2rtc?
Most 2020-and-newer models work on the reliable cs2 (xiaomi/mess) path, a number of older models fall on the less reliable legacy tutk (xiaomi/legacy) path, and a few are confirmed unsupported. Check the live compatibility list at github.com/AlexxIT/go2rtc/issues/1982 before buying or troubleshooting, since it’s actively updated.

Do I still need the Mi Home or Xiaomi Home app after this?
Not for day-to-day viewing or recording. You’ll still need the account credentials for go2rtc’s initial login and, per the documentation, for the periodic key fetch — but the app itself doesn’t need to stay installed or open.

Is this the same as the old Xiaofang RTSP hack?
No, and that’s the point. The Xiaofang-era approach required rooting the camera and flashing custom firmware, and it only applied to that specific hardware line. go2rtc’s Xiaomi source needs no root and no firmware changes. It talks to the camera’s existing proprietary protocol from the network side.

Can I send the stream to a NAS instead of Home Assistant?
Yes. The same go2rtc Xiaomi stream can be routed into a NAS-based NVR such as EasyNVR rather than into HA or Frigate. The stream source is the same either way. Only the destination changes.

Why does go2rtc need my Xiaomi account login if the goal is avoiding the cloud?
Because Xiaomi’s protocol encrypts the stream with a key that has to be issued per session, and go2rtc needs your account credentials to request that key on your behalf. It’s a limitation of Xiaomi’s own protocol design, not a choice go2rtc made.

I haven’t run this against my own cameras yet, so the config walkthrough above is my best reading of the documentation rather than a field report. The compatibility list is also a moving target — worth rechecking against your specific model before you sink an evening into it, since the maintainer’s “post-2020 cameras probably work” guidance is a heuristic, not a guarantee.

local-firstHome Assistantno-cloud