schema improvements

This commit is contained in:
Sergey Krashevich
2025-12-14 05:20:59 +03:00
parent ce9138b354
commit d041c89c5c
3 changed files with 774 additions and 74 deletions
+360 -22
View File
@@ -24,7 +24,10 @@
"debug", "debug",
"info", "info",
"warn", "warn",
"error" "error",
"fatal",
"panic",
"disabled"
] ]
} }
}, },
@@ -48,6 +51,11 @@
"password": { "password": {
"type": "string" "type": "string"
}, },
"local_auth": {
"description": "Allow auth from local network without credentials (uses existing Auth header)",
"type": "boolean",
"default": false
},
"base_path": { "base_path": {
"type": "string", "type": "string",
"examples": [ "examples": [
@@ -61,8 +69,18 @@
] ]
}, },
"origin": { "origin": {
"description": "Set to \"*\" to enable CORS and allow any Origin",
"type": "string", "type": "string",
"const": "*" "anyOf": [
{
"type": "string",
"const": "*"
},
{
"type": "string",
"const": ""
}
]
}, },
"tls_listen": { "tls_listen": {
"$ref": "#/definitions/listen" "$ref": "#/definitions/listen"
@@ -86,6 +104,116 @@
"examples": [ "examples": [
"/tmp/go2rtc.sock" "/tmp/go2rtc.sock"
] ]
},
"allow_paths": {
"description": "Allow only these HTTP paths (full paths, including base_path); when set, all other endpoints are not registered",
"type": "array",
"items": {
"type": "string"
},
"examples": [
[
"/api/ws",
"/api/config",
"/api/streams"
]
]
}
}
},
"app": {
"type": "object",
"properties": {
"modules": {
"description": "Enable only these modules (empty / omitted means all)",
"type": "array",
"items": {
"type": "string",
"enum": [
"api",
"ws",
"http",
"rtsp",
"webrtc",
"mp4",
"hls",
"mjpeg",
"hass",
"homekit",
"onvif",
"rtmp",
"webtorrent",
"wyoming",
"echo",
"exec",
"expr",
"ffmpeg",
"alsa",
"v4l2",
"bubble",
"doorbird",
"dvrip",
"eseecloud",
"flussonic",
"gopro",
"isapi",
"ivideon",
"mpegts",
"nest",
"ring",
"roborock",
"tapo",
"tuya",
"yandex",
"debug",
"ngrok",
"pinggy",
"srtp"
]
}
}
}
},
"env": {
"description": "Config variables that can be referenced as ${NAME} / ${NAME:default}",
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"echo": {
"type": "object",
"properties": {
"allow_paths": {
"description": "Allow only these binaries for echo: URLs (exact cmd name/path)",
"type": "array",
"items": {
"type": "string"
},
"examples": [
[
"ffmpeg",
"/usr/bin/ffmpeg"
]
]
}
}
},
"exec": {
"type": "object",
"properties": {
"allow_paths": {
"description": "Allow only these binaries for exec: URLs (exact cmd name/path)",
"type": "array",
"items": {
"type": "string"
},
"examples": [
[
"ffmpeg",
"/usr/bin/ffmpeg"
]
]
} }
} }
}, },
@@ -118,25 +246,56 @@
"type": "object", "type": "object",
"additionalProperties": { "additionalProperties": {
"type": "object", "type": "object",
"properties": { "properties": {
"pin": { "pin": {
"type": "string", "description": "HomeKit pairing PIN (will be normalized to XXX-XX-XXX); insecure PINs are rejected",
"default": "19550224", "type": "string",
"pattern": "^[0-9]{8}$" "default": "19550224",
}, "anyOf": [
"name": { {
"type": "string" "type": "string",
}, "pattern": "^[0-9]{8}$"
},
{
"type": "string",
"pattern": "^[0-9]{3}-[0-9]{2}-[0-9]{3}$"
}
]
},
"name": {
"type": "string"
},
"device_id": { "device_id": {
"type": "string" "type": "string"
}, },
"device_private": { "device_private": {
"type": "string"
},
"category_id": {
"description": "Accessory category: \"bridge\", \"doorbell\" or numeric ID (default: camera)",
"type": "string",
"anyOf": [
{
"type": "string",
"enum": [
"bridge",
"doorbell"
]
},
{
"type": "string",
"pattern": "^[0-9]+$"
},
{
"type": "string",
"const": ""
}
]
},
"pairings": {
"type": "array",
"items": {
"type": "string" "type": "string"
},
"pairings": {
"type": "array",
"items": {
"type": "string"
} }
} }
} }
@@ -146,9 +305,11 @@
"type": "object", "type": "object",
"properties": { "properties": {
"format": { "format": {
"description": "Log format: color/json/text or empty for autodetect",
"type": "string", "type": "string",
"default": "color", "default": "color",
"enum": [ "enum": [
"",
"color", "color",
"json", "json",
"text" "text"
@@ -160,12 +321,26 @@
"$ref": "#/definitions/log_level" "$ref": "#/definitions/log_level"
}, },
"output": { "output": {
"description": "Log output: stdout/stderr/file[:path] or empty (memory only)",
"type": "string", "type": "string",
"default": "stdout", "default": "stdout",
"enum": [ "anyOf": [
"", {
"stdout", "type": "string",
"stderr" "enum": [
"",
"stdout",
"stderr"
]
},
{
"type": "string",
"pattern": "^file(:.+)?$",
"examples": [
"file",
"file:go2rtc.log"
]
}
] ]
}, },
"time": { "time": {
@@ -191,6 +366,24 @@
"api": { "api": {
"$ref": "#/definitions/log_level" "$ref": "#/definitions/log_level"
}, },
"alsa": {
"$ref": "#/definitions/log_level"
},
"bubble": {
"$ref": "#/definitions/log_level"
},
"debug": {
"$ref": "#/definitions/log_level"
},
"doorbird": {
"$ref": "#/definitions/log_level"
},
"dvrip": {
"$ref": "#/definitions/log_level"
},
"eseecloud": {
"$ref": "#/definitions/log_level"
},
"echo": { "echo": {
"$ref": "#/definitions/log_level" "$ref": "#/definitions/log_level"
}, },
@@ -206,6 +399,12 @@
"default": "error", "default": "error",
"$ref": "#/definitions/log_level" "$ref": "#/definitions/log_level"
}, },
"flussonic": {
"$ref": "#/definitions/log_level"
},
"gopro": {
"$ref": "#/definitions/log_level"
},
"hass": { "hass": {
"$ref": "#/definitions/log_level" "$ref": "#/definitions/log_level"
}, },
@@ -215,30 +414,78 @@
"homekit": { "homekit": {
"$ref": "#/definitions/log_level" "$ref": "#/definitions/log_level"
}, },
"http": {
"$ref": "#/definitions/log_level"
},
"isapi": {
"$ref": "#/definitions/log_level"
},
"ivideon": {
"$ref": "#/definitions/log_level"
},
"mjpeg": {
"$ref": "#/definitions/log_level"
},
"mpegts": {
"$ref": "#/definitions/log_level"
},
"mp4": { "mp4": {
"$ref": "#/definitions/log_level" "$ref": "#/definitions/log_level"
}, },
"nest": {
"$ref": "#/definitions/log_level"
},
"ngrok": { "ngrok": {
"$ref": "#/definitions/log_level" "$ref": "#/definitions/log_level"
}, },
"onvif": { "onvif": {
"$ref": "#/definitions/log_level" "$ref": "#/definitions/log_level"
}, },
"pinggy": {
"$ref": "#/definitions/log_level"
},
"ring": {
"$ref": "#/definitions/log_level"
},
"roborock": {
"$ref": "#/definitions/log_level"
},
"rtmp": { "rtmp": {
"$ref": "#/definitions/log_level" "$ref": "#/definitions/log_level"
}, },
"rtsp": { "rtsp": {
"$ref": "#/definitions/log_level" "$ref": "#/definitions/log_level"
}, },
"srtp": {
"$ref": "#/definitions/log_level"
},
"streams": { "streams": {
"$ref": "#/definitions/log_level" "$ref": "#/definitions/log_level"
}, },
"tapo": {
"$ref": "#/definitions/log_level"
},
"tuya": {
"$ref": "#/definitions/log_level"
},
"v4l2": {
"$ref": "#/definitions/log_level"
},
"webrtc": { "webrtc": {
"$ref": "#/definitions/log_level" "$ref": "#/definitions/log_level"
}, },
"webtorrent": { "webtorrent": {
"$ref": "#/definitions/log_level" "$ref": "#/definitions/log_level"
},
"wyoming": {
"$ref": "#/definitions/log_level"
},
"yandex": {
"$ref": "#/definitions/log_level"
} }
},
"additionalProperties": {
"$ref": "#/definitions/log_level"
} }
}, },
"ngrok": { "ngrok": {
@@ -253,6 +500,30 @@
} }
} }
}, },
"pinggy": {
"type": "object",
"properties": {
"tunnel": {
"description": "Expose local address via Pinggy (scheme: http/tcp/tls/tlstcp, host:port is your local address)",
"type": "string",
"examples": [
"http://127.0.0.1:1984",
"tcp://127.0.0.1:8554"
]
}
}
},
"preload": {
"description": "Preload streams on startup (map stream name => probe query, default \"video&audio\")",
"type": "object",
"additionalProperties": {
"type": "string",
"examples": [
"video&audio",
"video"
]
}
},
"publish": { "publish": {
"type": "object", "type": "object",
"additionalProperties": { "additionalProperties": {
@@ -352,6 +623,29 @@
"description": "Source", "description": "Source",
"type": "string" "type": "string"
} }
},
{
"type": "object",
"properties": {
"url": {
"description": "Source URL or list of URLs",
"anyOf": [
{
"type": "string",
"examples": [
"rtsp://username:password@192.168.1.123/stream1",
"ffmpeg:media.mp4#video=h264#audio=copy"
]
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
}
}
} }
] ]
} }
@@ -472,7 +766,8 @@
"type": "object", "type": "object",
"properties": { "properties": {
"pwd": { "pwd": {
"type": "string" "type": "string",
"minLength": 4
}, },
"src": { "src": {
"type": "string" "type": "string"
@@ -481,6 +776,49 @@
} }
} }
} }
},
"wyoming": {
"type": "object",
"additionalProperties": {
"type": "object",
"properties": {
"listen": {
"description": "Listen address for Wyoming server",
"$ref": "#/definitions/listen"
},
"name": {
"description": "Optional satellite name (default: stream name)",
"type": "string"
},
"mode": {
"description": "Optional mode: mic / snd / default",
"type": "string",
"enum": [
"",
"mic",
"snd"
]
},
"event": {
"description": "Event handlers (map event type => expr script)",
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"wake_uri": {
"description": "Optional WAKE service URI (ex. tcp://host:port?name=...)",
"type": "string",
"examples": [
"tcp://192.168.1.23:10400"
]
},
"vad_threshold": {
"description": "Optional VAD threshold (0.1..3.5 typical)",
"type": "number"
}
}
}
} }
} }
} }
+15
View File
@@ -356,6 +356,21 @@
if (!contextSchema) return {suggestions: []}; if (!contextSchema) return {suggestions: []};
// Scalar array item (e.g. "- tcp4") - suggest values (enum/examples/default)
if (listItem && colonIndex === -1 && !isValueContext) {
const props = getObjectProperties(contextSchema);
if (!props || Object.keys(props).length === 0) {
const values = getValueSuggestions(contextSchema);
const suggestions = values.map((v) => ({
label: toYamlScalar(v),
kind: monaco.languages.CompletionItemKind.Value,
insertText: toYamlScalar(v),
range,
}));
return {suggestions};
}
}
if (!isValueContext) { if (!isValueContext) {
const props = getObjectProperties(contextSchema); const props = getObjectProperties(contextSchema);
const suggestions = Object.keys(props).map((key) => { const suggestions = Object.keys(props).map((key) => {
+399 -52
View File
@@ -24,7 +24,10 @@
"debug", "debug",
"info", "info",
"warn", "warn",
"error" "error",
"fatal",
"panic",
"disabled"
] ]
} }
}, },
@@ -49,21 +52,35 @@
"type": "string" "type": "string"
}, },
"local_auth": { "local_auth": {
"description": "Will use Auth header from local network", "description": "Allow auth from local network without credentials (uses existing Auth header)",
"type": "boolean", "type": "boolean",
"default": false "default": false
}, },
"base_path": { "base_path": {
"type": "string", "type": "string",
"default": "" "examples": [
"/go2rtc"
]
}, },
"static_dir": { "static_dir": {
"type": "string", "type": "string",
"default": "" "examples": [
"/var/www"
]
}, },
"origin": { "origin": {
"description": "Set to \"*\" to enable CORS and allow any Origin",
"type": "string", "type": "string",
"default": "*" "anyOf": [
{
"type": "string",
"const": "*"
},
{
"type": "string",
"const": ""
}
]
}, },
"tls_listen": { "tls_listen": {
"$ref": "#/definitions/listen" "$ref": "#/definitions/listen"
@@ -71,13 +88,15 @@
"tls_cert": { "tls_cert": {
"type": "string", "type": "string",
"examples": [ "examples": [
"/etc/ssl/certs/my_certificate.pem" "-----BEGIN CERTIFICATE-----",
"/ssl/fullchain.pem"
] ]
}, },
"tls_key": { "tls_key": {
"type": "string", "type": "string",
"examples": [ "examples": [
"/etc/ssl/private/my_certificate_key.pem" "-----BEGIN PRIVATE KEY-----",
"/ssl/privkey.pem"
] ]
}, },
"unix_listen": { "unix_listen": {
@@ -85,6 +104,116 @@
"examples": [ "examples": [
"/tmp/go2rtc.sock" "/tmp/go2rtc.sock"
] ]
},
"allow_paths": {
"description": "Allow only these HTTP paths (full paths, including base_path); when set, all other endpoints are not registered",
"type": "array",
"items": {
"type": "string"
},
"examples": [
[
"/api/ws",
"/api/config",
"/api/streams"
]
]
}
}
},
"app": {
"type": "object",
"properties": {
"modules": {
"description": "Enable only these modules (empty / omitted means all)",
"type": "array",
"items": {
"type": "string",
"enum": [
"api",
"ws",
"http",
"rtsp",
"webrtc",
"mp4",
"hls",
"mjpeg",
"hass",
"homekit",
"onvif",
"rtmp",
"webtorrent",
"wyoming",
"echo",
"exec",
"expr",
"ffmpeg",
"alsa",
"v4l2",
"bubble",
"doorbird",
"dvrip",
"eseecloud",
"flussonic",
"gopro",
"isapi",
"ivideon",
"mpegts",
"nest",
"ring",
"roborock",
"tapo",
"tuya",
"yandex",
"debug",
"ngrok",
"pinggy",
"srtp"
]
}
}
}
},
"env": {
"description": "Config variables that can be referenced as ${NAME} / ${NAME:default}",
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"echo": {
"type": "object",
"properties": {
"allow_paths": {
"description": "Allow only these binaries for echo: URLs (exact cmd name/path)",
"type": "array",
"items": {
"type": "string"
},
"examples": [
[
"ffmpeg",
"/usr/bin/ffmpeg"
]
]
}
}
},
"exec": {
"type": "object",
"properties": {
"allow_paths": {
"description": "Allow only these binaries for exec: URLs (exact cmd name/path)",
"type": "array",
"items": {
"type": "string"
},
"examples": [
[
"ffmpeg",
"/usr/bin/ffmpeg"
]
]
} }
} }
}, },
@@ -105,49 +234,69 @@
"type": "object", "type": "object",
"properties": { "properties": {
"config": { "config": {
"description": "Home Assistant config directory path",
"type": "string", "type": "string",
"examples": [ "examples": [
"/config/go2rtc.yaml" "/config"
] ]
},
"api": {
"type": "object",
"properties": {
"listen": {
"default": ":8124",
"$ref": "#/definitions/listen"
}
}
} }
} }
}, },
"homekit": { "homekit": {
"type": "object", "type": "object",
"additionalProperties": {
"type": "object",
"properties": { "properties": {
"pin": { "pin": {
"description": "HomeKit pairing PIN (will be normalized to XXX-XX-XXX); insecure PINs are rejected",
"type": "string", "type": "string",
"default": "123-45-678" "default": "19550224",
"anyOf": [
{
"type": "string",
"pattern": "^[0-9]{8}$"
},
{
"type": "string",
"pattern": "^[0-9]{3}-[0-9]{2}-[0-9]{3}$"
}
]
}, },
"name": { "name": {
"type": "string", "type": "string"
"default": "go2rtc"
},
"device_id": {
"type": "string",
"default": ""
}, },
"device_id": {
"type": "string"
},
"device_private": { "device_private": {
"type": "string", "type": "string"
"default": ""
}, },
"category_id": { "category_id": {
"type": "integer", "description": "Accessory category: \"bridge\", \"doorbell\" or numeric ID (default: camera)",
"default": 2 "type": "string",
"anyOf": [
{
"type": "string",
"enum": [
"bridge",
"doorbell"
]
},
{
"type": "string",
"pattern": "^[0-9]+$"
},
{
"type": "string",
"const": ""
}
]
}, },
"pairings": { "pairings": {
"type": "array", "type": "array",
"items": { "items": {
"type": "string" "type": "string"
}
} }
} }
} }
@@ -156,9 +305,11 @@
"type": "object", "type": "object",
"properties": { "properties": {
"format": { "format": {
"description": "Log format: color/json/text or empty for autodetect",
"type": "string", "type": "string",
"default": "color", "default": "color",
"enum": [ "enum": [
"",
"color", "color",
"json", "json",
"text" "text"
@@ -170,12 +321,26 @@
"$ref": "#/definitions/log_level" "$ref": "#/definitions/log_level"
}, },
"output": { "output": {
"description": "Log output: stdout/stderr/file[:path] or empty (memory only)",
"type": "string", "type": "string",
"default": "stdout", "default": "stdout",
"enum": [ "anyOf": [
"", {
"stdout", "type": "string",
"stderr" "enum": [
"",
"stdout",
"stderr"
]
},
{
"type": "string",
"pattern": "^file(:.+)?$",
"examples": [
"file",
"file:go2rtc.log"
]
}
] ]
}, },
"time": { "time": {
@@ -201,6 +366,24 @@
"api": { "api": {
"$ref": "#/definitions/log_level" "$ref": "#/definitions/log_level"
}, },
"alsa": {
"$ref": "#/definitions/log_level"
},
"bubble": {
"$ref": "#/definitions/log_level"
},
"debug": {
"$ref": "#/definitions/log_level"
},
"doorbird": {
"$ref": "#/definitions/log_level"
},
"dvrip": {
"$ref": "#/definitions/log_level"
},
"eseecloud": {
"$ref": "#/definitions/log_level"
},
"echo": { "echo": {
"$ref": "#/definitions/log_level" "$ref": "#/definitions/log_level"
}, },
@@ -216,6 +399,12 @@
"default": "error", "default": "error",
"$ref": "#/definitions/log_level" "$ref": "#/definitions/log_level"
}, },
"flussonic": {
"$ref": "#/definitions/log_level"
},
"gopro": {
"$ref": "#/definitions/log_level"
},
"hass": { "hass": {
"$ref": "#/definitions/log_level" "$ref": "#/definitions/log_level"
}, },
@@ -225,41 +414,116 @@
"homekit": { "homekit": {
"$ref": "#/definitions/log_level" "$ref": "#/definitions/log_level"
}, },
"http": {
"$ref": "#/definitions/log_level"
},
"isapi": {
"$ref": "#/definitions/log_level"
},
"ivideon": {
"$ref": "#/definitions/log_level"
},
"mjpeg": {
"$ref": "#/definitions/log_level"
},
"mpegts": {
"$ref": "#/definitions/log_level"
},
"mp4": { "mp4": {
"$ref": "#/definitions/log_level" "$ref": "#/definitions/log_level"
}, },
"nest": {
"$ref": "#/definitions/log_level"
},
"ngrok": { "ngrok": {
"$ref": "#/definitions/log_level" "$ref": "#/definitions/log_level"
}, },
"onvif": { "onvif": {
"$ref": "#/definitions/log_level" "$ref": "#/definitions/log_level"
}, },
"pinggy": {
"$ref": "#/definitions/log_level"
},
"ring": {
"$ref": "#/definitions/log_level"
},
"roborock": {
"$ref": "#/definitions/log_level"
},
"rtmp": { "rtmp": {
"$ref": "#/definitions/log_level" "$ref": "#/definitions/log_level"
}, },
"rtsp": { "rtsp": {
"$ref": "#/definitions/log_level" "$ref": "#/definitions/log_level"
}, },
"srtp": {
"$ref": "#/definitions/log_level"
},
"streams": { "streams": {
"$ref": "#/definitions/log_level" "$ref": "#/definitions/log_level"
}, },
"tapo": {
"$ref": "#/definitions/log_level"
},
"tuya": {
"$ref": "#/definitions/log_level"
},
"v4l2": {
"$ref": "#/definitions/log_level"
},
"webrtc": { "webrtc": {
"$ref": "#/definitions/log_level" "$ref": "#/definitions/log_level"
}, },
"webtorrent": { "webtorrent": {
"$ref": "#/definitions/log_level" "$ref": "#/definitions/log_level"
},
"wyoming": {
"$ref": "#/definitions/log_level"
},
"yandex": {
"$ref": "#/definitions/log_level"
} }
},
"additionalProperties": {
"$ref": "#/definitions/log_level"
} }
}, },
"ngrok": { "ngrok": {
"type": "object", "type": "object",
"properties": { "properties": {
"command": { "command": {
"description": "ngrok start --all --config ngrok.yaml", "type": "string",
"type": "string" "examples": [
"ngrok tcp 8555 --authtoken xxx",
"ngrok start --all --config ngrok.yaml"
]
} }
} }
}, },
"pinggy": {
"type": "object",
"properties": {
"tunnel": {
"description": "Expose local address via Pinggy (scheme: http/tcp/tls/tlstcp, host:port is your local address)",
"type": "string",
"examples": [
"http://127.0.0.1:1984",
"tcp://127.0.0.1:8554"
]
}
}
},
"preload": {
"description": "Preload streams on startup (map stream name => probe query, default \"video&audio\")",
"type": "object",
"additionalProperties": {
"type": "string",
"examples": [
"video&audio",
"video"
]
}
},
"publish": { "publish": {
"type": "object", "type": "object",
"additionalProperties": { "additionalProperties": {
@@ -299,22 +563,25 @@
"$ref": "#/definitions/listen" "$ref": "#/definitions/listen"
}, },
"username": { "username": {
"type": "string" "type": "string",
"examples": [
"admin"
]
}, },
"password": { "password": {
"type": "string" "type": "string"
}, },
"default_query": { "default_query": {
"type": "string", "type": "string",
"default": "" "default": "video&audio"
}, },
"pkt_size": { "pkt_size": {
"type": "integer", "type": "integer"
"default": 0
} }
} }
}, },
"srtp": { "srtp": {
"description": "SRTP server for HomeKit",
"type": "object", "type": "object",
"properties": { "properties": {
"listen": { "listen": {
@@ -356,6 +623,29 @@
"description": "Source", "description": "Source",
"type": "string" "type": "string"
} }
},
{
"type": "object",
"properties": {
"url": {
"description": "Source URL or list of URLs",
"anyOf": [
{
"type": "string",
"examples": [
"rtsp://username:password@192.168.1.123/stream1",
"ffmpeg:media.mp4#video=h264#audio=copy"
]
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
}
}
} }
] ]
} }
@@ -364,18 +654,29 @@
"type": "object", "type": "object",
"properties": { "properties": {
"listen": { "listen": {
"default": ":8555", "default": ":8555/tcp",
"$ref": "#/definitions/listen" "type": "string",
"anyOf": [
{
"type": "string",
"pattern": ":[0-9]{1,5}(/tcp|/udp)?$"
},
{
"type": "string",
"const": ""
}
]
}, },
"candidates": { "candidates": {
"type": "array", "type": "array",
"items": { "items": {
"type": "string", "$ref": "#/definitions/listen/anyOf/0"
"examples": [ },
"192.168.1.123", "examples": [
"stun:stun.l.google.com:19302" "216.58.210.174:8555",
] "stun:8555",
} "home.duckdns.org:8555"
]
}, },
"ice_servers": { "ice_servers": {
"type": "array", "type": "array",
@@ -461,14 +762,60 @@
} }
}, },
"shares": { "shares": {
"type": "object", "additionalProperties": {
"properties": { "type": "object",
"pwd": { "properties": {
"type": "string" "pwd": {
}, "type": "string",
"src": { "minLength": 4
},
"src": {
"type": "string"
}
}
}
}
}
},
"wyoming": {
"type": "object",
"additionalProperties": {
"type": "object",
"properties": {
"listen": {
"description": "Listen address for Wyoming server",
"$ref": "#/definitions/listen"
},
"name": {
"description": "Optional satellite name (default: stream name)",
"type": "string"
},
"mode": {
"description": "Optional mode: mic / snd / default",
"type": "string",
"enum": [
"",
"mic",
"snd"
]
},
"event": {
"description": "Event handlers (map event type => expr script)",
"type": "object",
"additionalProperties": {
"type": "string" "type": "string"
} }
},
"wake_uri": {
"description": "Optional WAKE service URI (ex. tcp://host:port?name=...)",
"type": "string",
"examples": [
"tcp://192.168.1.23:10400"
]
},
"vad_threshold": {
"description": "Optional VAD threshold (0.1..3.5 typical)",
"type": "number"
} }
} }
} }