brad cca3c1f2b4 Test the OBS script against a mock OBS API
The OBS script was the largest piece with no coverage, and its failure mode
inside OBS is silence rather than an error, so wiring mistakes would have
surfaced only as "the hotkey does nothing".

Mocks obslua and drives the script through the sequence OBS uses: defaults,
update, load, hotkey callbacks, frontend events, properties, save, unload.
Asserts the behaviour that is easy to get wrong: key-down acts while key-up
does not, the preset hotkey reads the preset name when pressed rather than
when registered, an unmapped scene does nothing, repeated studio-mode events
collapse, and the scene-prefill button preserves actions already assigned.

Confirmed the suite has teeth by mutation: shrinking the debounce window,
dropping --force, and capturing the preset name at registration time are each
caught.
2026-10-07 09:47:57 -07:00

Insta360 Link 2 integration for OBS and KDE

Hotkey and OBS integration on top of linkctl, so AI tracking and gimbal presets are a keypress rather than a terminal command.

Three pieces, usable independently:

Path What it gives you
bin/linkctl-macro A wrapper that makes linkctl safe to bind to a hotkey: finds the binary in a desktop session's sparse PATH, passes --force, and reports the result as a desktop notification.
kde/install-shortcuts.sh Registers KDE Plasma global shortcuts, so the keys work from anywhere including under Wayland.
obs/obs-linkctl.lua OBS hotkeys, buttons, and scene automation: a scene switch can set tracking or load a preset on its own.

Prerequisites

linkctl installed and working (linkctl status reports your camera), and a saved home preset:

linkctl preset save home     # point the camera where you want "home" first

Install

./kde/install-shortcuts.sh --dry-run    # review, changes nothing
./kde/install-shortcuts.sh

Default bindings, editable in the BINDINGS table at the top of that script:

Key Action
Meta+Alt+T toggle AI tracking
Meta+Alt+1 tracking on
Meta+Alt+0 tracking off
Meta+Alt+H preset load home
Meta+Alt+C recenter gimbal

Check them afterwards with ./kde/install-shortcuts.sh --list, or in System Settings under Keyboard, Shortcuts, searching for "Insta360". Reverse the whole thing with --uninstall.

OBS

Tools, Scripts, +, then pick obs/obs-linkctl.lua.

Set the linkctl binary path if it is not on OBS's PATH, then bind the hotkeys under Settings, Hotkeys (search "Insta360").

Scene automation. Press Insert current scene names to prefill the mapping box, then give the scenes you care about an action:

Talking Head = tracking on
Overhead     = preset load overhead
Slides       = tracking off

The left side is the scene name, the right side is any linkctl arguments. Blank actions and # comments are ignored.

Startup action runs when OBS finishes loading, and defaults to preset load home. This is the setting worth keeping: the Link parks its gimbal facing down when idle, so launching OBS puts it back on its own.

Under Wayland, OBS's own hotkeys only fire while OBS has focus. That is an OBS limitation, and the reason the KDE shortcuts exist; install both and use the KDE ones for anything you need mid-stream.

Configuration

Optional, at ~/.config/linkctl-macro.conf (see linkctl-macro.conf.example):

LINKCTL=/usr/local/bin/linkctl   # if not on PATH
LINKCTL_DEVICE=/dev/video0       # pin the camera if you have more than one
LINKCTL_FORCE=1                  # 0 respects linkctl's idle-camera guard
LINKCTL_NOTIFY=always            # always | error | never

--force is on by default because a deliberate keypress means "do it now", including when nothing currently holds the camera open. That is exactly the case where the gimbal is parked facing down.

Testing without a camera

lua tests/test_obs_linkctl.lua          # pure helpers: quoting, parsing, commands
lua tests/test_obs_lifecycle.lua        # the OBS script against a mock OBS API
bin/linkctl-macro --print tracking on   # show the command without running it
./kde/install-shortcuts.sh --dry-run    # show the KDE changes, apply nothing
shellcheck bin/linkctl-macro kde/install-shortcuts.sh

The lifecycle suite drives the script the way OBS does, so it catches broken wiring (hotkeys not firing, scene actions not matching, the preset name being captured too early) without needing OBS or a camera.

Troubleshooting

Shortcut does nothing. Run the action directly first: bin/linkctl-macro tracking on. A failure notification names the cause. If that works but the key does not, re-run the installer with SHOW_IN_MENU=1; some Plasma builds only resolve launcher-visible application entries.

tracking fails with exit 12. AI tracking is experimental in linkctl and goes through the camera's vendor extension unit. Pan, tilt, zoom and presets use standard UVC and are unaffected.

Permission denied (exit 6). Add yourself to the video group, or install the udev rule from linkctl's contrib/99-insta360-link.rules.

Nothing moves at all. The Link 2 rejects single-axis pan/tilt writes and needs both axes set in one VIDIOC_S_EXT_CTRLS call. linkctl does this correctly; raw v4l2-ctl needs --set-ctrl pan_absolute=0,tilt_absolute=0 as one argument.

Status

The Lua helpers and the shell scripts are tested offline, and the KDE installer is dry-runnable and reversible. None of it has been exercised against a live camera or a running Plasma session by the author of this commit, so treat the first run as the real test and use --dry-run first.

S
Description
Tools for operating an Insta360 Link 2 camera on Linux
Readme GPL-3.0
130 KiB
Languages
Python 23.9%
QML 23%
Shell 21.5%
Lua 18.9%
JavaScript 12.7%