Stardream c4c3e6f445
Build and Push Docker Image / build (push) Successful in 17s
fix: instant cookie probe, default Auto quality, consistent control order
- Trigger a stream probe immediately when the upstream cookie field changes,
  instead of waiting for the next monitor cycle
- Remove the probeActive guard in checkLinkRow so a cookie-triggered probe is no
  longer dropped when it lands while the URL probe is still in flight (the
  probeToken check already handles superseded results)
- Default the HLS resolution menu to its "Auto" (ABR) entry rather than landing
  on a fixed (lowest) rung; start hls.js in auto level mode
- Keep source (视角) selector on the left and resolution on the right in both
  live and archive players, which previously rendered in opposite order
2026-06-02 00:59:55 +10:00
2026-05-20 15:25:51 +10:00
2026-05-20 15:25:51 +10:00
2026-05-20 15:25:51 +10:00
2026-05-20 15:25:51 +10:00

StreamHall

Self-hosted live stream hall - public list, player, admin panel, analytics & push notifications

English · 简体中文


Features

  • Public stream list - Live and archive tabs, password-protected streams, custom site branding, bilingual UI (Chinese / English) with per-language site description
  • Player - HLS, FLV, MPEG-DASH playback via ArtPlayer; AES-128 key override and DASH ClearKey support; Widevine and FairPlay DRM playback via Shaka Player (multi-DRM configs per source, Android Telegram WebView detection)
  • Admin panel - Add, edit, reorder, enable/disable streams; manage sources with per-source labels and proxy mode selection
  • Viewer analytics - Session tracking, unique visitors, peak concurrent viewers, average watch duration, device / browser / OS / geography breakdown, real-time dashboard, CSV export
  • Telegram notifications - Per-stream push messages on stream start and stop; each source going live fires its own notification, simultaneous go-lives within a configurable window are merged into one message, and brief RTMP reconnects within a grace period are suppressed to avoid spurious stop/start pairs
  • Stream push - Local file browser with per-file and per-folder RTMP push management; multi-file folder push with independent stream keys; inline push status and detail modal; remote RTMP push config for external encoders; hidden HLS route proxy (/h/<slug>) so real stream keys are never exposed publicly
  • VOD / file serving - Signed /video/ URLs with HTTP Range support (seek-capable); publish any local video file or folder as an archive stream directly from the file browser
  • HLS proxy modes - Per-source direct, full proxy, or manifest-only proxy modes for balancing source URL exposure, CORS compatibility, and server bandwidth; full proxy supports upstream cookie forwarding for cookie-authenticated CDNs (e.g. CloudFront signed cookies), with the cookie stored server-side and never exposed in playback URLs
  • API key auth - Generate per-key tokens in the admin panel for programmatic access to all admin and analytics endpoints
  • Mobile responsive - Admin panel sidebar, source editor, file browser rows, and push directory sidebar all collapse gracefully on narrow screens

🚀 Quick Start

1. Download and configure

curl -LO https://git.stdm.moe/Stardream/StreamHall/raw/branch/main/docker-compose.yml
curl -LO https://git.stdm.moe/Stardream/StreamHall/raw/branch/main/nginx-hls.conf

Important

Open docker-compose.yml and change SECRET_KEY and POSTGRES_PASSWORD to strong random values before starting.

2. Start

docker compose up -d

3. Find the initial admin password

docker logs streamhall

Look for:

StreamHall initial admin password: <random-password>

4. Access

URL Description
http://HOST:8085/ Public stream list
http://HOST:8085/admin Admin panel
http://HOST:18088/ SRS HTTP playback
http://HOST:8889/ Nginx HLS proxy

Tip

After first login, change your password under Site Settings → Security. The initial password is printed once and not stored in plaintext.

Updating to a newer version

docker compose pull && docker compose up -d

Resetting a forgotten admin password

docker exec streamhall-postgres psql -U streamhall -d streamhall \
  -c "DELETE FROM site_settings WHERE key='admin_password_hash';"
docker restart streamhall
docker logs streamhall

Deleting the hash causes StreamHall to generate a new random password on the next startup and print it to the log.

💻 Local Development

Prerequisites: Python 3.12+, PostgreSQL 14+

# 1. Clone the repo
git clone https://git.stdm.moe/Stardream/StreamHall.git
cd StreamHall

# 2. Install the single runtime dependency
pip install -r requirements.txt

# 3. Export required environment variables
export SECRET_KEY=dev-secret
export DATABASE_URL=postgresql://user:pass@localhost:5432/streamhall

# 4. Start the server
python server.py

The app listens on http://localhost:8080 by default. On first startup it creates the database schema and prints a one-time admin password to stdout.

⚙️ Configuration

Set these environment variables in docker-compose.yml:

Variable Default Required Description
SECRET_KEY REPLACE_ME Yes HMAC signing key for sessions and stream routes. Generate with openssl rand -hex 32
DATABASE_URL see compose file Yes PostgreSQL connection string
POSTGRES_PASSWORD see compose file Yes PostgreSQL password
TZ UTC No Container timezone, e.g. Asia/Shanghai
SRS_HTTP_ORIGIN http://srs:8080 No SRS HTTP playback base URL
STREAM_PROBE_TIMEOUT 4 No Seconds before aborting a stream URL probe
HLS_PROXY_TIMEOUT 15 No Seconds before aborting an upstream HLS manifest/segment proxy request
STREAM_MONITOR_INTERVAL 10 No Seconds between stream liveness checks
TELEGRAM_TIMEOUT 6 No Seconds before aborting a Telegram API call
TG_RECONNECT_GRACE_SECS 60 No Grace period before sending a stop notification; absorbs brief RTMP reconnects (0 disables)
TG_START_MERGE_SECS 30 No Window for merging simultaneous link-online events into one start notification (0 disables)
RTMP_HOST srs No Hostname of the SRS container used for local push jobs
VIDEOS_DIRS (unset) No Comma-separated list of directories exposed in the file browser. Optionally prefix each path with a label: label:/app/path. Multiple entries: movies:/app/movies,shows:/app/shows

Warning

Always change SECRET_KEY and POSTGRES_PASSWORD before exposing StreamHall to a network. The defaults are intentionally weak placeholders.

Mounting video directories for Local Push

Method 1 — single base directory, multiple sources as subdirectories:

Mount multiple host paths under one container base path. The file browser shows them as subdirectories.

environment:
  VIDEOS_DIRS: "/app/videos"
volumes:
  - ./videos:/app/videos/local
  - /your/media/path:/app/videos/external

Method 2 — multiple labeled top-level directories:

Each path is listed as a separate labeled root entry in the file browser.

environment:
  VIDEOS_DIRS: "/app/videos,external:/app/media/external"
volumes:
  - ./videos:/app/videos
  - /your/media/path:/app/media/external

HLS proxy modes

Each stream source can choose how external HLS URLs are exposed to viewers:

Mode Behavior Bandwidth impact
Auto Backward-compatible default; external HLS uses the full proxy StreamHall carries manifest and segment traffic
Direct Player uses the source URL directly Viewer traffic goes to the source server
Full proxy Manifest, segments, maps, and keys are routed through /proxy/hls/ StreamHall carries all HLS media traffic
Manifest only Only the playlist uses StreamHall; segment/key/map URLs are absolute source URLs Low StreamHall bandwidth; final media URLs remain visible in browser network tools

In Full proxy mode, a source can also set an upstream cookie for CDNs that require cookie-based authentication (e.g. CloudFront signed cookies). StreamHall forwards the cookie on every manifest and segment request. The cookie is stored server-side and referenced via a signed opaque token in proxy URLs, so it is never derivable from a playback or segment URL. Upstream proxy requests reuse pooled HTTP connections to avoid per-request TLS handshake overhead.

🐳 Services

The default compose stack starts four containers:

Container Image Port(s) Purpose
streamhall local build 8085→8080 Python app + static frontend
streamhall-postgres postgres:16-alpine - PostgreSQL persistent database
streamhall-srs ossrs/srs:6 1935, 18088→8080 RTMP publishing + HTTP playback
streamhall-nginx-hls nginx:alpine 8889→80 Clean public HLS route proxy

Persistent data is stored in ./postgres-data/.

🔌 Stream Push

SRS handles RTMP publishing on port 1935. Configure your encoder as follows:

RTMP server:  rtmp://HOST:1935/live
Stream key:   your-stream-key

The admin panel's Local Push section provides a file browser for your media directory. Select any video file to push it via RTMP with a custom stream key, or select a folder to push all contained videos simultaneously with independent stream keys. Push status is shown inline per file; a detail modal gives real-time duration, copy addresses, and stop controls.

The hidden public HLS URL (/h/<slug>/...) routes through nginx on port 8889, keeping the real stream key out of the public URL.

Note

The RTMP host field accepts an optional port, e.g. live.example.com:1935. Do not hard-code :1935 if you use a non-standard port.

📡 API

Authentication

  • Browser session - cookie set by POST /api?action=login
  • API key - send Authorization: Bearer <token> header. Keys are managed in the admin panel under Site Settings → API Keys.

Public Endpoints

Method Endpoint Description
GET /api?action=public_list Stream list for the public homepage
GET /api?action=site_settings Site title, description, branding
GET /api?action=get_player_data&id=<public_id> Player sources and metadata
POST /api?action=verify_password Verify a stream password
GET /video/<token>/<payload> Signed VOD endpoint with HTTP Range support

Admin Endpoints

Method Endpoint Description
POST /api?action=login Authenticate and start a session
GET /api?action=logout End the current session
GET /api?action=list_admin Full stream list
POST /api?action=add Add a stream
POST /api?action=update Update a stream
POST /api?action=delete Delete a stream
POST /api?action=set_stream_enabled Toggle stream visibility
POST /api?action=reorder_streams Reorder within a label group
POST /api?action=update_site_settings Save site settings
GET /api?action=telegram_settings Read Telegram bot config
POST /api?action=update_telegram_settings Save Telegram bot config
POST /api?action=update_admin_password Change admin password
GET /api?action=list_api_keys List API keys (tokens not returned)
POST /api?action=create_api_key Create a key - token returned once
POST /api?action=delete_api_key Revoke a key by id
GET /api?action=list_pushes List active push jobs
POST /api?action=start_push Start an RTMP push job for a file
POST /api?action=stop_push Stop a push job by stream key
GET /api?action=list_folder_videos List playable files in a directory (with signed URLs)

Analytics Endpoints

Method Endpoint Description
GET /api?action=stats_overview Aggregated totals
GET /api?action=stats_streams Per-stream stats table
GET /api?action=stats_timeseries Bucketed view counts
GET /api?action=stats_geo Country-level visitor counts
GET /api?action=stats_stream_detail&id=<id> Single-stream detail
GET /api?action=stats_sessions_page&id=<id> Paginated session list
GET /api?action=stats_export_csv&range=<range> Export sessions as CSV (range: today, 7d, 30d (default), all)

💡 Acknowledgements

StreamHall was inspired by AniLive, a live stream listing site that is not open-source. This project is an independent reimplementation built from scratch, sharing no code with the original site.

🤝 Contributing

Issues and pull requests are welcome. Please open an issue first for major changes so the direction can be discussed.

📝 License

Copyright © 2026 Stardream. This project is licensed under the GNU Affero General Public License v3.0.

Permissions

Commercial use
Modification
Distribution
Private use

Conditions

⚠️ Disclose source - modified versions must also be open-source
⚠️ Same license - derivative works must use AGPL-3.0
⚠️ Network use = distribution - if you run a modified version as a network service, you must make the source available to users
⚠️ State changes - modifications must be documented

In short: you are free to use, modify, and self-host StreamHall. If you distribute or offer a modified version as a hosted service, you must publish the full source under AGPL-3.0.


S
Description
Self-hosted live stream hall - public list, player, admin panel, analytics & push notifications | https://github.com/STRDM-User/StreamHall
https://live.stdm.moe
Readme AGPL-3.0 2.9 MiB
v1.2.4 Latest
2026-05-31 01:18:51 +10:00
Languages
HTML 70.1%
Python 29.8%