controller: switch wire format JSON → key=val URL-encoded (matches filter)
Filter использует sscanf("%s") который stops on whitespace — нужно
URL-encode string values (text="hello world" → text=hello%20world).
Filter inline decode'ит %xx.
Также:
tools/smoke_test_overlays.sh — integration test script (manual run
утром когда GPU свободна; сейчас прод-сервисы заняли всю VRAM)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -25,14 +25,28 @@ log = structlog.get_logger()
|
||||
def _serialize_overlay_to_zmq(overlay: Overlay) -> str:
|
||||
"""Сериализовать overlay в одну строку для FFmpeg process_command.
|
||||
|
||||
Формат: `add_overlay <id> <type> <json-base64-payload>`
|
||||
Filter-side (Phase 4b) парсит JSON и применяет.
|
||||
|
||||
JSON используем потому что overlay имеет вложенные поля (style для graph
|
||||
и т.п.); проще чем positional args.
|
||||
Формат: `<id> <type> <key>=<val> <key>=<val> ...`
|
||||
String values URL-encoded (spaces → %20), filter-side decode'ит inline
|
||||
в parse_overlay_args. Nested values (style и т.п.) skip'аются — Phase 4b
|
||||
их не поддерживает.
|
||||
"""
|
||||
payload = overlay.model_dump_json()
|
||||
return f"{overlay.id} {overlay.type} {payload}"
|
||||
from urllib.parse import quote
|
||||
|
||||
parts = [overlay.id, overlay.type]
|
||||
data = overlay.model_dump()
|
||||
for key, value in data.items():
|
||||
if key in {"id", "type"}:
|
||||
continue
|
||||
if value is None:
|
||||
continue
|
||||
if isinstance(value, (dict, list)):
|
||||
continue # Phase 4b skipped — Phase 5 для nested style
|
||||
if isinstance(value, bool):
|
||||
value = 1 if value else 0
|
||||
if isinstance(value, str):
|
||||
value = quote(value, safe="") # encode spaces + всё кроме alnum
|
||||
parts.append(f"{key}={value}")
|
||||
return " ".join(parts)
|
||||
|
||||
|
||||
class CommandDispatcher:
|
||||
|
||||
Reference in New Issue
Block a user