Skip to content

JacobiusMakes/insta360-link-ctl

Repository files navigation

insta360-link-ctl

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.


Features

  • 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 hotkeysCtrl+Option+arrows to nudge, Ctrl+Option+1–9 for presets, Ctrl+Option+0 to home
  • MIDI CC control — map a physical fader controller to pan/tilt/zoom/presets

Menu bar layout

[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).


Install

git clone https://github.com/JacobiusMakes/insta360-link-ctl.git
cd insta360-link-ctl
make
make install

Then 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

Build from source

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 /Applications

Or 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-menubar

MIDI control

Connect 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

CLI tools (also in this repo)

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 ranges

insta360-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 state

Warning: USBDeviceReEnumerate can crash coreaudiod and the videoconference.camera service, 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


How it works (reverse engineering notes)

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.


Known issues

  • 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

Credits

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.

About

macOS menu bar controller for Insta360 Link webcam. Reverse-engineered PTZ, AI tracking, gestures, mic mute. No official app needed.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors