Nine cameras had been running on a Banana Pi M5 for over six months, and the engineering debt accumulated since v0.6 had reached the point where it needed paying off. The /api/cameras endpoint would stall for 14.9 seconds while all 9 recorders started up — not because the traversal was slow, but because the cm.mu RWMutex was blocking, holding every read operation out. ONVIF camera addition still required typing in IP addresses manually, and with a household of CW500s, DS-2CD2047G2s, and others, every new camera meant opening a terminal session — not sustainable. FFmpeg as the only third-party binary dependency meant every deployment needed a check for whether it was installed, and on Raspberry Pi you also had to worry about hardware encoder compatibility. And the older Xiaomi devices — Dafang, Xiaofang, Aqara G2 — couldn’t be integrated at all because they speak the TUTK protocol. None of these are new technical challenges; they’re engineering debt, and v0.9 pays it off in one shot.
The previous post covered what v0.3.0 ships. This one covers why — this release has three seemingly casual decisions with specific engineering trade-offs behind them: how the Docker network mode decides the scanner’s probe fidelity, why TLS cert-chain collection can cover eight protocols with one core, and why L2 topology needs three MIBs to assemble. Let’s take them one at a time.
Docker Network Mode vs Probe Fidelity This is the hardest engineering finding in this release, and the reason v0.3.0 ships container images at all. Measured on the test LAN (31 devices):
Take over an unfamiliar LAN and the first thing you need is to figure out what’s on it — office, server room, and home subnets tangled together, no documentation left behind, a switch full of MACs nobody can name. MiBeeSteward exists for exactly that: scan the network and tell you what devices are there, what they are, and how they connect.
v0.3.0 goes after three specific pains left over from the last two releases:
The previous post covered what v0.2.0 ships. This one covers why it’s designed that way — distributed consistency is the heaviest part of this release, and several seemingly casual decisions have specific trade-offs behind them.
The problem is clear: the center can only see its own LAN, but users have several. Dropping a center into every subnet isn’t realistic, so enter mibee-agent — a binary that only “scans local + reports to center.” But the moment an agent exists, it drags along a whole string of protocol questions: how to report, how to reconcile, how to detect offline, how not to overwhelm the center’s writes. Let’s take them one at a time.
When v0.1.0 shipped, I wrote that it answers three questions: what devices are on the network, what they are, and how they relate. Honestly, v0.1.0 only answered the first half well — and only for the one LAN the center sat on.
The real-world layout is messier: one subnet in the office, one in the server room, another at home for test machines. The center lives in the office and literally cannot see the cameras in the server room. Getting it to scan the server room means crossing subnets — either opening up SNMP routing or just moving the center over there. Neither is elegant.
As a studio operator, the biggest pain point is never a specific problem — it’s the “not knowing” when devices multiply.
Not knowing which devices are alive, what services are running on them, whether a new machine has appeared on the network, whether a certain port is still open. This accumulated “not knowing” eventually becomes an outage.
My previous approach was a patchwork: Zabbix for monitoring, Nmap for scanning, Excel for asset tracking, Prometheus for metrics. Each tool is fine on its own, but together they’re a disaster — data silos, duplicate configuration, version drift, complex deployment.
It doesn’t matter how good your content is — if search engines can’t crawl it and users can’t find it, it might as well not exist. That sounds harsh, but for the vast majority of independent blogs it’s simply the truth. Your server sits on some VPS, your domain has little authority, backlinks are scarce, and Googlebot might swing by only once a month — and every time it does, it sees the same content from weeks ago. The keywords readers type into the search box will never point to your pages. A painstakingly polished technical article ends up gathering dust in your own archive page.
To push camera feeds from the MiBee NVR project to a domestic live-streaming platform, there are three candidates: call FFmpeg directly, use the pure-Go gortmplib, or use go2rtc. All three “do RTMP”, but their behaviour against Chinese live-streaming platforms differs wildly — some disconnect instantly, some after a few seconds, some are rock solid. This post tears all three apart at the source level, and walks through the pitfalls and fixes for integrating with FMS-compatible domestic platforms.
Zhi theme v0.2.0 is out — the most significant feature update since the initial release back in April. This release addresses real needs accumulated from personal usage and iterative development.
In a nutshell:
Language switcher: Globe icon button with CSS dropdown, auto-linking translated pages Post Series: Series overview page (card layout) + detail page (stepper/timeline layout) with sort toggle Mermaid v11+: Async render API with reliable dark mode adaptation Plus a slew of bug fixes and comprehensive documentation updates Let’s walk through each feature.
After v0.6.0 put the timelapse pipeline in place, community feedback quickly pointed out several hard problems: the JPEG sequence consumed too much storage, H.265 cameras couldn’t generate playable timelapse segments, dual-lens Xiaomi devices could only capture the main lens, and H.265 HLS would occasionally panic outright. None of these are edge cases — the dual-lens CW500 and Outdoor Cam 4 ship in large volumes in China, and H.265 is the de facto standard for mid-to-high-end cameras. The v0.7.0 mainline was built around exactly this feedback.