docs(media): document phase5 stream media credential endpoints
This commit is contained in:
@@ -31,12 +31,15 @@ Required env vars:
|
|||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `DATABASE_URL` | Postgres connection string |
|
| `DATABASE_URL` | Postgres connection string |
|
||||||
| `BETTER_AUTH_SECRET` | Secret used to sign sessions |
|
| `BETTER_AUTH_SECRET` | Secret used to sign sessions |
|
||||||
| `BETTER_AUTH_URL` | Public base URL for the backend (e.g., `http://localhost:3000`) |
|
| `BETTER_AUTH_BASE_URL` | Public base URL for the backend (e.g., `http://localhost:3000`) |
|
||||||
| `BETTER_AUTH_TRUSTED_ORIGINS` | Comma-separated list of allowed frontend origins |
|
| `BETTER_AUTH_TRUSTED_ORIGINS` | Comma-separated list of allowed frontend origins |
|
||||||
| `PORT` | HTTP port (default `3000`) |
|
| `PORT` | HTTP port (default `3000`) |
|
||||||
|
| `MEDIA_PROVIDER` | Media backend provider (`mock` by default) |
|
||||||
| `MINIO_*` | Connection settings for the MinIO/S3 endpoint |
|
| `MINIO_*` | Connection settings for the MinIO/S3 endpoint |
|
||||||
| `ADMIN_USERNAME` / `ADMIN_PASSWORD` | Basic auth for `/admin` dashboard |
|
| `ADMIN_USERNAME` / `ADMIN_PASSWORD` | Basic auth for `/admin` dashboard |
|
||||||
|
|
||||||
|
`BETTER_AUTH_URL` is still accepted as a legacy fallback, but `BETTER_AUTH_BASE_URL` is preferred.
|
||||||
|
|
||||||
## Running
|
## Running
|
||||||
- Start the server in development:
|
- Start the server in development:
|
||||||
|
|
||||||
@@ -122,11 +125,13 @@ Motion realtime events:
|
|||||||
- Linked clients receive `motion:detected` as soon as camera starts event.
|
- Linked clients receive `motion:detected` as soon as camera starts event.
|
||||||
- Linked clients receive `motion:ended` when camera ends event.
|
- Linked clients receive `motion:ended` when camera ends event.
|
||||||
|
|
||||||
### On-Demand Streams (Phase 4)
|
### On-Demand Streams + Media Credentials (Phase 4 + 5)
|
||||||
| Endpoint | Purpose |
|
| Endpoint | Purpose |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `POST /streams/request` | Client device requests a linked camera to start a live stream |
|
| `POST /streams/request` | Client device requests a linked camera to start a live stream |
|
||||||
| `POST /streams/:streamSessionId/accept` | Camera device accepts and transitions stream session to `streaming` |
|
| `POST /streams/:streamSessionId/accept` | Camera device accepts and transitions stream session to `streaming` |
|
||||||
|
| `GET /streams/:streamSessionId/publish-credentials` | Camera fetches media ingest credentials for the active stream session |
|
||||||
|
| `GET /streams/:streamSessionId/subscribe-credentials` | Viewer fetches media subscribe credentials for the active stream session |
|
||||||
| `POST /streams/:streamSessionId/end` | Requester/camera ends an existing stream session |
|
| `POST /streams/:streamSessionId/end` | Requester/camera ends an existing stream session |
|
||||||
| `GET /streams/:streamSessionId/playback-token` | Obtain short-lived playback token for active stream |
|
| `GET /streams/:streamSessionId/playback-token` | Obtain short-lived playback token for active stream |
|
||||||
| `GET /streams/me/list` | List stream sessions for the current device |
|
| `GET /streams/me/list` | List stream sessions for the current device |
|
||||||
@@ -148,8 +153,8 @@ OpenAPI docs are generated from Zod/OpenAPI definitions:
|
|||||||
Use `GET /sim/mobile-sim.html` to run a browser simulator that behaves like the mobile app:
|
Use `GET /sim/mobile-sim.html` to run a browser simulator that behaves like the mobile app:
|
||||||
- Register as `camera` or `client`
|
- Register as `camera` or `client`
|
||||||
- Connect Socket.IO with bearer device token
|
- Connect Socket.IO with bearer device token
|
||||||
- Camera: process incoming `start_stream` commands, start/end motion events
|
- Camera: process incoming `start_stream` commands, fetch publish credentials, start/end motion events
|
||||||
- Client: create links, request streams, and fetch playback tokens
|
- Client: create links, request streams, fetch subscribe credentials, and fetch playback tokens
|
||||||
|
|
||||||
### Admin Dashboard
|
### Admin Dashboard
|
||||||
Access `/admin` with Basic auth to:
|
Access `/admin` with Basic auth to:
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { OpenAPIRegistry, OpenApiGeneratorV3, extendZodWithOpenApi } from '@asteasolutions/zod-to-openapi';
|
import { OpenAPIRegistry, OpenApiGeneratorV3, extendZodWithOpenApi } from '@asteasolutions/zod-to-openapi';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
import { getBetterAuthBaseUrl } from '../utils/env';
|
||||||
|
|
||||||
extendZodWithOpenApi(z);
|
extendZodWithOpenApi(z);
|
||||||
|
|
||||||
@@ -806,6 +807,10 @@ registry.registerPath({
|
|||||||
id: z.string().uuid(),
|
id: z.string().uuid(),
|
||||||
status: z.string(),
|
status: z.string(),
|
||||||
streamKey: z.string().nullable(),
|
streamKey: z.string().nullable(),
|
||||||
|
mediaProvider: z.string(),
|
||||||
|
mediaSessionId: z.string().nullable(),
|
||||||
|
publishEndpoint: z.string().nullable(),
|
||||||
|
subscribeEndpoint: z.string().nullable(),
|
||||||
startedAt: z.string().datetime().nullable(),
|
startedAt: z.string().datetime().nullable(),
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
@@ -852,6 +857,60 @@ registry.registerPath({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
registry.registerPath({
|
||||||
|
method: 'get',
|
||||||
|
path: '/streams/{streamSessionId}/publish-credentials',
|
||||||
|
summary: 'Get publish credentials for camera ingest to media provider',
|
||||||
|
tags: ['Streams'],
|
||||||
|
security: [{ bearerDeviceToken: [] }],
|
||||||
|
request: {
|
||||||
|
params: z.object({ streamSessionId: z.string().uuid() }),
|
||||||
|
},
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
description: 'Publish credentials',
|
||||||
|
content: {
|
||||||
|
'application/json': {
|
||||||
|
schema: z.object({
|
||||||
|
provider: z.string(),
|
||||||
|
mediaSessionId: z.string(),
|
||||||
|
publishToken: z.string(),
|
||||||
|
publishUrl: z.string(),
|
||||||
|
expiresInSeconds: z.number().int(),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
registry.registerPath({
|
||||||
|
method: 'get',
|
||||||
|
path: '/streams/{streamSessionId}/subscribe-credentials',
|
||||||
|
summary: 'Get subscribe credentials for viewing stream from media provider',
|
||||||
|
tags: ['Streams'],
|
||||||
|
security: [{ bearerDeviceToken: [] }],
|
||||||
|
request: {
|
||||||
|
params: z.object({ streamSessionId: z.string().uuid() }),
|
||||||
|
},
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
description: 'Subscribe credentials',
|
||||||
|
content: {
|
||||||
|
'application/json': {
|
||||||
|
schema: z.object({
|
||||||
|
provider: z.string(),
|
||||||
|
mediaSessionId: z.string(),
|
||||||
|
subscribeToken: z.string(),
|
||||||
|
subscribeUrl: z.string(),
|
||||||
|
expiresInSeconds: z.number().int(),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
registry.registerPath({
|
registry.registerPath({
|
||||||
method: 'get',
|
method: 'get',
|
||||||
path: '/streams/{streamSessionId}/playback-token',
|
path: '/streams/{streamSessionId}/playback-token',
|
||||||
@@ -871,6 +930,8 @@ registry.registerPath({
|
|||||||
streamKey: z.string(),
|
streamKey: z.string(),
|
||||||
status: z.string(),
|
status: z.string(),
|
||||||
playbackToken: z.string(),
|
playbackToken: z.string(),
|
||||||
|
subscribeUrl: z.string(),
|
||||||
|
mediaProvider: z.string(),
|
||||||
expiresInSeconds: z.number().int(),
|
expiresInSeconds: z.number().int(),
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
@@ -906,6 +967,8 @@ registry.registerPath({
|
|||||||
status: z.string(),
|
status: z.string(),
|
||||||
reason: z.string(),
|
reason: z.string(),
|
||||||
streamKey: z.string().nullable(),
|
streamKey: z.string().nullable(),
|
||||||
|
mediaProvider: z.string(),
|
||||||
|
mediaSessionId: z.string().nullable(),
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
@@ -924,7 +987,7 @@ export function buildOpenApiDocument() {
|
|||||||
version: '1.0.0',
|
version: '1.0.0',
|
||||||
description: 'Auto-generated API documentation from Zod schemas.',
|
description: 'Auto-generated API documentation from Zod schemas.',
|
||||||
},
|
},
|
||||||
servers: [{ url: process.env.BETTER_AUTH_URL ?? 'http://localhost:3000' }],
|
servers: [{ url: getBetterAuthBaseUrl() }],
|
||||||
tags: [
|
tags: [
|
||||||
{ name: 'System', description: 'Service endpoints' },
|
{ name: 'System', description: 'Service endpoints' },
|
||||||
{ name: 'Videos', description: 'Authenticated video object operations' },
|
{ name: 'Videos', description: 'Authenticated video object operations' },
|
||||||
|
|||||||
Reference in New Issue
Block a user