14 KiB
✨ 功能特性
- 公开直播列表 - 直播 / 存档双 Tab,支持密码保护、自定义站点品牌,内置中英双语界面(含分语言站点简介)
- 播放器 - 基于 ArtPlayer,支持 HLS、FLV、MPEG-DASH 播放;支持 AES-128 密钥覆盖及 DASH ClearKey;通过 Shaka Player 支持 Widevine 和 FairPlay DRM 播放(每路播放源可独立配置多 DRM 方案,内置 Android Telegram WebView 检测)
- 管理后台 - 直播的增删改查、启用/禁用、拖拽排序;多播放源管理,支持逐字段标签和代理模式选择
- 观看统计 - 会话追踪、独立访客数、峰值并发、平均时长、设备 / 浏览器 / 操作系统 / 地理分布实时看板,支持 CSV 导出
- Telegram 推送 - 可按直播单独配置,开播 / 关播自动发送通知;多视角直播下每个视角上线都会独立推送,时间窗口内同时开播的视角会合并为一条消息,RTMP 短暂断线重连在宽限期内不会误触发关播 / 开播通知
- 推流配置 - 内置文件浏览器,支持单文件和文件夹 RTMP 推流管理;文件夹可同时向多个推流码批量推送独立任务;推流状态内联显示于文件行,详情弹窗提供实时时长、复制地址和停止操作;同时支持远端编码器 RTMP 推流配置;隐藏 HLS 路由代理(
/h/<slug>),真实推流码不出现在公开地址中 - VOD 点播 / 视频服务 - 带 HMAC 签名的
/video/URL,支持 HTTP Range 请求(可 seek);文件浏览器中可直接将视频文件或文件夹发布为归档直播 - HLS 代理模式 - 每个播放源可选择直连、完整代理或仅代理 Manifest,在源地址暴露、跨域兼容和服务器带宽之间自行取舍;完整代理模式支持上游 Cookie 转发,可对接依赖 Cookie 鉴权的 CDN(如 CloudFront 签名 Cookie),Cookie 仅存于服务端、不会暴露在播放地址中
- API 密钥鉴权 - 在后台生成 Token,可通过 API 密钥对所有管理及统计接口进行程序化访问
- 移动端适配 - 管理后台侧边栏、视角编辑器、文件浏览器行、推流目录侧边栏均可在窄屏设备上自适应折叠
🚀 快速开始
1. 下载并配置
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
启动前请打开
docker-compose.yml,将SECRET_KEY和POSTGRES_PASSWORD改为强随机值。
2. 启动
docker compose up -d
3. 获取初始管理员密码
docker logs streamhall
在日志中找到:
StreamHall initial admin password: <random-password>
4. 访问地址
| 地址 | 说明 |
|---|---|
http://HOST:8085/ |
公开直播列表 |
http://HOST:8085/admin |
管理后台 |
http://HOST:18088/ |
SRS HTTP 播放 |
http://HOST:8889/ |
Nginx HLS 代理 |
Tip
首次登录后,请在网站设置 → 安全设置中修改密码。初始密码仅打印一次,不会以明文形式存储。
更新到新版本
docker compose pull && docker compose up -d
重置忘记的管理员密码
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
删除密码哈希后,StreamHall 在下次启动时会重新生成随机密码并打印到日志中。
💻 本地开发
前置要求: Python 3.12+、PostgreSQL 14+
# 1. 克隆仓库
git clone https://git.stdm.moe/Stardream/StreamHall.git
cd StreamHall
# 2. 安装唯一的运行时依赖
pip install -r requirements.txt
# 3. 配置必要的环境变量
export SECRET_KEY=dev-secret
export DATABASE_URL=postgresql://user:pass@localhost:5432/streamhall
# 4. 启动服务
python server.py
服务默认监听 http://localhost:8080。首次启动时会自动创建数据库结构,并在终端打印一次性管理员密码。
⚙️ 配置项
在 docker-compose.yml 中设置以下环境变量:
| 变量 | 默认值 | 是否必填 | 说明 |
|---|---|---|---|
SECRET_KEY |
REPLACE_ME |
必填 | 会话与推流路由的 HMAC 签名密钥。可用 openssl rand -hex 32 生成 |
DATABASE_URL |
见 compose 文件 | 必填 | PostgreSQL 连接字符串 |
POSTGRES_PASSWORD |
见 compose 文件 | 必填 | PostgreSQL 数据库密码 |
TZ |
UTC |
否 | 容器时区,如 Asia/Shanghai |
SRS_HTTP_ORIGIN |
http://srs:8080 |
否 | SRS HTTP 播放基础地址 |
STREAM_PROBE_TIMEOUT |
4 |
否 | 流地址探测超时秒数 |
HLS_PROXY_TIMEOUT |
15 |
否 | 上游 HLS manifest / 分片代理请求超时秒数 |
STREAM_MONITOR_INTERVAL |
10 |
否 | 流存活检测间隔秒数 |
TELEGRAM_TIMEOUT |
6 |
否 | Telegram API 请求超时秒数 |
TG_RECONNECT_GRACE_SECS |
60 |
否 | 发送关播通知前的宽限期,用于吸收短暂 RTMP 重连(0 关闭) |
TG_START_MERGE_SECS |
30 |
否 | 合并同时上线视角为一条开播通知的时间窗口(0 关闭) |
RTMP_HOST |
srs |
否 | 本地推流任务使用的 SRS 容器主机名 |
VIDEOS_DIRS |
(未设置) | 否 | 文件浏览器暴露的目录,逗号分隔。可为每个路径加标签前缀:label:/app/path。多个示例:movies:/app/movies,shows:/app/shows |
Warning
在将 StreamHall 暴露到网络前,务必修改
SECRET_KEY和POSTGRES_PASSWORD。默认值仅为占位符,安全性极低。
挂载本地推流视频目录
方式一 - 单一基路径,多个来源作为子目录:
将多个宿主机路径挂载到同一容器基路径的子目录下,文件浏览器中以子文件夹形式展示。
environment:
VIDEOS_DIRS: "/app/videos"
volumes:
- ./videos:/app/videos/local
- /your/media/path:/app/videos/external
方式二 - 多个带标签的顶级目录:
每个路径在文件浏览器中作为独立的顶级条目显示。
environment:
VIDEOS_DIRS: "/app/videos,external:/app/media/external"
volumes:
- ./videos:/app/videos
- /your/media/path:/app/media/external
HLS 代理模式
每个播放源都可以选择外部 HLS 链接如何暴露给观众:
| 模式 | 行为 | 带宽影响 |
|---|---|---|
自动 |
向后兼容默认行为;外部 HLS 使用完整代理 | StreamHall 承担 manifest 和分片流量 |
直连 |
播放器直接使用源站 URL | 观众流量走源服务器 |
完整代理 |
manifest、分片、map、key 都通过 /proxy/hls/ |
StreamHall 承担全部 HLS 媒体流量 |
仅 Manifest |
只有播放列表经过 StreamHall;分片、key、map 改写为源站绝对地址 | StreamHall 带宽较低;最终媒体 URL 仍会出现在浏览器网络请求中 |
完整代理模式下,播放源还可以设置上游 Cookie,用于对接依赖 Cookie 鉴权的 CDN(如 CloudFront 签名 Cookie)。StreamHall 会在每次 manifest 和分片请求时附带该 Cookie。Cookie 仅存于服务端,并以签名后的不可逆 token 形式嵌入代理地址,因此无法从播放或分片 URL 中还原出来。上游代理请求会复用连接池中的持久 HTTP 连接,避免每次请求都重新进行 TLS 握手。
🐳 服务说明
默认 compose 配置启动四个容器:
| 容器名 | 镜像 | 端口 | 用途 |
|---|---|---|---|
streamhall |
本地构建 | 8085→8080 |
Python 应用 + 静态前端 |
streamhall-postgres |
postgres:16-alpine |
- | PostgreSQL 持久化数据库 |
streamhall-srs |
ossrs/srs:6 |
1935、18088→8080 |
RTMP 推流 + HTTP 播放 |
streamhall-nginx-hls |
nginx:alpine |
8889→80 |
HLS 公开路由代理 |
持久化数据存储在 ./postgres-data/ 目录下。
🔌 推流配置
SRS 在 1935 端口接收 RTMP 推流,推流端配置示例:
RTMP 服务器: rtmp://HOST:1935/live
推流码: your-stream-key
管理后台的本地推流页面提供媒体目录文件浏览器。选择单个视频文件可使用自定义推流码发起 RTMP 推流;选择文件夹可同时为其中所有视频分别分配独立推流码并批量启动。每个文件行内联显示推流状态,点击"编辑推流"可查看实时时长、复制推流/播放地址和停止操作。
隐藏公开 HLS 地址(/h/<slug>/...)通过 Nginx 在 8889 端口对外提供访问,真实推流码不会出现在公开 URL 中。
Note
RTMP 主机字段支持填写自定义端口,如
live.example.com:1935。若使用非标准端口,请勿将:1935硬编码到地址中。
📡 API 文档
鉴权方式
- 浏览器会话 - 通过
POST /api?action=login登录后设置的 Cookie - API 密钥 - 在请求头携带
Authorization: Bearer <token>。密钥在后台网站设置 → API 密钥处管理。
公开接口
| 方法 | 接口 | 说明 |
|---|---|---|
GET |
/api?action=public_list |
首页直播列表 |
GET |
/api?action=site_settings |
站点标题、简介、品牌设置 |
GET |
/api?action=get_player_data&id=<public_id> |
播放器播放源及元数据 |
POST |
/api?action=verify_password |
验证直播访问密码 |
GET |
/video/<token>/<payload> |
签名 VOD 点播端点,支持 HTTP Range |
管理接口(需鉴权)
| 方法 | 接口 | 说明 |
|---|---|---|
POST |
/api?action=login |
登录并创建会话 |
GET |
/api?action=logout |
退出当前会话 |
GET |
/api?action=list_admin |
完整直播列表 |
POST |
/api?action=add |
添加直播 |
POST |
/api?action=update |
修改直播 |
POST |
/api?action=delete |
删除直播 |
POST |
/api?action=set_stream_enabled |
切换直播可见状态 |
POST |
/api?action=reorder_streams |
调整同分组内排序 |
POST |
/api?action=update_site_settings |
保存网站设置 |
GET |
/api?action=telegram_settings |
读取 Telegram Bot 配置 |
POST |
/api?action=update_telegram_settings |
保存 Telegram Bot 配置 |
POST |
/api?action=update_admin_password |
修改管理员密码 |
GET |
/api?action=list_api_keys |
列出所有 API 密钥(不返回 Token 明文) |
POST |
/api?action=create_api_key |
创建密钥(Token 仅返回一次) |
POST |
/api?action=delete_api_key |
按 id 撤销密钥 |
GET |
/api?action=list_pushes |
列出当前活跃推流任务 |
POST |
/api?action=start_push |
为指定文件启动 RTMP 推流任务 |
POST |
/api?action=stop_push |
按推流码停止推流任务 |
GET |
/api?action=list_folder_videos |
列出目录内可播放文件及签名 URL |
统计接口(需鉴权)
| 方法 | 接口 | 说明 |
|---|---|---|
GET |
/api?action=stats_overview |
汇总数据 |
GET |
/api?action=stats_streams |
各直播统计明细 |
GET |
/api?action=stats_timeseries |
分桶观看趋势 |
GET |
/api?action=stats_geo |
地理分布(国家级) |
GET |
/api?action=stats_stream_detail&id=<id> |
单场直播详情 |
GET |
/api?action=stats_sessions_page&id=<id> |
分页会话列表 |
GET |
/api?action=stats_export_csv&range=<range> |
导出会话 CSV(range:today、7d、30d(默认)、all) |
💡 致谢
StreamHall 参照 AniLive 网站进行重构,该网站提供直播列表功能但未开源。本项目为独立重写实现,与原网站不共享任何代码。
🤝 参与贡献
欢迎提交 Issue 和 Pull Request。较大的改动请先开 Issue 讨论方向。
📝 许可证
版权所有 © 2026 Stardream。本项目基于 GNU Affero General Public License v3.0 协议开源。
授权权限
| ✅ | 商业使用 |
| ✅ | 修改源代码 |
| ✅ | 分发 |
| ✅ | 私人使用 |
使用条件
| ⚠️ | 开放源码 - 修改后的版本同样必须开源 |
| ⚠️ | 相同许可证 - 衍生作品须采用 AGPL-3.0 协议 |
| ⚠️ | 网络使用视同分发 - 若将修改版作为网络服务运行,须向用户提供完整源码 |
| ⚠️ | 说明修改内容 - 需记录对源码的修改 |
简而言之:你可以自由使用、修改和自部署 StreamHall。但若将修改版对外分发或作为托管服务提供,须以 AGPL-3.0 协议公开完整源码。