Skip to content

HomeKit Secure Video #2130

Open
skrashevich wants to merge 16 commits intoAlexxIT:masterfrom
skrashevich:hksv
Open

HomeKit Secure Video #2130
skrashevich wants to merge 16 commits intoAlexxIT:masterfrom
skrashevich:hksv

Conversation

@skrashevich
Copy link
Copy Markdown
Collaborator

@skrashevich skrashevich commented Mar 4, 2026

Summary

Add HomeKit Secure Video (HKSV) support — go2rtc can now expose any camera as an HKSV-compatible device for Apple Home, recording video clips to iCloud when motion is detected.

Key features

  • HKSV recording — fragmented MP4 (fMP4) muxer with GOP-based buffering, sent over HDS (HomeKit DataStream) protocol
  • Motion detection modes:
    • continuous — always report motion, Home Hub decides what to record
    • detect — automatic P-frame size analysis using EMA baseline (no CPU-heavy decoding needed)
    • api — external trigger via HTTP API (for Frigate, ONVIF events, etc.)
  • Doorbell supportcategory_id: doorbell with ring event API
  • Speaker service — optional 2-way audio with backchannel support
  • Standalone librarypkg/hksv/ has zero internal/ imports, can be used in any Go project

New packages

Package Description
pkg/hksv/ HKSV server, consumer (fMP4 + GOP buffer + HDS sender), session management, motion detector, helpers
pkg/hap/hds/ HDS protocol implementation (opack codec, encrypted message framing)
pkg/hap/camera/ HKSV-related HAP services and TLV8 structs (services_hksv.go, ch207.go)

New API endpoints

  • POST /api/homekit/motion?id= — trigger motion detection
  • DELETE /api/homekit/motion?id= — clear motion detection
  • POST /api/homekit/doorbell?id= — trigger doorbell ring event

Configuration

homekit:
  outdoor:
    hksv: true              # enable HKSV
    motion: detect          # continuous | detect | api
    motion_threshold: 2.0   # sensitivity for detect mode
    speaker: true           # enable 2-way audio

Binary size impact

  Branch                        Size   Size (MB)
  ---------------------------------------------------
  master                    18791634    17.92 MB
  hksv                      19012898    18.13 MB

  ---------------------------------------------------
  Difference:           +216.0 KB (+1.17%)
                       (≈ +0.21 MB)

…nctionality

- Introduced HKSV configuration options in homekit.go, allowing for motion detection and doorbell features.
- Implemented API endpoints for triggering motion detection and doorbell events.
- Enhanced server.go to handle HKSV sessions and manage motion detection states.
- Created new accessory types for HKSV and doorbell in accessory.go.
- Added support for audio recording configurations in ch207.go.
- Defined new services for motion detection and doorbell in services_hksv.go.
- Implemented opack encoding/decoding for HDS protocol in opack.go and protocol.go.
- Updated OpenAPI documentation to reflect new endpoints and features.
- Extended schema.json to include HKSV configuration options.
…g GOP buffering

The HKSV recording was failing because:
1. The dataSend.data message structure was wrong - `packets` was a flat integer
   instead of an array of objects with `data` and `metadata` fields matching
   the HAP-NodeJS specification
2. Each video/audio frame was sent as a separate mediaFragment, but Home Hub
   expects GOP-based fragments (~2-4 seconds of accumulated data)
3. Large fragments were not chunked (max 256 KiB per chunk)

Changes:
- Fix HDS dataSend.data message structure to use proper packets array with
  nested data/metadata (dataType, dataSequenceNumber, dataChunkSequenceNumber,
  isLastDataChunk, dataTotalSize)
- Add 256 KiB chunking for large media fragments
- Buffer moof+mdat pairs in hksvConsumer and flush on keyframe boundaries
  (GOP-based fragmentation)
- Pre-start consumer at pair-verify for instant init segment delivery
- Add write-response support to HAP PUT handler for ch131 DataStream setup
- Fix HAP service linking to match HAP-NodeJS reference
- Add default SelectedCameraRecordingConfiguration (ch209) value
- Start continuous motion generator at pair-verify with dedup protection
@skrashevich skrashevich changed the title WIP: HomeKit Secure Video HomeKit Secure Video Mar 5, 2026
@skrashevich skrashevich marked this pull request as ready for review March 5, 2026 03:32
@skrashevich
Copy link
Copy Markdown
Collaborator Author

It's not ready to merge yet, but it is already fully functional and ready for testing by any user

…sumer

HDS protocol tests (15 tests, 4 benchmarks):
- Message structure for SendMediaInit and SendMediaFragment
- Multi-chunk splitting for fragments > 256KB
- Chunk boundary handling and sequence preservation
- WriteEvent/WriteResponse/WriteRequest round-trip
- opack helper functions

HKSV consumer tests (14 tests, 3 benchmarks):
- Consumer creation and field initialization
- GOP buffer flush with sequence numbering
- Activate with init segment and seqNum=2
- Activate timeout and error handling
- Stop safety (double-stop, deactivation)
- WriteTo blocking until Stop

Also fixes broken hds_test.go (undefined Client → NewConn).
Replace time.Now() calls in hot path with frame-based timing:
- Pre-compute triggerLevel (integer comparison instead of float division)
- Calibrate hold/cooldown budgets from FPS (default 30fps)
- Periodic FPS recalibration every 150 frames for accuracy
- Active motion path: 47ns → 3.6ns (13x faster)

Update schema.json with detect mode and motion_threshold.
Add threshold tuning guide to README.
@mikemwalsh
Copy link
Copy Markdown

I’m going to jump on trying this right away. I’ve been hoping for this for a while!!

- Implemented MotionDetector for detecting motion based on H.264 P-frame sizes.
- Introduced adjustable sensitivity threshold for motion detection.
- Added tests for various scenarios including motion detection, hold time, cooldown, and baseline adaptation.
- Created hksvSession to manage HDS DataStream connections for HKSV recording.
- Updated schema.json to include a new speaker option for 2-way audio support.
@mikemwalsh
Copy link
Copy Markdown

@skrashevich first initial attempt for this was partially successful. I was able to add the camera and the hksv settings were enabled in the home app settings (when/what to record). I set it up to record all motion but it seems that part was not working. No recordings were ever triggered. I am using the basic “continuous” motion config, have not tried to get the motion api hooked up yet.

@skrashevich
Copy link
Copy Markdown
Collaborator Author

skrashevich commented Mar 6, 2026

@skrashevich first initial attempt for this was partially successful. I was able to add the camera and the hksv settings were enabled in the home app settings (when/what to record). I set it up to record all motion but it seems that part was not working. No recordings were ever triggered. I am using the basic “continuous” motion config, have not tried to get the motion api hooked up yet.

Try to update to the latest version of this PR

It’s a known bug, I hope i fixed it in c567831

@mikemwalsh
Copy link
Copy Markdown

@skrashevich first initial attempt for this was partially successful. I was able to add the camera and the hksv settings were enabled in the home app settings (when/what to record). I set it up to record all motion but it seems that part was not working. No recordings were ever triggered. I am using the basic “continuous” motion config, have not tried to get the motion api hooked up yet.

Try to update to the latest version of this PR

It’s a known bug, I think I fixed it

Will try this afternoon if possible! Thanks

@skrashevich
Copy link
Copy Markdown
Collaborator Author

skrashevich commented Mar 6, 2026

Will try this afternoon if possible! Thanks

In any case, try to re-pair the camera in HomeKit.
Make sure your Apple TV/HomePod (HomeKit hub) has the latest software installed
Make sure you have an active iCloud subscription and haven't exceeded the limit for the number of cameras or storage space

@mikemwalsh
Copy link
Copy Markdown

Worked with the latest commit! I currently use the same cameras via scrypted for this use case. So I can easily do a side by side on functionality.

Great work so far, this is a game changer in my opinion. When this is stable, I can’t wait to try to integrate it directly into thingino on camera (thingino optionally supports go2rtc)

@skrashevich
Copy link
Copy Markdown
Collaborator Author

Worked with the latest commit! I currently use the same cameras via scrypted for this use case. So I can easily do a side by side on functionality.

Great work so far, this is a game changer in my opinion. When this is stable, I can’t wait to try to integrate it directly into thingino on camera (thingino optionally supports go2rtc)

Although my motion detector implementation is very "cheap" in terms of CPU, I'm not sure if the camera's processor can handle it

@mikemwalsh
Copy link
Copy Markdown

Worked with the latest commit! I currently use the same cameras via scrypted for this use case. So I can easily do a side by side on functionality.
Great work so far, this is a game changer in my opinion. When this is stable, I can’t wait to try to integrate it directly into thingino on camera (thingino optionally supports go2rtc)

Although my motion detector implementation is very "cheap" in terms of CPU, I'm not sure if the camera's processor can handle it

With motion set to continuous is it needed?

@skrashevich
Copy link
Copy Markdown
Collaborator Author

skrashevich commented Mar 6, 2026

With motion set to continuous is it needed?

No. Continuous is an emulation of a motion sensor that just reports motion event every 30 seconds.

@mikemwalsh
Copy link
Copy Markdown

Worked with the latest commit! I currently use the same cameras via scrypted for this use case. So I can easily do a side by side on functionality.

Great work so far, this is a game changer in my opinion. When this is stable, I can’t wait to try to integrate it directly into thingino on camera (thingino optionally supports go2rtc)

seems like two way audio is broken now though. the talk button has disappeared. (cam in go2rtc via onvif)

@skrashevich
Copy link
Copy Markdown
Collaborator Author

skrashevich commented Mar 6, 2026

seems like two way audio is broken now though. the talk button has disappeared. (cam in go2rtc via onvif)

homekit:
  camera1:
    hksv: true
    speaker: true # RTFM !

@nschimme
Copy link
Copy Markdown

nschimme commented Mar 7, 2026

Very nice! Do ONVIF motion events trigger the motion for HKSV or do we need a third party program to hit that API?

@skrashevich
Copy link
Copy Markdown
Collaborator Author

Do ONVIF motion events trigger the motion for HKSV

Currently -- no. I don't have cameras with ONVIF motion detector for such development and testing.

@nschimme
Copy link
Copy Markdown

nschimme commented Mar 7, 2026

I don't have cameras with ONVIF motion detector for such development and testing.

You should be able to emulate one with https://github.com/roleoroleo/onvif_simple_server and a RTSP feed. I noticed that the HomeKit source already is able to forward motion events to a destination. Ideally this is generalized such that other motion events are supported. Maybe a follow up PR :-)

@sherbibv
Copy link
Copy Markdown

sherbibv commented Mar 8, 2026

This looks great! Will try this out ASAP 🙌

@coniman
Copy link
Copy Markdown

coniman commented Mar 9, 2026

Hi guys! Right now im working on a project to automate my analog intercom. I'm using an IP camera pointing to my door and a Raspberry Pi to transmit the audio from the 4N intercom. I've created a device in Go2RTC that mixes the camera's video with the incoming intercom audio, and I've also added the outgoing intercom audio as a backchannel. But I'm having trouble with two way audio as HomeKit outputs audio in OPUS raw packets (as far as I know) and I'm unable to decode them with ffmpeg. Using go2rtc website everything works perfectly. Also I'm trying to set it up as a video doorbell, but im getting "out of compilance error", if I disable category: doorbell it works but as simple cam and the trigger doorbell ring event is not working.
This is my config:

log:
  level: debug

api:
  listen: ":1984"

rtsp:
  listen: ":8554"

webrtc:
  listen: ":8555"

streams:
  intercom:
    - exec:ffmpeg -loglevel error -rtsp_transport tcp -analyzeduration 100000 -probesize 100000 -fflags nobuffer -flags low_delay -i rtsp://XXX:XXX@192.168.2.15:554/stream1 -f alsa -thread_queue_size 1024 -ac 1 -ar 48000 -i plughw:0,0 -map 0:v -map 1:a -c:v copy -c:a libopus -ar 48000 -ac 1 -b:a 32k -vsync passthrough -f rtsp {output}
    - exec:ffmpeg -loglevel debug -fflags nobuffer -protocol_whitelist file,pipe,rtp -f rtp -payload_type 111 -i pipe:0 -c:a copy -f rtp rtp://239.11.11.11:1234#backchannel=1#audio=opus/48000

homekit:
  intercom:
    hksv: true              # enable HKSV
    motion: continuous      # continuous | detect | api
    motion_threshold: 2.0   # sensitivity for detect mode
    speaker: true

I've set up the audio to be streamed over UDP for testing and this is what I get when I press Talk button in Home App:

06:47:05.210 DBG [exec] [rtp @ 0x1778db0] Unsupported RTP version packet received
06:47:05.331 DBG [exec]     Last message repeated 5 times
[rtp @ 0x1778db0] Received too short packet
06:47:05.350 DBG [exec] [rtp @ 0x1778db0] Unsupported RTP version packet received
06:47:05.370 DBG [exec] [rtp @ 0x1778db0] Received too short packet

Any help is appreciated

- implement ONVIF motion watcher to handle motion events
- add configuration options for motion hold time and ONVIF URL
- remap motion mode from "onvif" to "api" for compatibility
- log ONVIF motion watcher activity for better debugging

feat(onvif): implement event subscription for motion detection
- create PullPoint subscription to receive motion events
- implement methods for pulling messages and renewing subscriptions
- handle event requests and responses specific to motion detection

test(onvif): add unit tests for motion event parsing and subscription
- create tests for parsing various motion event XML responses
- verify correct handling of multiple notifications and edge cases
- test resolving event addresses for ONVIF clients

fix(hksv): improve motion detection logging
- log warnings when accessory or character not found during motion detection
- log number of listeners notified during motion state changes

feat(hap): add listener count method
- introduce method to retrieve the number of listeners for a character

feat(onvif): enhance ONVIF client with event URL handling
- extract event URL from ONVIF device response for subscription management
@mikemwalsh
Copy link
Copy Markdown

The ONVIF commit is pretty huge. I’ll go back to onvif on mine and test. Thanks for all the work on this.

Can confirm after a few days with the previous commit I am getting consistent recordings to hksv so far!

@mikemwalsh
Copy link
Copy Markdown

Can confirm the onvif motion detection triggered and hksv recorded with default settings hooked up to a Wyze cam v3 running Thingino. Great work!!

FYI your commit did not update the Yaml schema.json with the onvif option so web
Ui schema validation fails.

@AlexxIT AlexxIT added enhancement New feature or request module/homekit labels Mar 10, 2026
@AlexxIT AlexxIT self-assigned this Mar 10, 2026
…d motion detection modes to include 'onvif' for event subscription - introduce 'motion_hold_time' to manage active motion duration - add 'onvif_url' for specifying ONVIF device URL for detection
@skrashevich
Copy link
Copy Markdown
Collaborator Author

FYI your commit did not update the Yaml schema.json with the onvif option so web

Thank you. I really forgot.

@digaus
Copy link
Copy Markdown

digaus commented Apr 13, 2026

@mikemwalsh
How is the performance compared to Scrypted?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request module/homekit

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants