From 7377aee6fa83ed8278774ed2fc0664dc37904128 Mon Sep 17 00:00:00 2001 From: ZGaetano Date: Tue, 14 Apr 2026 10:00:46 -0400 Subject: [PATCH] feat: add multi-destination SRT support and per-port SCTE35 --- backend/app/models.py | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/backend/app/models.py b/backend/app/models.py index 62b1a83..118fb56 100644 --- a/backend/app/models.py +++ b/backend/app/models.py @@ -1,7 +1,7 @@ from enum import Enum from datetime import datetime from pydantic import BaseModel, Field, ConfigDict -from typing import Optional +from typing import Optional, List class CodecType(str, Enum): @@ -12,6 +12,15 @@ class CodecType(str, Enum): H264 = "h264" +class SRTDestination(BaseModel): + """A single SRT output destination""" + model_config = ConfigDict(use_enum_values=False) + + url: str = Field(..., description="SRT destination URL (srt://host:port)") + label: str = Field(default="", description="Human-readable label for this destination") + enabled: bool = Field(default=True, description="Whether this destination is active") + + class RecorderConfig(BaseModel): """Configuration for a recorder port""" model_config = ConfigDict(use_enum_values=False) @@ -30,8 +39,13 @@ class RecorderConfig(BaseModel): srt_enabled: bool = Field( default=False, description="Enable SRT streaming output" ) + # Legacy single destination (kept for backwards compat) srt_destination: Optional[str] = Field( - default=None, description="SRT destination address (host:port)" + default=None, description="SRT destination address (host:port) — use srt_destinations for multi" + ) + # Multi-destination + srt_destinations: List[SRTDestination] = Field( + default_factory=list, description="List of SRT output destinations" ) preview_enabled: bool = Field( default=True, description="Enable live HLS preview" @@ -41,7 +55,7 @@ class RecorderConfig(BaseModel): class PortStatus(BaseModel): """Real-time status of a recorder port""" model_config = ConfigDict(use_enum_values=False) - + port_index: int = Field(..., description="Index of the recorder port") is_recording: bool = Field(..., description="Whether this port is currently recording") frame_count: int = Field(..., description="Total frames recorded") @@ -50,6 +64,9 @@ class PortStatus(BaseModel): uptime_seconds: int = Field(..., description="Recording uptime in seconds") current_file: str = Field(..., description="Current output file path") codec: CodecType = Field(..., description="Codec being used") + srt_destinations: List[str] = Field( + default_factory=list, description="Active SRT destination URLs" + ) class SCTE35Marker(BaseModel): @@ -74,3 +91,9 @@ class SCTE35Marker(BaseModel): webhook_url: Optional[str] = Field( default=None, description="Webhook URL to notify on ad break" ) + port_index: Optional[int] = Field( + default=None, description="Port index this marker was injected on (None = global)" + ) + srt_destination_url: Optional[str] = Field( + default=None, description="Specific SRT destination URL this marker targets (None = all)" + )