feat: add per-port SCTE35 inject endpoint

This commit is contained in:
Zac Gaetano 2026-04-14 10:01:22 -04:00
parent 7377aee6fa
commit 5f2f61edfe

View file

@ -23,6 +23,7 @@ class SCTE35InjectionRequest(BaseModel):
webhook_url: Optional[str] = Field(None, description="Optional webhook URL") webhook_url: Optional[str] = Field(None, description="Optional webhook URL")
out_of_network: bool = Field(True, description="Out of network indicator") out_of_network: bool = Field(True, description="Out of network indicator")
splice_immediate: bool = Field(False, description="Splice immediate flag") splice_immediate: bool = Field(False, description="Splice immediate flag")
srt_destination_url: Optional[str] = Field(None, description="Target specific SRT destination (None = all)")
router = APIRouter(prefix="/api") router = APIRouter(prefix="/api")
@ -206,15 +207,10 @@ async def inject_scte35_marker(
manager: SCTE35Manager = Depends(get_scte35_manager), manager: SCTE35Manager = Depends(get_scte35_manager),
) -> SCTE35Marker: ) -> SCTE35Marker:
""" """
Inject a SCTE35 ad break marker. Inject a SCTE35 ad break marker globally (all ports).
Args: Args:
request: SCTE35InjectionRequest with: request: SCTE35InjectionRequest
- event_id: int (unique event identifier)
- duration_seconds: float (duration in seconds)
- webhook_url: str | None (optional callback URL)
- out_of_network: bool (whether out-of-network ad)
- splice_immediate: bool (whether splice immediately)
Returns: Returns:
SCTE35Marker with timestamp and metadata SCTE35Marker with timestamp and metadata
@ -229,9 +225,11 @@ async def inject_scte35_marker(
webhook_url=request.webhook_url, webhook_url=request.webhook_url,
out_of_network=request.out_of_network, out_of_network=request.out_of_network,
splice_immediate=request.splice_immediate, splice_immediate=request.splice_immediate,
port_index=None,
srt_destination_url=request.srt_destination_url,
) )
logger.info(f"Injected SCTE35 marker with event_id {request.event_id}") logger.info(f"Injected global SCTE35 marker event_id={request.event_id}")
return marker return marker
except ValueError as e: except ValueError as e:
@ -242,6 +240,44 @@ async def inject_scte35_marker(
raise HTTPException(status_code=500, detail="Internal server error") raise HTTPException(status_code=500, detail="Internal server error")
@router.post("/ports/{port_index}/scte35/inject", response_model=SCTE35Marker)
async def inject_scte35_marker_for_port(
port_index: int,
request: SCTE35InjectionRequest,
manager: SCTE35Manager = Depends(get_scte35_manager),
) -> SCTE35Marker:
"""
Inject a SCTE35 ad break marker on a specific port's SRT output(s).
Args:
port_index: 0-based port index
request: SCTE35InjectionRequest
Returns:
SCTE35Marker with timestamp, port_index, and metadata
"""
try:
marker = await manager.inject_marker(
event_id=request.event_id,
duration_seconds=request.duration_seconds,
webhook_url=request.webhook_url,
out_of_network=request.out_of_network,
splice_immediate=request.splice_immediate,
port_index=port_index,
srt_destination_url=request.srt_destination_url,
)
logger.info(f"Injected SCTE35 marker event_id={request.event_id} on port {port_index}")
return marker
except ValueError as e:
logger.warning(f"Invalid SCTE35 parameters: {e}")
raise HTTPException(status_code=400, detail=str(e))
except Exception as e:
logger.error(f"Error injecting SCTE35 marker on port {port_index}: {e}")
raise HTTPException(status_code=500, detail="Internal server error")
@router.get("/scte35/history", response_model=list[SCTE35Marker]) @router.get("/scte35/history", response_model=list[SCTE35Marker])
async def get_scte35_history( async def get_scte35_history(
manager: SCTE35Manager = Depends(get_scte35_manager), manager: SCTE35Manager = Depends(get_scte35_manager),
@ -257,3 +293,18 @@ async def get_scte35_history(
except Exception as e: except Exception as e:
logger.error(f"Error retrieving SCTE35 history: {e}") logger.error(f"Error retrieving SCTE35 history: {e}")
raise HTTPException(status_code=500, detail="Internal server error") raise HTTPException(status_code=500, detail="Internal server error")
@router.get("/ports/{port_index}/scte35/history", response_model=list[SCTE35Marker])
async def get_scte35_history_for_port(
port_index: int,
manager: SCTE35Manager = Depends(get_scte35_manager),
) -> list[SCTE35Marker]:
"""
Get SCTE35 marker history for a specific port.
"""
try:
return [m for m in manager.get_marker_history() if m.port_index == port_index]
except Exception as e:
logger.error(f"Error retrieving SCTE35 history for port {port_index}: {e}")
raise HTTPException(status_code=500, detail="Internal server error")