GUIDE 25 / 28 · NATIVE 2.0.7

Host bridge & local media

Understand JSON messages, request ordering, WebView2 origin checks and authenticated local video playback.

JSON lines between host and service#

The Windows host and Node backend communicate through redirected process pipes. Each message is one JSON line. Requests carry an ID and channel; responses carry the matching ID with a result or error. Events are forwarded to the renderer after its bridge is ready.

The host serializes writes with SemaphoreSlim so concurrent UI requests, global shortcuts and backend replies cannot interleave on the stream. Host-side pending requests are removed after completion or failure and have a five-minute wait limit.

Illustrative internal request
{
  "id": "host_123",
  "channel": "capture:status",
  "args": []
}

This describes an internal implementation boundary, not a public network or plugin API. Plugin authors should use context methods rather than constructing transport messages.

WebView2 boundary#

The renderer is mapped from packaged local files to https://app.hydroclips.local. The host checks message origins against that application origin. External HTTP and HTTPS navigation opens the system browser; the app does not navigate its privileged renderer to arbitrary websites.

General WebView2 permission requests are denied, and normal builds disable developer tools, context menus and the browser status bar. Native dialogs and window actions are routed through defined host channels.

Local clip streaming#

The Node service listens on an ephemeral 127.0.0.1 port for media playback. A per-run random token protects access, and only registered clip and thumbnail paths are served. Valid range requests allow the player to seek through larger files; invalid ranges return an error.

The service uses no-store responses and allows the app's virtual origin. It does not provide recording controls, an arbitrary file browser or JavaScript evaluation over HTTP. Treat local media URLs as temporary session data rather than shareable download links.

Shortcuts and shutdown#

The host registers global key handling with explicit modifiers and debounces held keys. Alt+B toggles the window, while recording shortcuts call defined backend actions. A hidden interface keeps capture running.

On normal shutdown the service saves an active manual recording before stopping capture. The host waits for service exit and has a fallback process-tree stop if orderly shutdown does not finish. A forced Windows termination can still leave unfinished media, so use the tray quit action when possible.

Changing the bridge#

Add a narrowly defined channel to the backend switch and the matching typed renderer API. Validate arguments at the receiving boundary, return a serializable result and keep logs on stderr so stdout remains valid protocol data. Preserve origin validation and ordered writes.

Use the transport regression test in native validation when changing concurrency or request handling. Interface tab HTML is covered separately in plugin UI.

Implementation reference: native/Program.cs; src/native/backend.ts; src/native/runtime.ts · native 2.0.7.

Typed clip editing channels#

  • clips:inspect(id) returns actual duration and audioTracks with index, role and label.
  • clips:audio-url(id, index) returns an authenticated temporary URL for one valid audio stream. HTTP /audio serves registered clips only, with range support.
  • clips:edit(id, options) accepts finite Start/End seconds and optional systemGain, microphoneGain and mixedGain between 0 and 2. It creates a new library clip with sourceClipId and edit metadata.

Selections must fit the source and be at least 0.1 seconds. The service coalesces identical export requests and rejects a different concurrent edit. It pins the source, validates output before library insertion and leaves the original file unchanged. Normal shutdown waits for in-flight edits and audio preview preparation before stopping capture.