Hardware encoding
- Detect the best usable encoder at startup by encoding a test frame with each
candidate in turn (nvenc, qsv, amf, then libx264). Being compiled into ffmpeg
is not enough: h264_amf fails without amfrt64.dll and h264_qsv fails without an
Intel iGPU, so the probe is the only reliable answer.
- Translate the quality target into the chosen encoder's own vocabulary. libx264's
-crf and "ultrafast" mean nothing to h264_nvenc, which takes -cq and p1..p7, so
passing the configured values straight through would have been silently wrong.
- On the reference GTX 1060 a 1080p->720p rendition costs ~62% of a core on NVENC
versus ~109% on libx264 ultrafast.
Per-rendition supervision
- Track encoder processes per rendition, not per stream. is_running answered
"any alive", so when the source ("原画") encoder died while 1080p and 720p kept
running, the supervisor saw a healthy stream and never restarted it — the
source URL then 404'd permanently. It now requires every rendition to be alive
and reports which ones are down.
- Restart only the dead renditions, so a single failure no longer interrupts
viewers on the renditions that were fine.
Production serving
- Serve the built frontend from FastAPI with SPA fallback, so production is one
process and one port with no Node runtime. Node becomes a build-time dependency.
- start.ps1/start.sh build the frontend on first run instead of failing to a 503.
Cleanup
- Drop the duplicated top-left LIVE badge; the control strip already carries it.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
124 lines
5.0 KiB
Markdown
124 lines
5.0 KiB
Markdown
# Deployment
|
|
|
|
The maintained deployment target for this project is Windows first. Linux and macOS can still run services manually, but real end-to-end deployment testing should use the PowerShell flow below.
|
|
|
|
Runtime paths are resolved relative to the repository by default and can be overridden with environment variables.
|
|
|
|
- LS_DATABASE_URL: SQLAlchemy database URL.
|
|
- LS_REPLAY_MEDIA_DIR: server-local directory containing replay files. When started by start.ps1, the default is runtime\replay under the repository.
|
|
- LS_HLS_RUNTIME_DIR: backend and FFmpeg HLS output directory. When started by start.ps1, the default is runtime\hls under the repository.
|
|
|
|
## Windows deployment
|
|
|
|
Run these commands from PowerShell on the Windows node.
|
|
|
|
### 1. Install prerequisites
|
|
|
|
Required on PATH: Python 3.11+, FFmpeg, and MediaMTX. MediaMTX may instead be left in the repository's `mediamtx\` directory, which is where the backend looks second. Node.js is only needed to build the frontend for deployment.
|
|
|
|
### 2. Install application dependencies
|
|
|
|
```powershell
|
|
powershell -ExecutionPolicy Bypass -File .\start.ps1 -InstallDeps
|
|
```
|
|
|
|
### 3. Build the frontend
|
|
|
|
Once per deployment, and again whenever the frontend changes. The build output is
|
|
committed to the server by the build step and then served by the backend itself,
|
|
so **Node.js is a build-time dependency only** — production runs without it and
|
|
without a Vite dev server.
|
|
|
|
```powershell
|
|
cd frontend
|
|
npm install
|
|
npm run build
|
|
cd ..
|
|
```
|
|
|
|
Skipping this is not silent: the backend answers every page with HTTP 503 and
|
|
`s Frontend not built` until `frontend\dist` exists.
|
|
|
|
### 4. Start the stack
|
|
|
|
```powershell
|
|
powershell -ExecutionPolicy Bypass -File .\start.ps1
|
|
```
|
|
|
|
This starts one process on 0.0.0.0:8080 that owns everything:
|
|
|
|
- **The frontend** is served from `frontend\dist` on the same port. Unknown paths
|
|
return the app shell so client-side routes survive a refresh.
|
|
- **MediaMTX** is started at boot if nothing is already answering its API on :9997, and restarted by the supervisor if it dies. Set `LS_MEDIA_ORIGIN_AUTOSTART=false` to manage it externally; the backend then only supervises transcoders.
|
|
- **Transcoders** are started for every live stream whose MediaMTX path is publishing, and restarted within ~10s of an ffmpeg process exiting. They encode on the GPU when one is available (see below).
|
|
- **HLS** is written under `runtime\hls` and served through `GET /hls/...`, which falls back to proxying MediaMTX's own HLS when the local files are absent.
|
|
|
|
Open http://127.0.0.1:8080/ for the site and /docs for the API. Publish RTMP to
|
|
rtmp://127.0.0.1:1935/live/<stream_key>.
|
|
|
|
### Hardware encoding
|
|
|
|
The transcoders detect the best encoder the host actually has, at startup, by
|
|
encoding a test frame with each candidate in turn:
|
|
|
|
1. `h264_nvenc` / `hevc_nvenc` (NVIDIA)
|
|
2. `h264_qsv` (Intel iGPU)
|
|
3. `h264_amf` (AMD)
|
|
4. `libx264` (CPU fallback)
|
|
|
|
Only encoders that really work are used — being compiled into ffmpeg is not
|
|
enough, since `h264_amf` fails without `amfrt64.dll` and `h264_qsv` fails without
|
|
an Intel iGPU. The choice is logged at startup as `[transcoder] hardware encoder:
|
|
…`, or `[transcoder] no working hardware encoder; falling back to libx264` with
|
|
the probed candidates listed. On the reference GTX 1060, one 1080p→720p
|
|
rendition costs ~62% of a core on NVENC versus ~109% on libx264 ultrafast.
|
|
|
|
### 5. Useful variants
|
|
|
|
```powershell
|
|
powershell -ExecutionPolicy Bypass -File .\start.ps1 -HostAddress 0.0.0.0 -BackendPort 8080
|
|
```
|
|
|
|
### 6. Smoke test commands
|
|
|
|
```powershell
|
|
curl.exe http://127.0.0.1:8080/api/health
|
|
curl.exe http://127.0.0.1:9997/v3/paths/list
|
|
ffmpeg -version
|
|
mediamtx --version
|
|
nvidia-smi
|
|
```
|
|
|
|
If browser or network tests run from another machine, open the Windows firewall for ports 8080, 1935, and 8888.
|
|
|
|
## Windows edge node launcher
|
|
|
|
Build and start an edge node from a Windows edge machine:
|
|
|
|
```powershell
|
|
powershell -ExecutionPolicy Bypass -File .\edge-agent\start-edge.ps1 -Build -OriginUrl http://<origin-host>:8080 -NodeId edge-win-01 -Region default -HlsPort 8889 -ApiPort 9997
|
|
```
|
|
|
|
For normal subsequent starts, omit `-Build`:
|
|
|
|
```powershell
|
|
powershell -ExecutionPolicy Bypass -File .\edge-agent\start-edge.ps1 -OriginUrl http://<origin-host>:8080 -NodeId edge-win-01 -Region default -HlsPort 8889 -ApiPort 9997
|
|
```
|
|
|
|
The launcher sets the StreamCore edge environment variables, starts the Windows edge-agent executable, stores runtime data under `ProgramData\StreamCore\edge\<node-id>` by default, and writes logs to that node data directory. The edge agent then manages its embedded MediaMTX edge process.
|
|
|
|
## Edge node scripts
|
|
|
|
```cmd
|
|
mediamtx\scripts\start_origin.bat
|
|
mediamtx\scripts\start_edge.bat 1 127.0.0.1
|
|
mediamtx\scripts\check_multicast.bat
|
|
```
|
|
|
|
## Replay file safety
|
|
|
|
Replay records store paths relative to LS_REPLAY_MEDIA_DIR. Absolute paths and parent-directory traversal are rejected.
|
|
|
|
## Linux and macOS
|
|
|
|
Linux and macOS are not the primary deployment path. For local development, run the backend with uvicorn from `backend`, run the frontend with `npm run dev` from `frontend`, and set `LS_HLS_RUNTIME_DIR` to a writable directory. |