Serve video-on-demand and live streams over HLS and DASH from your own server. Adaptive bitrate delivery, origin pull, and DVR for live streams — without a CDN contract.
Works best alongside nself-media-processing for ABR transcode and nself-epg for live channel scheduling.
nself license set nself_pro_...
nself plugin install streaming
nself build
nself startnself-streaming is an origin server for HLS (.m3u8 + .ts segments) and MPEG-DASH (.mpd + .mp4 segments). It reads renditions produced by nself-media-processing from your object storage and generates manifest files on demand, supporting adaptive bitrate switching at the player level.
For live streams, the plugin accepts RTMP ingest (from OBS, ffmpeg, or any RTMP encoder), segments the stream in real time using FFmpeg, and serves the live HLS playlist. DVR windowing lets viewers seek back into a live stream up to a configurable window (default: 2 hours) without storing the whole recording upfront.
Token-protected manifests prevent hotlinking. Each stream URL is signed with a short-lived HMAC token tied to the requesting user's session. Expired tokens result in a 403 before any segment is served.
| Variable | Required | Description |
|---|---|---|
DATABASE_URL | Yes | Postgres connection string (auto-set by nself) |
STREAMING_STORAGE_BUCKET | Yes | Object storage bucket where media-processing writes renditions |
STREAMING_RTMP_PORT | No | RTMP ingest port. Default: 1935 |
STREAMING_DVR_WINDOW_HOURS | No | Live stream DVR seek window. Default: 2 |
STREAMING_TOKEN_TTL_SECONDS | No | Signed URL lifetime. Default: 3600 |
STREAMING_SIGNING_KEY | Yes | HMAC key for manifest URL signing. Generate with openssl rand -hex 32 |
| Endpoint | Method | Description |
|---|---|---|
/streaming/vod/:id/manifest.m3u8 | GET | HLS master manifest for a VOD asset |
/streaming/vod/:id/manifest.mpd | GET | DASH manifest for a VOD asset |
/streaming/live/:channel/index.m3u8 | GET | Live HLS playlist for a streaming channel |
/streaming/token | POST | Issue a signed URL token for a specific asset |
/streaming/streams | GET | List active live streams and their RTMP ingest keys |
/health | GET | Plugin health, active stream count |
| Table | Purpose |
|---|---|
np_streaming_assets | VOD asset registry with source job ID, renditions, access policy |
np_streaming_channels | Live stream channels with RTMP keys, EPG link, DVR config |
np_streaming_sessions | Viewer sessions: asset, user, quality, watch time |
| Event | Payload |
|---|---|
streaming.live.started | Channel ID, RTMP stream key, ingest IP |
streaming.live.ended | Channel ID, duration, peak viewer count |
streaming.vod.played | Asset ID, user ID, watch duration, quality selected |
nself-streaming is the delivery layer for the ɳTV media stack. nself-media-processing feeds it transcoded renditions; nself-epg feeds it the live channel schedule. The ɳTV app (ntv/) reads the streaming manifests directly — no intermediate CDN required for local or single-datacenter deployments.
| Feature | nself-streaming | Cloudflare Stream | Wowza |
|---|---|---|---|
| Cost (100 GB/mo storage + delivery) | $0.99/mo bundle + your disk | ~$5 storage + $1/1000 min viewed | $149/mo+ streaming plan |
| Data residency | Your server | Cloudflare PoPs | Cloud or on-prem |
| DVR | Configurable window | Yes (paid) | Yes |
RTMP stream not connecting: Port 1935 must be open in your firewall. OBS settings: Server = rtmp://your.domain/live, Stream Key = the key from GET /streaming/streams.
Manifest 403 errors: The signed URL has expired. Shorten player session length or increase STREAMING_TOKEN_TTL_SECONDS. Players using the HLS.js or video.js SDK can auto-refresh tokens on 403.
Port: 3511 (moved from 3732) | Bundle: ɳTV ($0.99/mo) or ɳSelf+ ($3.99/mo) | Last Updated: May 2026 | Plugin Version 1.0.13