1 Overlay-Plugins-entwickeln
frank edited this page 2026-07-13 14:40:03 +02:00

Overlay-Plugins entwickeln

Manifest

{
  "id": "my-extension",
  "name": "My Extension",
  "version": "1.0.0",
  "entry": "overlay/main.js",
  "permissions": ["events:read"],
  "events": ["*"],
  "contributes": {
    "overlays": [{
      "id": "chat",
      "name": "Chat",
      "entry": "overlay/chat.js",
      "defaultConfig": { "fontSize": 20 },
      "configSchema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "type": "object",
        "properties": {
          "fontSize": { "type": "integer", "minimum": 8, "maximum": 96 }
        }
      }
    }],
    "modules": [{
      "id": "clock",
      "name": "Uhr",
      "entry": "modules/clock.js",
      "defaultConfig": { "format": "HH:mm" },
      "configSchema": {
        "type": "object",
        "properties": { "format": { "type": "string" } },
        "required": ["format"]
      }
    }]
  }
}

IDs dürfen nur ASCII-Buchstaben, Ziffern, - und _ enthalten. Entry-Pfade dürfen kein .. enthalten. Doppelte Contribution-IDs, ungültige Schemas oder nicht passende Defaults verhindern die Installation. Reine Modul-Pakete dürfen das Top-Level-entry leer lassen.

Overlay-Entry

export async function mount({ root, config, events, assetUrl, meta }) {
  root.textContent = "Bereit";
  const off = events.on("*", (event, delivery) => {
    root.textContent = event.type;
    delivery.ack();
  });

  return {
    updateConfig(next) { config = next; },
    dispose() { off(); root.replaceChildren(); }
  };
}

Modul-Entry

Module verwenden denselben Lifecycle. root ist ihr eigener transparenter Layer; assetUrl() zeigt auf das Asset-Verzeichnis des Modulpakets.

export function mount({ root, config, events }) {
  const node = document.createElement("div");
  root.append(node);
  const off = events.on("obs.scene.program_changed", (event, delivery) => {
    node.textContent = event.payload.sceneName;
    delivery.ack();
  });
  return {
    updateConfig(next) { config = next; },
    dispose() { off(); node.remove(); }
  };
}

Hinweise

  • Listener müssen delivery.ack() aufrufen oder bewusst den Timeout abwarten.
  • Für kontrollierte Parallelität zuerst den visuellen Effekt starten und unmittelbar bestätigen.
  • delivery.signal verwenden, um lange Animationen oder Ressourcen zur Deadline abzubrechen.
  • Unsubscribe im dispose() verhindert verwaiste Registrierungen.
  • Vollständige Deklarationen: overlays/runtime/streamertool.d.ts im Repository.
  • Die Admin-UI erzeugt Standardfelder aus dem JSON Schema und bietet zusätzlich einen validierten JSON-Editor.