A 50KB native macOS menu bar app that fully controls the Insta360 Link webcam — no Insta360 Link Controller required.
The official app is ~200MB, hangs constantly, and the camera won't respond to standard UVC commands without its proprietary initialization sequence. This replaces it entirely by reverse-engineering the USB/UVC Extension Unit protocol.
- Drag-to-pan trackpad in the menu dropdown — click and drag to aim the camera
- Scroll wheel zoom on the trackpad area
- AI tracking modes — Body Track, Head Track, DeskView, or off
- Gesture toggles — enable/disable AI tracking gesture, zoom gesture, whiteboard mode
- Mic mute with current state shown in the menu
- Saveable presets — name and store up to 9 positions, persisted to
~/.config/insta360-ptz/presets.json - Global hotkeys —
Ctrl+Option+arrowsto nudge,Ctrl+Option+1–9for presets,Ctrl+Option+0to home - MIDI CC control — map a physical fader controller to pan/tilt/zoom/presets
[camera icon]
┌─────────────────────────────────────┐
│ [drag pad — 240×100px] │
│ ← → ↑ ↓ │
│ drag • scroll zoom • dblclick home│
├─────────────────────────────────────┤
│ AI Off │
│ Body Track │
│ Head Track │
│ DeskView │
├─────────────────────────────────────┤
│ Gesture: AI Track [checkmark] │
│ Gesture: Zoom │
│ Gesture: Whiteboard │
├─────────────────────────────────────┤
│ 🔊 Mic On [m] │
├─────────────────────────────────────┤
│ PRESETS │
│ Desk [1] │
│ Whiteboard [2] │
│ Wide [3] │
│ + Save Current Position... [s] │
│ - Delete Last Preset │
│ Reset to Defaults │
├─────────────────────────────────────┤
│ HOTKEYS (^⌥+key) │
│ 1-9: presets arrows: move +/-:z │
├─────────────────────────────────────┤
│ Quit [q] │
└─────────────────────────────────────┘
Double-click the drag pad to return to home position (pan=0, tilt=0, zoom=1x).
git clone https://github.com/JacobiusMakes/insta360-link-ctl.git
cd insta360-link-ctl
make
make installThen open "Insta360 Link Ctl" from Spotlight or your Applications folder. The 🎥 icon appears in your menu bar — no dock icon, no window.
For global hotkeys, add the app to System Settings > Privacy & Security > Accessibility.
Requirements:
- macOS 12+ (tested on macOS 14.6.1, Apple Silicon)
- Insta360 Link connected via USB
- No Xcode — Command Line Tools is enough:
xcode-select --install
Single Objective-C file, no external dependencies — just macOS frameworks.
make # builds app bundle + CLI tools
make install # copies to /Applications
make uninstall # removes from /ApplicationsOr build manually:
clang -framework IOKit -framework CoreFoundation -framework AppKit \
-framework Foundation -framework QuartzCore -framework CoreMIDI \
-O2 -fobjc-arc -Wno-deprecated-declarations \
-o insta360-menubar insta360-menubar.m
./insta360-menubarConnect any MIDI controller before launching. All sources are auto-connected.
| CC | Function | Range |
|---|---|---|
| 1 | Pan | full range |
| 2 | Tilt | full range |
| 7 | Zoom | 1x–4x |
| 20 | Recall preset 1 | val > 0 |
| 21 | Recall preset 2 | val > 0 |
| 22 | Recall preset 3 | val > 0 |
| 23 | Recall preset 4 | val > 0 |
| 24 | Recall preset 5 | val > 0 |
insta360-ptz.c — Scriptable pan/tilt/zoom control
clang -framework IOKit -framework CoreFoundation -O2 -o insta360-ptz insta360-ptz.c
./insta360-ptz --get # current position
./insta360-ptz --pan 30 --tilt -15 # move to absolute angle (degrees)
./insta360-ptz --zoom 200 # zoom value (100=1x, 400=4x)
./insta360-ptz --preset desk # named preset
./insta360-ptz --home # center + min zoom
./insta360-ptz --probe # discover control rangesinsta360-wake.c — USB re-enumerate to wake the camera from firmware standby
clang -framework IOKit -framework CoreFoundation -O2 -o insta360-wake insta360-wake.c
./insta360-wake # one-shot wake
./insta360-wake --keepalive # wake + re-wake every 4 minutes
./insta360-wake --status # check camera stateWarning:
USBDeviceReEnumeratecan crashcoreaudiodand thevideoconference.cameraservice, requiring a reboot to recover. This method is disabled in the menu bar app. A safe wake path is still being researched.
xu-bruteforce.c — Enumerate all XU selector values on the camera
usb-dump-descriptors.c — Full USB descriptor parser/pretty-printer
The Insta360 Link (VID 0x2e1a, PID 0x4c01) is UVC 1.16 compliant with three proprietary Extension Units beyond the standard camera terminal:
| Unit | GUID | Selectors |
|---|---|---|
| XU9 | FAF1672D-B71B-4793-8C91-7B1C9B7F95F8 |
30 |
| XU10 | E307E649-4618-A3FF-82FC-2D8B5F216773 |
6 |
| XU11 | A8BD5DF2-1A98-474E-8DD0-D92672D194FA |
5 |
Pan and tilt use standard UVC Camera Terminal controls (CT_PANTILT_ABSOLUTE 0x0D, CT_ZOOM_ABSOLUTE 0x0B). The proprietary features go through XU9 via UVC class-specific SET_CUR/GET_CUR requests.
Ranges:
- Pan: ±145° (±522000 arc-seconds in UVC units, 1 arc-second = 1/3600°)
- Tilt: -90° to +100° (−324000 to +360000)
- Zoom: 1x–4x (100–400 in UVC units)
XU9 control map (reverse-engineered by diffing selector values while toggling features in the official app):
SEL2 [byte0, byte1] — AI Mode
00 03 = off
00 10 = Body Track
01 10 = Head Track
06 10 = DeskView
SEL5 [byte0] — Gesture bitmask
0x02 = AI tracking gesture
0x04 = zoom gesture
0x08 = whiteboard mode
SEL8 [byte2] — Mic mute
0x00 = unmuted
0x50 = muted
Reads use GET_LEN (bRequest 0x85) first to determine the actual selector payload size before issuing GET_CUR, which is required for reliable reads on this camera.
- USBDeviceReEnumerate (the only discovered wake method) crashes
coreaudiod— currently disabled in the menu bar app, safe wake research ongoing - Global hotkeys require Accessibility permission (System Settings > Privacy & Security > Accessibility)
- Gesture controls require the camera to be in an active/initialized state to take effect
Built by reverse-engineering USB traffic from the official Insta360 Link Controller app using USB packet capture. The XU control map was discovered by diffing Extension Unit selector values while toggling features in the app.