fix: inject hls_manager into routes module so preview endpoints work
This commit is contained in:
parent
b936647abb
commit
7e51da50c8
1 changed files with 16 additions and 28 deletions
|
|
@ -14,13 +14,12 @@ from .recorders.recorder import RecorderManager
|
||||||
from .recorders.scte35 import SCTE35Manager
|
from .recorders.scte35 import SCTE35Manager
|
||||||
from .utils.hls import HLSPreviewManager
|
from .utils.hls import HLSPreviewManager
|
||||||
from .api.routes import router
|
from .api.routes import router
|
||||||
from .api import routes as routes_module # to set module-level globals
|
from .api import routes as routes_module
|
||||||
from .api.websocket import ConnectionManager
|
from .api.websocket import ConnectionManager
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
settings = Settings()
|
settings = Settings()
|
||||||
|
|
||||||
# Global manager instances
|
|
||||||
recorder_manager: RecorderManager | None = None
|
recorder_manager: RecorderManager | None = None
|
||||||
scte35_manager: SCTE35Manager | None = None
|
scte35_manager: SCTE35Manager | None = None
|
||||||
hls_manager: HLSPreviewManager | None = None
|
hls_manager: HLSPreviewManager | None = None
|
||||||
|
|
@ -29,48 +28,43 @@ connection_manager = ConnectionManager()
|
||||||
|
|
||||||
@asynccontextmanager
|
@asynccontextmanager
|
||||||
async def lifespan(app: FastAPI):
|
async def lifespan(app: FastAPI):
|
||||||
"""Initialize and cleanup application resources."""
|
|
||||||
global recorder_manager, scte35_manager, hls_manager
|
global recorder_manager, scte35_manager, hls_manager
|
||||||
|
|
||||||
# Startup
|
|
||||||
logger.info("Starting Deltacast SDI Recorder...")
|
logger.info("Starting Deltacast SDI Recorder...")
|
||||||
|
|
||||||
recorder_manager = RecorderManager(settings)
|
recorder_manager = RecorderManager(settings)
|
||||||
recorder_manager.initialize()
|
recorder_manager.initialize()
|
||||||
|
|
||||||
scte35_manager = SCTE35Manager()
|
scte35_manager = SCTE35Manager()
|
||||||
|
|
||||||
hls_manager = HLSPreviewManager(settings)
|
hls_manager = HLSPreviewManager(settings)
|
||||||
|
|
||||||
# Inject managers into routes module
|
# Inject all managers into routes module
|
||||||
routes_module.recorder_manager = recorder_manager
|
routes_module.recorder_manager = recorder_manager
|
||||||
routes_module.scte35_manager = scte35_manager
|
routes_module.scte35_manager = scte35_manager
|
||||||
|
routes_module.hls_manager = hls_manager
|
||||||
# Start background task for status broadcasting
|
|
||||||
status_task = asyncio.create_task(broadcast_port_status())
|
status_task = asyncio.create_task(broadcast_port_status())
|
||||||
|
|
||||||
logger.info("Deltacast SDI Recorder started successfully")
|
logger.info(f"Deltacast SDI Recorder started — {settings.deltacast_port_count} ports")
|
||||||
|
|
||||||
yield # Application runs here
|
yield
|
||||||
|
|
||||||
# Shutdown
|
|
||||||
logger.info("Shutting down Deltacast SDI Recorder...")
|
logger.info("Shutting down Deltacast SDI Recorder...")
|
||||||
status_task.cancel()
|
status_task.cancel()
|
||||||
try:
|
try:
|
||||||
await status_task
|
await status_task
|
||||||
except asyncio.CancelledError:
|
except asyncio.CancelledError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Stop all recorders and previews
|
|
||||||
for port_index in range(settings.deltacast_port_count):
|
for port_index in range(settings.deltacast_port_count):
|
||||||
await recorder_manager.stop_recording(port_index)
|
await recorder_manager.stop_recording(port_index)
|
||||||
await hls_manager.stop_preview(port_index)
|
await hls_manager.stop_preview(port_index)
|
||||||
|
|
||||||
logger.info("Shutdown complete")
|
logger.info("Shutdown complete")
|
||||||
|
|
||||||
|
|
||||||
async def broadcast_port_status():
|
async def broadcast_port_status():
|
||||||
"""Background task: broadcast port status to all WebSocket clients every 1 second."""
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
if recorder_manager is not None:
|
if recorder_manager is not None:
|
||||||
|
|
@ -92,7 +86,6 @@ app = FastAPI(
|
||||||
lifespan=lifespan
|
lifespan=lifespan
|
||||||
)
|
)
|
||||||
|
|
||||||
# CORS - allow all origins for local network use
|
|
||||||
app.add_middleware(
|
app.add_middleware(
|
||||||
CORSMiddleware,
|
CORSMiddleware,
|
||||||
allow_origins=["*"],
|
allow_origins=["*"],
|
||||||
|
|
@ -101,18 +94,14 @@ app.add_middleware(
|
||||||
allow_headers=["*"],
|
allow_headers=["*"],
|
||||||
)
|
)
|
||||||
|
|
||||||
# Include API router
|
|
||||||
app.include_router(router)
|
app.include_router(router)
|
||||||
|
|
||||||
|
|
||||||
@app.websocket("/ws")
|
@app.websocket("/ws")
|
||||||
async def websocket_endpoint(websocket: WebSocket):
|
async def websocket_endpoint(websocket: WebSocket):
|
||||||
"""WebSocket endpoint for real-time port status updates."""
|
|
||||||
await connection_manager.connect(websocket)
|
await connection_manager.connect(websocket)
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
# Keep connection alive, receive any messages
|
|
||||||
# (not used but required to detect disconnect)
|
|
||||||
data = await websocket.receive_text()
|
data = await websocket.receive_text()
|
||||||
except WebSocketDisconnect:
|
except WebSocketDisconnect:
|
||||||
connection_manager.disconnect(websocket)
|
connection_manager.disconnect(websocket)
|
||||||
|
|
@ -120,7 +109,6 @@ async def websocket_endpoint(websocket: WebSocket):
|
||||||
|
|
||||||
@app.get("/hls/{filename}")
|
@app.get("/hls/{filename}")
|
||||||
async def serve_hls(filename: str):
|
async def serve_hls(filename: str):
|
||||||
"""Serve HLS segment and playlist files."""
|
|
||||||
hls_path = Path("/tmp/hls") / filename
|
hls_path = Path("/tmp/hls") / filename
|
||||||
if not hls_path.exists():
|
if not hls_path.exists():
|
||||||
raise HTTPException(status_code=404, detail="HLS file not found")
|
raise HTTPException(status_code=404, detail="HLS file not found")
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue