param( [switch]$InstallDeps, [switch]$BuildFrontend, [string]$HostAddress = "0.0.0.0", [int]$BackendPort = 8080 ) $ErrorActionPreference = "Stop" $Base = Split-Path -Parent $MyInvocation.MyCommand.Path $BackendDir = Join-Path $Base "backend" $RuntimeDir = Join-Path $Base "runtime" $HlsDir = Join-Path $RuntimeDir "hls" $ReplayDir = Join-Path $RuntimeDir "replay" $LogDir = Join-Path $RuntimeDir "logs" New-Item -ItemType Directory -Force -Path $RuntimeDir, $HlsDir, $ReplayDir, $LogDir | Out-Null if (-not $env:LS_HLS_RUNTIME_DIR) { $env:LS_HLS_RUNTIME_DIR = $HlsDir } if (-not $env:LS_REPLAY_MEDIA_DIR) { $env:LS_REPLAY_MEDIA_DIR = $ReplayDir } function Resolve-Python { $candidates = @( (Join-Path $BackendDir ".venv\Scripts\python.exe"), (Join-Path $BackendDir "venv\Scripts\python.exe"), "python", "py" ) foreach ($candidate in $candidates) { if (Test-Path $candidate) { return $candidate } $cmd = Get-Command $candidate -ErrorAction SilentlyContinue if ($cmd) { return $cmd.Source } } throw "Python not found. Install Python 3.11+ or create backend\.venv." } $Python = Resolve-Python if ($InstallDeps) { Write-Host "[StreamCore] Installing backend dependencies..." Push-Location $BackendDir & $Python -m pip install -r requirements.txt Pop-Location } # The frontend is built once and then served by the backend, so Node is only # needed here — production never runs npm. Done automatically on a first start so # a fresh checkout does not come up as a 503 with no obvious cause. $FrontendDir = Join-Path $Base "frontend" $DistDir = Join-Path $FrontendDir "dist" if ($BuildFrontend -or -not (Test-Path (Join-Path $DistDir "index.html"))) { if (Get-Command "npm" -ErrorAction SilentlyContinue) { Write-Host "[StreamCore] Building frontend..." Push-Location $FrontendDir if (-not (Test-Path "node_modules")) { npm install } npm run build Pop-Location } else { Write-Warning "npm not found and frontend\dist is missing; the site will return 503." Write-Warning "Install Node.js and run: cd frontend; npm install; npm run build" } } # MediaMTX, the transcoders and the HLS tree are managed by the backend itself: # it starts the media origin at boot, supervises ffmpeg, and restarts either if it # dies. This launcher only has to bring up the process that owns all of that. Write-Host "[StreamCore] Starting backend on ${HostAddress}:${BackendPort} ..." Write-Host "[StreamCore] Frontend, MediaMTX, transcoders and HLS are served by the backend." $backendArgs = @("-m", "uvicorn", "main:app", "--host", $HostAddress, "--port", "$BackendPort") & $Python @backendArgs