StreamHall
Self-hosted live stream hall - public list, player, admin panel, analytics & push notifications
English · 简体中文
- ✨ Features
- 🚀 Quick Start
- 💻 Local Development
- ⚙️ Configuration
- 🐳 Services
- 🔌 Stream Push
- 📡 API
- 🤝 Contributing
- 📝 License
✨ 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
- Admin panel - Add, edit, reorder, enable/disable streams; manage sources; drag-and-drop ordering
- 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
- Stream push - SRS RTMP publishing helpers, hidden HLS route proxy so real stream keys are never exposed publicly
- HLS proxy - Signed
/proxy/hls/routes for cross-origin HLS playback - API key auth - Generate per-key tokens in the admin panel for programmatic access to all admin and analytics endpoints
🚀 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.ymland changeSECRET_KEYandPOSTGRES_PASSWORDto 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
💻 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 |
change-this-secret |
Yes | HMAC signing key for sessions and stream routes |
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 |
STREAM_MONITOR_INTERVAL |
10 |
No | Seconds between stream liveness checks |
TELEGRAM_TIMEOUT |
6 |
No | Seconds before aborting a Telegram API call |
Warning
Always change
SECRET_KEYandPOSTGRES_PASSWORDbefore exposing StreamHall to a network. The defaults are intentionally weak placeholders.
🐳 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 Stream Setup section generates a hidden public HLS URL (/h/<slug>/...) that 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:1935if you use a non-standard port.
📡 API
Authentication
- Browser session - cookie set by
POST /api?action=login - API key - send
Authorization: Bearer <token>header, or append?api_key=<token>to any admin endpoint. 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 |
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 |
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 |
Export sessions as CSV |
💡 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.