Appearance
Streaming API
Play media files from the Local Media Store, start HLS transcode sessions, and save playback progress.
Try it with a token
Start with the Authentication login flow, then use that bearer token in the requests below.
Direct file streaming
http
GET /api/stream/file?path=/data/movies/Inception%20(2010)/Inception.mkv
Authorization: Bearer <token>
Range: bytes=0-bash
curl -i \
-H "Authorization: Bearer $OMNILUX_TOKEN" \
-H "Range: bytes=0-" \
--get \
--data-urlencode "path=/data/movies/Inception (2010)/Inception.mkv" \
"http://your-server:4000/api/stream/file"The path query value must point to a validated media file inside an allowed library root. The endpoint supports HTTP range requests and returns either 200 OK or 206 Partial Content.
Error example:
json
{
"error": "Path outside allowed media roots",
"code": "FORBIDDEN"
}Start an HLS transcode session
http
POST /api/stream/transcode/start
Authorization: Bearer <token>
Content-Type: application/json
{
"mediaPath": "/data/movies/Inception (2010)/Inception.mkv",
"audioStreamIndex": 1,
"startPositionSeconds": 120,
"profile": {
"resolution": "1080p"
},
"subtitleMode": "embedded",
"subtitleStreamIndex": 2,
"forceTranscode": true
}bash
curl -sS \
-X POST \
-H "Authorization: Bearer $OMNILUX_TOKEN" \
-H "Content-Type: application/json" \
--data @- \
"http://your-server:4000/api/stream/transcode/start" <<'EOF'
{
"mediaPath": "/data/movies/Inception (2010)/Inception.mkv",
"audioStreamIndex": 1,
"startPositionSeconds": 120,
"profile": { "resolution": "1080p" },
"subtitleMode": "embedded",
"subtitleStreamIndex": 2,
"forceTranscode": true
}
EOFResponse:
json
{
"sessionId": "stream_01HV6Y7J6P46B8Q4K6XK5J9A6A",
"playbackMode": "transcode",
"playlistUrl": "/api/stream/transcode/stream_01HV6Y7J6P46B8Q4K6XK5J9A6A/index.m3u8"
}When the runtime decides the file can be played directly, the response can be:
json
{
"sessionId": null,
"playbackMode": "direct",
"playlistUrl": null
}HLS playlist and session assets
http
GET /api/stream/transcode/:sessionId/index.m3u8
Authorization: Bearer <token>The playlist endpoint returns an HLS manifest when the session is ready. While FFmpeg is still preparing the playlist, it can return:
json
{
"status": "preparing"
}Players then request segment and subtitle assets under the same session path:
http
GET /api/stream/transcode/:sessionId/:asset
Authorization: Bearer <token>Stop a session when the player is done:
http
DELETE /api/stream/transcode/:sessionId
Authorization: Bearer <token>Transcode status
http
GET /api/stream/transcode/:sessionId/status
Authorization: Bearer <token>json
{
"ready": true,
"progress": 100,
"error": null,
"mode": "transcode",
"diagnostics": {
"encoder": "libx264"
}
}Report watch progress
http
POST /api/stream/progress
Authorization: Bearer <token>
Content-Type: application/json
{
"mediaPath": "/data/movies/Inception (2010)/Inception.mkv",
"mediaType": "video",
"title": "Inception",
"positionSeconds": 1234,
"durationSeconds": 8880,
"completed": false,
"player": "web"
}bash
curl -sS \
-X POST \
-H "Authorization: Bearer $OMNILUX_TOKEN" \
-H "Content-Type: application/json" \
--data @- \
"http://your-server:4000/api/stream/progress" <<'EOF'
{
"mediaPath": "/data/movies/Inception (2010)/Inception.mkv",
"mediaType": "video",
"title": "Inception",
"positionSeconds": 1234,
"durationSeconds": 8880,
"completed": false,
"player": "web"
}
EOFThe response is the saved watch-progress record.
Read or reset progress for a file:
http
GET /api/stream/progress?path=/data/movies/Inception%20(2010)/Inception.mkv
DELETE /api/stream/progress?path=/data/movies/Inception%20(2010)/Inception.mkv
Authorization: Bearer <token>Mark a title watched:
http
POST /api/stream/progress/watched
Authorization: Bearer <token>
Content-Type: application/json
{
"mediaPath": "/data/movies/Inception (2010)/Inception.mkv",
"mediaType": "video",
"title": "Inception",
"durationSeconds": 8880
}Fetch recently watched items:
http
GET /api/stream/history?limit=20
Authorization: Bearer <token>Audiobook progress
Audiobook playback has a chapter-aware progress endpoint:
http
POST /api/stream/audiobook/progress
Authorization: Bearer <token>
Content-Type: application/json
{
"audiobookPath": "/data/audiobooks/Dune/Dune.m4b",
"title": "Dune",
"chapterIndex": 3,
"chapterPositionSeconds": 90,
"positionSeconds": 5400,
"durationSeconds": 72000,
"progressPercentage": 7.5,
"playbackRate": 1.25,
"completed": false
}The response is:
json
{
"progress": {
"audiobookPath": "/data/audiobooks/Dune/Dune.m4b",
"positionSeconds": 5400,
"durationSeconds": 72000,
"progressPercentage": 7.5,
"completed": false
}
}Media info, tracks, and subtitles
Use media info endpoints before choosing a playback path:
http
GET /api/stream/info/full?path=/data/movies/Inception%20(2010)/Inception.mkv
Authorization: Bearer <token>The response includes probe data, stream tracks, subtitle options, watch progress, and playback capability hints used by the bundled web player.
V2 worker capabilities
http
GET /api/stream/v2-workers
Authorization: Bearer <token>Returns the current V2 transcoding worker capability view. This is diagnostic metadata only; native workers remain optional and local FFmpeg stays the baseline fallback.
json
{
"local": {
"kind": "transcoding",
"boundary": "ffmpeg-subprocess",
"status": "available",
"protocol": { "name": "omnilux-runtime-transcoding", "version": "2.0-draft" },
"supportedEncoders": ["libx264", "h264_nvenc"],
"maxConcurrentJobs": 1,
"activeJobCount": 0,
"fallback": {
"mode": "ffmpeg-subprocess",
"reason": "WORKER_FALLBACK_USED",
"userMessage": "Local FFmpeg is available as the baseline transcoding path."
}
},
"nodes": [],
"workers": []
}If FFmpeg is missing, local.status is unsupported and local.fallback.mode is unsupported-state.