from enum import Enum from datetime import datetime from pydantic import BaseModel, Field, ConfigDict from typing import Optional, List class CodecType(str, Enum): """Supported video codec types""" PRORES = "prores" DNXHD = "dnxhd" UNCOMPRESSED = "uncompressed" 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) port_index: int = Field(..., description="Index of the recorder port (0-based)") codec: CodecType = Field(..., description="Selected codec for recording") bitrate: int = Field(..., description="Target bitrate in Mbps") quality_profile: str = Field( ..., description="Quality profile name (high, medium, low)" ) recording_path: str = Field( ..., description="Directory path for recording output files" ) 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) — 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" ) 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") fps: float = Field(..., description="Frames per second") bitrate_mbps: float = Field(..., description="Current bitrate in Mbps") 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): """SCTE-35/SCTE-104 advertisement marker""" model_config = ConfigDict(use_enum_values=False) event_id: str = Field( ..., description="Unique identifier for this ad break event" ) duration_seconds: int = Field( ..., description="Duration of the ad break in seconds" ) out_of_network: bool = Field( ..., description="Whether this is an out-of-network ad" ) splice_immediate: bool = Field( ..., description="Whether splice should happen immediately" ) timestamp: datetime = Field( ..., description="Timestamp when marker was created/triggered" ) 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)" )