基于最新版LunaTV二次开发的一个开箱即用的、跨平台的影视聚合播放站。【原KatelyaTV】
See the code
🎬 DecoTV 是一个开箱即用的、跨平台的影视聚合播放器。它基于 Next.js 16 + Tailwind CSS 4 + TypeScript 5 构建,支持多资源搜索、在线播放、收藏同步、播放记录、云端存储,让你可以随时随地畅享海量免费影视内容。支持本地无数据库模式、CMS 全量代理、隐私纵深防御等企业级特性。
明亮模式 |
暗夜模式 |
注意:部署后项目为空壳项目,无内置播放源和直播源,需要自行收集配置。
免责声明:请不要在 B 站、小红书、微信公众号、抖音、今日头条或其他中国大陆社交平台发布视频或文章宣传本项目,不授权任何"科技周刊/月刊"类项目或站点收录本项目。
| 分类 | 主要依赖 |
|---|---|
| 前端框架 | Next.js 16 · App Router · Turbopack |
| UI & 样式 | Tailwind CSS 4 |
| 语言 | TypeScript 5 |
| 播放器 | ArtPlayer · HLS.js |
| 代码质量 | ESLint 9 · Prettier 3 · Jest 29 |
| 部署 | Docker |
本项目仅支持 Docker 或其他基于 Docker 的平台 部署。
如果你计划运行在 OpenWrt(软路由 / ARM 盒子 / 树莓派等)设备上,参阅完整指南:
快速拉取预构建镜像:
docker pull ghcr.io/decohererk/decotv:latest
若需在外部主机自行构建后再导入至 OpenWrt,请参考指南中的 “获取或构建镜像” 与 “导出并传输” 步骤。
DecoTV 提供以下 Docker 镜像标签:
| 标签 | 说明 | 使用场景 |
|---|---|---|
latest | 最新构建版本 | 总是使用最新代码,包含所有小更新 |
v1.0.0 | 特定版本号 | 固定版本部署,便于版本管理和回滚 |
推荐使用方式:
# 方式1:使用 latest 标签(自动获取最新更新)
docker pull ghcr.io/decohererk/decotv:latest
# 方式2:使用特定版本号(生产环境推荐)
docker pull ghcr.io/decohererk/decotv:v1.0.0
# 方式3:回滚到旧版本
docker pull ghcr.io/decohererk/decotv:v0.9.0
版本号标签优势:
注意:使用
latest标签时,重启容器不会自动拉取新镜像,需要手动执行docker pull才能获取更新。使用版本号标签可以明确控制何时更新。
DecoTV 支持直接通过 Docker 端口映射在局域网 HTTP 地址访问,例如 http://192.168.1.10:3000。这种场景下登录 Cookie 不会设置 Secure 属性,浏览器可以正常保存认证状态。
公网部署强烈建议使用 HTTPS。若前面有 Nginx/OpenResty 等反向代理,请确保把外部访问协议传给 DecoTV:
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
DecoTV 会根据请求 URL、X-Forwarded-Proto、X-Forwarded-Host 或标准 Forwarded 头判断实际协议和外部访问域名。使用 https://域名:非443端口 反代时,务必传递带端口的 $http_host,否则浏览器后续请求 m3u8 代理地址时会丢端口。HTTPS 访问会设置 Secure Cookie;HTTP 局域网直连和 HTTP 反代不会设置 Secure Cookie。不要仅依赖容器内的 NODE_ENV=production 判断访问协议。
services:
decotv-core:
image: ghcr.io/decohererk/decotv:latest # 或使用 :v1.0.0 固定版本
container_name: decotv-core
restart: on-failure
ports:
- '3000:3000'
environment:
- USERNAME=admin
- PASSWORD=admin_password
- NEXT_PUBLIC_STORAGE_TYPE=kvrocks
- KVROCKS_URL=redis://decotv-kvrocks:6666
networks:
- decotv-network
depends_on:
- decotv-kvrocks
decotv-kvrocks:
image: apache/kvrocks
container_name: decotv-kvrocks
restart: unless-stopped
volumes:
- kvrocks-data:/var/lib/kvrocks
networks:
- decotv-network
networks:
decotv-network:
driver: bridge
volumes:
kvrocks-data:
services:
decotv-core:
image: ghcr.io/decohererk/decotv:latest # 或使用 :v1.0.0 固定版本
container_name: decotv-core
restart: on-failure
ports:
- '3000:3000'
environment:
- USERNAME=admin
- PASSWORD=admin_password
- NEXT_PUBLIC_STORAGE_TYPE=redis
- REDIS_URL=redis://decotv-redis:6379
networks:
- decotv-network
depends_on:
- decotv-redis
decotv-redis:
image: redis:alpine
container_name: decotv-redis
restart: unless-stopped
networks:
- decotv-network
# 请开启持久化,否则升级/重启后数据丢失
volumes:
- ./data:/data
networks:
decotv-network:
driver: bridge
services:
decotv-core:
image: ghcr.io/decohererk/decotv:latest # 或使用 :v1.0.0 固定版本
container_name: decotv-core
restart: on-failure
ports:
- '3000:3000'
environment:
- USERNAME=admin
- PASSWORD=admin_password
- NEXT_PUBLIC_STORAGE_TYPE=upstash
- UPSTASH_URL=上面 https 开头的 HTTPS ENDPOINT
- UPSTASH_TOKEN=上面的 TOKEN
如果你只是想快速体验或单机使用,不需要多端同步功能,可以使用本地存储模式。此模式下数据保存在浏览器的 localStorage 中,无需任何外部数据库。
docker run -d \
--name decotv \
-p 3000:3000 \
-v decotv-downloads:/app/.cache/ffmpeg-downloads \
-e PASSWORD=你的管理密码 \
ghcr.io/decohererk/decotv:latest
services:
decotv:
image: ghcr.io/decohererk/decotv:latest
container_name: decotv
restart: unless-stopped
ports:
- '3000:3000'
environment:
- PASSWORD=你的管理密码
volumes:
- decotv-downloads:/app/.cache/ffmpeg-downloads
volumes:
decotv-downloads:
| 项目 | 说明 |
|---|---|
| ✅ 必需配置 | PASSWORD - 管理员登录密码 |
| ❌ 不需要 | USERNAME、NEXT_PUBLIC_STORAGE_TYPE、任何数据库连接变量 |
| ❌ 不需要 | AUTH_SECRET、AUTH_URL(这些是其他认证框架的配置,DecoTV 不使用) |
| ⚠️ 数据存储 | 所有配置保存在浏览器 localStorage,清除浏览器数据会丢失配置 |
| ⚠️ 多端同步 | 不支持,每个浏览器独立存储 |
| ⬇️ 下载缓存 | 建议挂载 /app/.cache/ffmpeg-downloads,避免容器重建时丢失已转存文件 |
默认仍为 NEXT_PUBLIC_AUTH_MODE=password,需要登录后使用。家庭局域网、NAS、电视盒子、OpenWrt、飞牛 OS 等完全可信内网场景,可以显式开启免登录:
docker run -d \
--name decotv \
-p 3000:3000 \
-e NEXT_PUBLIC_AUTH_MODE=public \
-v decotv-downloads:/app/.cache/ffmpeg-downloads \
ghcr.io/decohererk/decotv:latest
Docker Compose 示例:
services:
decotv:
image: ghcr.io/decohererk/decotv:latest
container_name: decotv
restart: unless-stopped
ports:
- '3000:3000'
environment:
- NEXT_PUBLIC_AUTH_MODE=public
volumes:
- decotv-downloads:/app/.cache/ffmpeg-downloads
volumes:
decotv-downloads:
⚠️
NEXT_PUBLIC_AUTH_MODE=public仅建议局域网、NAS、家庭内网、VPN、自用环境开启,不建议公网暴露。/admin和/api/admin/*默认仍需要登录保护;只有同时设置PUBLIC_ALLOW_ADMIN=true才会免登录开放后台和后台 API,该开关风险极高,仅适合完全可信内网。
Q: 登录成功后操作仍提示 401 Unauthorized?
这可能是以下原因:
REDIS_URL、KV_REST_API_URL 等数据库变量X-Forwarded-Proto $scheme,否则应用可能无法按外部访问协议设置 Cookielatest 镜像重启不会自动拉取新版本,升级前需要先执行 docker pull ghcr.io/decohererk/decotv:latestQ: 如何从本地模式迁移到数据库模式?
由于本地模式数据存储在浏览器中,无法直接迁移。建议:
完成部署后为空壳应用,无播放源,需要站长在管理后台的配置文件设置中填写配置文件(后续会支持订阅)
配置文件示例如下:
{
"cache_time": 7200,
"api_site": {
"dyttzy": {
"api": "http://xxx.com/api.php/provide/vod",
"name": "示例资源",
"detail": "http://xxx.com"
}
// ...更多站点
},
"custom_category": [
{
"name": "华语",
"type": "movie",
"query": "华语"
}
]
}
cache_time:接口缓存时间(秒)。api_site:你可以增删或替换任何资源站,字段说明:
key:唯一标识,保持小写字母/数字。api:资源站提供的 vod JSON API 根地址。name:在人机界面中展示的名称。detail:(可选)部分无法通过 API 获取剧集详情的站点,需要提供网页详情根 URL,用于爬取。custom_category:自定义分类配置,用于在导航中添加个性化的影视分类。以 type + query 作为唯一标识。支持以下字段:
name:分类显示名称(可选,如不提供则使用 query 作为显示名)type:分类类型,支持 movie(电影)或 tv(电视剧)query:搜索关键词,用于在豆瓣 API 中搜索相关内容custom_category 支持的自定义分类已知如下:
也可输入如 "哈利波特" 效果等同于豆瓣搜索
DecoTV 支持标准的苹果 CMS V10 API 格式。
可借助 watchtower 自动更新镜像容器
dockge/komodo 等 docker compose UI 也有自动更新功能
| 变量 | 说明 | 可选值 | 默认值 |
|---|---|---|---|
| USERNAME | 管理员账号 | 任意字符串 | 无默认,数据库模式必填,本地模式可省略 |
| PASSWORD | 管理员密码 | 任意字符串 | 无默认,必填 |
| NEXT_PUBLIC_AUTH_MODE | 访问模式 | password、public | password |
| PUBLIC_ALLOW_ADMIN | public 模式下是否开放后台 | true/false | false |
| SITE_BASE | 站点 URL | 形如 https://example.com | 空 |
| NEXT_PUBLIC_SITE_NAME | 站点名称 | 任意字符串 | DecoTV |
| ANNOUNCEMENT | 站点公告 | 任意字符串 | 本网站仅提供影视信息搜索服务,所有内容均来自第三方网站。本站不存储任何视频资源,不对任何内容的准确性、合法性、完整性负责。 |
| 变量 | 说明 | 可选值 | 默认值 | 备注 |
|---|---|---|---|---|
| NEXT_PUBLIC_STORAGE_TYPE | 存储类型 | localstorage、redis、kvrocks、upstash | localstorage | 不填则默认本地模式,数据存浏览器中 |
| KVROCKS_URL | Kvrocks 数据库连接地址 | redis://host:port | 空 | 当 STORAGE_TYPE=kvrocks 时必填 |
| REDIS_URL | Redis 数据库连接地址 | redis://host:port | 空 | 当 STORAGE_TYPE=redis 时必填 |
| UPSTASH_URL | Upstash Redis REST URL | https://xxx.upstash.io | 空 | 当 STORAGE_TYPE=upstash 时必填 |
| UPSTASH_TOKEN | Upstash Redis REST 令牌 | AUxxxx... | 空 | 当 STORAGE_TYPE=upstash 时必填 |
注意:Upstash 使用 REST API 连接,需要填写
UPSTASH_URL(HTTPS ENDPOINT)和UPSTASH_TOKEN,不是传统的 Redis 连接字符串。
注册需要先配置 redis、upstash 或 kvrocks 存储。部署后由站长在 /admin -> 用户配置 -> 公开注册 中直接控制开关和新用户默认用户组,无需为日常启停重新部署。
| 变量 | 说明 | 可选值 | 默认值 | 备注 |
|---|---|---|---|---|
| NEXT_PUBLIC_ENABLE_REGISTRATION | 旧配置迁移时的初始注册状态 | true/false | false | 后续以管理面板保存的设置为准 |
| DEFAULT_REGISTRATION_GROUP | 旧配置迁移时的初始默认用户组 | 用户组名称 | 空 | 后续在管理面板选择已创建的用户组 |
安全提示:公开注册默认关闭;不设置默认用户组时,新账号默认可使用全部可用视频源。详见 用户注册功能说明
| 变量 | 说明 | 可选值 | 默认值 | 备注 |
|---|---|---|---|---|
| NEXT_PUBLIC_SEARCH_MAX_PAGE | 搜索接口可拉取的最大页数 | 1-50 | 5 | 数值越大越慢 |
| NEXT_PUBLIC_DOUBAN_PROXY_TYPE | 豆瓣数据源请求方式 | 见下方说明 | auto | - |
| NEXT_PUBLIC_DOUBAN_PROXY | 自定义豆瓣数据代理 URL | URL prefix | 空 | custom 模式使用 |
| NEXT_PUBLIC_DOUBAN_IMAGE_PROXY_TYPE | 豆瓣图片代理类型 | 见下方说明 | auto | - |
| NEXT_PUBLIC_DOUBAN_IMAGE_PROXY | 自定义豆瓣图片代理 URL | URL prefix | 空 | custom 模式使用 |
| NEXT_PUBLIC_DISABLE_YELLOW_FILTER | 关闭色情内容过滤 | true/false | false | 不建议开启 |
| NEXT_PUBLIC_FLUID_SEARCH | 是否开启搜索接口流式输出 | true/false | true | - |
| 值 | 说明 |
|---|---|
| auto | 智能自动(默认),服务端按成功率和延迟在多个 provider 间自动降级 |
| direct | 服务器直接请求豆瓣源站 |
| server | 兼容值,等同于服务端智能代理 |
| cors-proxy-zwei | 服务端通过 Zwei 提供的 CORS Proxy 请求豆瓣数据 |
| cmliussss-cdn-tencent | 服务端通过 CMLiussss 提供的腾讯云 CDN 加速请求豆瓣数据 |
| cmliussss-cdn-ali | 服务端通过 CMLiussss 提供的阿里云 CDN 加速请求豆瓣数据 |
| custom | 使用自定义代理(需配置 NEXT_PUBLIC_DOUBAN_PROXY) |
| 值 | 说明 |
|---|---|
| auto | 智能自动(默认),按候选链路逐级重试 |
| direct | 浏览器直接请求豆瓣图片域名 |
| server | 服务器代理请求豆瓣图片 |
| img3 | 使用豆瓣官方精品 CDN(阿里云) |
| cmliussss-cdn-tencent | 使用 CMLiussss 提供的腾讯云 CDN |
| cmliussss-cdn-ali | 使用 CMLiussss 提供的阿里云 CDN |
| custom | 使用自定义代理(需配置 NEXT_PUBLIC_DOUBAN_IMAGE_PROXY) |
auto 模式下,豆瓣数据请求统一走服务端 /api/douban/*:优先使用最近成功且延迟较低的 provider,单个 provider 超时、403/429/5xx、返回 HTML 或非 JSON 时,会记录失败原因并短期负缓存,然后自动尝试下一个 provider。API 成功响应会带 X-DecoTV-Douban-Provider 与 X-DecoTV-Douban-Duration,失败响应会带 providerAttempts 便于排查。
豆瓣封面图片在浏览器端按候选链路重试:用户选择的代理 → 上次 auto 成功节点 → img3.doubanio.com → CMLiussss 阿里云 CDN → CMLiussss 腾讯云 CDN → /api/image-proxy 服务器代理 → 豆瓣原图直连 → poster-fallback.svg。本地设置或后台配置变更后会触发 doubanProxyChanged,只清理豆瓣相关缓存。
DecoTV 接入 弹弹play开放平台 提供的弹幕库。按照开放平台文档,应用取得的 AppId 与 AppSecret 需要妥善保管且不得泄露给他人。为避免将共享凭证写入公开代码或镜像,项目提供服务端中继用于部分公开部署场景。
| 部署方式 | 默认行为 |
|---|---|
| Vercel 等非 Docker Web 部署 | 未配置自有凭证时,通过项目公共中继 https://tv.katelya.eu.org 加载弹弹play官方弹幕 |
| 官方 Docker 镜像 | 不自动接入项目公共中继;可使用后台第三方弹幕节点,或配置自行申请的弹弹play凭证 |
已配置 DANDANPLAY_APP_* 的部署 | 优先在本部署服务端直连弹弹play开放平台 |
| 后台启用了第三方自定义弹幕节点 | 优先使用该第三方节点 |
当视频数据包含 TMDB ID 时,自动匹配会优先使用开放平台的 tmdbId + episode 查询,失败时再按标题回退;获取弹幕使用 withRelated=true 汇集关联来源。弹幕与搜索结果会在服务端/CDN 缓存,减少对开放平台的重复请求。
https://tv.katelya.eu.org 提供弹弹play官方弹幕的公共中继能力。中继服务在服务端完成开放平台认证,下游部署和浏览器不会获得项目使用的 AppSecret。
公共中继主要用于简化 Vercel 等 Web 平台的部署体验。由于公共服务存在可用容量、异常调用检测及平台额度约束,服务可能按实际运行情况进行限流或临时暂停,不保证作为专用弹幕后端长期无限制使用。
需要独立可用性、希望脱离公共中继运行的部署,可在 弹弹play DevCenter 申请凭证,并仅在自己的服务端环境变量中配置:
DANDANPLAY_APP_ID=在DevCenter申请的AppId
DANDANPLAY_APP_SECRET=有效AppSecret
Vercel 部署应将 DANDANPLAY_APP_SECRET 保存为 Sensitive Environment Variable,并在保存后重新部署。Docker 部署应从未提交到 Git 的运行时环境文件注入凭证,例如:
docker run --env-file .env.docker.local -p 3000:3000 decotv
公开 Docker 镜像不会内置共享 AppSecret,也不会默认请求项目公共中继。镜像持有者能够检查镜像内容和运行环境,因此将共享密钥打包进公开镜像无法保证凭证安全。
希望为 Docker 实例统一提供官方弹幕的用户,可以在自己控制的服务器上部署 DecoTV 中继,并为容器指定中继地址:
DANDANPLAY_RELAY_URL=https://your-relay.example.com
Vercel 或其他源码部署也可以使用 DANDANPLAY_RELAY_URL 覆盖默认中继;设为 disabled 时完全禁用中继回退。
不要将真实密钥提交到仓库、写入 NEXT_PUBLIC_* 环境变量、打包进公开镜像或提供给前端生成签名。弹弹play文档说明开放平台将在 2026 年 6 月 25 日 起启用应用分层与额度管理机制;自行部署的中继服务应开启缓存,并根据流量情况配置限流策略。
感谢 弹弹play 为 DecoTV 提供弹幕服务支持!
DecoTV 的网盘搜索采用远程 PanSou 节点转发模式。推荐先部署 fish2018/pansou,确认服务可访问后,在后台 PanSou 配置 中填入服务地址(可选填写 Token)。
快速示例:
https://your-pansou-domain/api/health 可访问。PanSou 配置 页面。https://your-pansou-domain)。如果 PanSou 开启 AUTH_ENABLED=true,可以直接填写 PanSou 用户名/密码,DecoTV 会自动登录换取 JWT;也可以在 API Token / 鉴权密钥 中直接填 JWT,支持填 Bearer xxx 或裸 token。DecoTV 支持把 TMDB 作为与豆瓣互补的第二元数据来源,尤其适合欧美 / 日韩内容和私人影库场景。
快速使用:
TMDB 配置 中填写 TMDB_API_KEY。TMDB_PROXY 或 TMDB_REVERSE_PROXY。TMDB 连通性测试,保存后即可生效。使用建议:
{tmdb-xxxx} 或 Emby / Jellyfin 的 ProviderIds.Tmdb 可以直接命中精准元数据。TMDB_API_KEY,项目会自动降级,不影响原有豆瓣链路和公共资源站播放。DecoTV 支持在后台接入 OpenList、小雅 Alist、Emby、Jellyfin 等私有媒体服务,配置成功后前台会自动显示“我的影库”入口。
OpenList 快速使用:
电影:流浪地球2 (2023) {tmdb-835547}/流浪地球2.mkv
剧集:三体 (2023) {tmdb-1428232}/Season 01/S01E01.mkv
私人影库 配置区块,添加连接并选择 OpenList。小雅 Alist 快速使用:
/。私人影库 配置区块,添加连接并选择 小雅 Alist。/电影。.strm 文件时,服务端会实时刷新阿里云盘直链。Emby / Jellyfin 快速使用:
Emby 或 Jellyfin 连接,填写服务地址、API Key,可选填写用户 ID 和媒体库过滤。补充说明:
/Media,小雅 Alist 默认根目录为 /。AudioStreamIndex 重新加载流并恢复切换前进度;HLS 资源支持无中断音轨切换。下载当前集。FFmpeg 转存下载。ffmpeg/ffprobe,VPS Docker 部署可直接使用。ffmpeg 和 ffprobe。/app/.cache/ffmpeg-downloads,用于保存服务端转存的临时成品文件。FFMPEG_PATH:自定义 ffmpeg 可执行路径。FFPROBE_PATH:自定义 ffprobe 可执行路径。FFMPEG_DOWNLOAD_DIR:服务端转存文件目录。FFMPEG_ALLOW_SERVERLESS=true:仅在你明确具备可执行二进制能力时使用。VPS Docker 持久化示例:
services:
decotv:
image: ghcr.io/decohererk/decotv:latest
ports:
- '3000:3000'
environment:
- PASSWORD=你的管理密码
- FFMPEG_MAX_CONCURRENT_JOBS=2
volumes:
- decotv-downloads:/app/.cache/ffmpeg-downloads
volumes:
decotv-downloads:
如果使用宿主机目录绑定,例如 ./downloads:/app/.cache/ffmpeg-downloads,请确保目录允许容器内 UID 1001 写入:
mkdir -p ./downloads
sudo chown -R 1001:1001 ./downloads
拉取播放列表失败 (502):通常是上游 m3u8 源需要特定 Referer/Origin,请确认源可访问,或切换其他源重试。FFmpeg API request failed (500/501):检查部署环境是否安装 FFmpeg;官方 Docker 镜像应开箱可用,自建镜像请确认 Dockerfile 包含 FFmpeg。EACCES / permission denied:转存目录不可写;使用上方 named volume,或修正宿主机目录权限。FFMPEG_JOB_RETENTION_MS,必要时降低 FFMPEG_MAX_CONCURRENT_JOBS。目前该项目可以配合 OrionTV 在 Android TV 上使用,可以直接作为 OrionTV 后端
已实现播放记录和网页端同步
详细配置指南:
OrionTV 成人内容过滤快速配置:
API 地址: https://your-domain.com/
✅ 自动过滤成人资源源和敏感关键词
API 地址: https://your-domain.com/adult/
✅ 显示所有内容(包括成人资源)
💡 工作原理:
- 路径前缀
/adult/会被自动识别并重写- 例如:
/adult/api/search→/api/search?adult=1- OrionTV 无需额外配置,开箱即用
注意: 此方式仅适用于 Web 端,OrionTV 可能不支持
API 地址: https://your-domain.com
API 地址: https://your-domain.com?adult=1
详细说明请参阅 成人内容过滤使用指南
具体可见 TVBox 配置优化说明 ,详细功能见/admin 管理页面 TVbox 配置
DecoTV 支持用户自助注册功能(可选),适合需要允许用户自行创建账号的场景。
功能特性:
详细使用指南:用户注册功能说明
快速启用:
# 先设置支持多用户的存储
NEXT_PUBLIC_STORAGE_TYPE=redis # 或 upstash、kvrocks
部署完成后,以站长账号进入 /admin 的“用户配置”,选择新用户默认用户组后打开“允许访客自行注册账号”。
⚠️ 安全提示:建议默认关闭注册,仅在需要时临时开启,注册完成后在后台立即关闭。
为了您的安全和避免潜在的法律风险,我们要求在部署时强烈建议关闭公网注册:
PASSWORD:为您的实例设置一个强密码MIT © 2025 DecoTV & Contributors
如果这个项目对你有所帮助,欢迎 Star ⭐ 本项目或请作者喝杯咖啡 ☕
🎨 微信赞赏 |
🌟 如果觉得项目有用,请点个 Star 支持一下!🌟
Made with ❤️ by Decohererk and Contributors
基于最新版LunaTV二次开发的一个开箱即用的、跨平台的影视聚合播放站。【原KatelyaTV】
See the code
🎬 DecoTV 是一个开箱即用的、跨平台的影视聚合播放器。它基于 Next.js 16 + Tailwind CSS 4 + TypeScript 5 构建,支持多资源搜索、在线播放、收藏同步、播放记录、云端存储,让你可以随时随地畅享海量免费影视内容。支持本地无数据库模式、CMS 全量代理、隐私纵深防御等企业级特性。
明亮模式 |
暗夜模式 |
注意:部署后项目为空壳项目,无内置播放源和直播源,需要自行收集配置。
免责声明:请不要在 B 站、小红书、微信公众号、抖音、今日头条或其他中国大陆社交平台发布视频或文章宣传本项目,不授权任何"科技周刊/月刊"类项目或站点收录本项目。
| 分类 | 主要依赖 |
|---|---|
| 前端框架 | Next.js 16 · App Router · Turbopack |
| UI & 样式 | Tailwind CSS 4 |
| 语言 | TypeScript 5 |
| 播放器 | ArtPlayer · HLS.js |
| 代码质量 | ESLint 9 · Prettier 3 · Jest 29 |
| 部署 | Docker |
本项目仅支持 Docker 或其他基于 Docker 的平台 部署。
如果你计划运行在 OpenWrt(软路由 / ARM 盒子 / 树莓派等)设备上,参阅完整指南:
快速拉取预构建镜像:
docker pull ghcr.io/decohererk/decotv:latest
若需在外部主机自行构建后再导入至 OpenWrt,请参考指南中的 “获取或构建镜像” 与 “导出并传输” 步骤。
DecoTV 提供以下 Docker 镜像标签:
| 标签 | 说明 | 使用场景 |
|---|---|---|
latest | 最新构建版本 | 总是使用最新代码,包含所有小更新 |
v1.0.0 | 特定版本号 | 固定版本部署,便于版本管理和回滚 |
推荐使用方式:
# 方式1:使用 latest 标签(自动获取最新更新)
docker pull ghcr.io/decohererk/decotv:latest
# 方式2:使用特定版本号(生产环境推荐)
docker pull ghcr.io/decohererk/decotv:v1.0.0
# 方式3:回滚到旧版本
docker pull ghcr.io/decohererk/decotv:v0.9.0
版本号标签优势:
注意:使用
latest标签时,重启容器不会自动拉取新镜像,需要手动执行docker pull才能获取更新。使用版本号标签可以明确控制何时更新。
DecoTV 支持直接通过 Docker 端口映射在局域网 HTTP 地址访问,例如 http://192.168.1.10:3000。这种场景下登录 Cookie 不会设置 Secure 属性,浏览器可以正常保存认证状态。
公网部署强烈建议使用 HTTPS。若前面有 Nginx/OpenResty 等反向代理,请确保把外部访问协议传给 DecoTV:
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
DecoTV 会根据请求 URL、X-Forwarded-Proto、X-Forwarded-Host 或标准 Forwarded 头判断实际协议和外部访问域名。使用 https://域名:非443端口 反代时,务必传递带端口的 $http_host,否则浏览器后续请求 m3u8 代理地址时会丢端口。HTTPS 访问会设置 Secure Cookie;HTTP 局域网直连和 HTTP 反代不会设置 Secure Cookie。不要仅依赖容器内的 NODE_ENV=production 判断访问协议。
services:
decotv-core:
image: ghcr.io/decohererk/decotv:latest # 或使用 :v1.0.0 固定版本
container_name: decotv-core
restart: on-failure
ports:
- '3000:3000'
environment:
- USERNAME=admin
- PASSWORD=admin_password
- NEXT_PUBLIC_STORAGE_TYPE=kvrocks
- KVROCKS_URL=redis://decotv-kvrocks:6666
networks:
- decotv-network
depends_on:
- decotv-kvrocks
decotv-kvrocks:
image: apache/kvrocks
container_name: decotv-kvrocks
restart: unless-stopped
volumes:
- kvrocks-data:/var/lib/kvrocks
networks:
- decotv-network
networks:
decotv-network:
driver: bridge
volumes:
kvrocks-data:
services:
decotv-core:
image: ghcr.io/decohererk/decotv:latest # 或使用 :v1.0.0 固定版本
container_name: decotv-core
restart: on-failure
ports:
- '3000:3000'
environment:
- USERNAME=admin
- PASSWORD=admin_password
- NEXT_PUBLIC_STORAGE_TYPE=redis
- REDIS_URL=redis://decotv-redis:6379
networks:
- decotv-network
depends_on:
- decotv-redis
decotv-redis:
image: redis:alpine
container_name: decotv-redis
restart: unless-stopped
networks:
- decotv-network
# 请开启持久化,否则升级/重启后数据丢失
volumes:
- ./data:/data
networks:
decotv-network:
driver: bridge
services:
decotv-core:
image: ghcr.io/decohererk/decotv:latest # 或使用 :v1.0.0 固定版本
container_name: decotv-core
restart: on-failure
ports:
- '3000:3000'
environment:
- USERNAME=admin
- PASSWORD=admin_password
- NEXT_PUBLIC_STORAGE_TYPE=upstash
- UPSTASH_URL=上面 https 开头的 HTTPS ENDPOINT
- UPSTASH_TOKEN=上面的 TOKEN
如果你只是想快速体验或单机使用,不需要多端同步功能,可以使用本地存储模式。此模式下数据保存在浏览器的 localStorage 中,无需任何外部数据库。
docker run -d \
--name decotv \
-p 3000:3000 \
-v decotv-downloads:/app/.cache/ffmpeg-downloads \
-e PASSWORD=你的管理密码 \
ghcr.io/decohererk/decotv:latest
services:
decotv:
image: ghcr.io/decohererk/decotv:latest
container_name: decotv
restart: unless-stopped
ports:
- '3000:3000'
environment:
- PASSWORD=你的管理密码
volumes:
- decotv-downloads:/app/.cache/ffmpeg-downloads
volumes:
decotv-downloads:
| 项目 | 说明 |
|---|---|
| ✅ 必需配置 | PASSWORD - 管理员登录密码 |
| ❌ 不需要 | USERNAME、NEXT_PUBLIC_STORAGE_TYPE、任何数据库连接变量 |
| ❌ 不需要 | AUTH_SECRET、AUTH_URL(这些是其他认证框架的配置,DecoTV 不使用) |
| ⚠️ 数据存储 | 所有配置保存在浏览器 localStorage,清除浏览器数据会丢失配置 |
| ⚠️ 多端同步 | 不支持,每个浏览器独立存储 |
| ⬇️ 下载缓存 | 建议挂载 /app/.cache/ffmpeg-downloads,避免容器重建时丢失已转存文件 |
默认仍为 NEXT_PUBLIC_AUTH_MODE=password,需要登录后使用。家庭局域网、NAS、电视盒子、OpenWrt、飞牛 OS 等完全可信内网场景,可以显式开启免登录:
docker run -d \
--name decotv \
-p 3000:3000 \
-e NEXT_PUBLIC_AUTH_MODE=public \
-v decotv-downloads:/app/.cache/ffmpeg-downloads \
ghcr.io/decohererk/decotv:latest
Docker Compose 示例:
services:
decotv:
image: ghcr.io/decohererk/decotv:latest
container_name: decotv
restart: unless-stopped
ports:
- '3000:3000'
environment:
- NEXT_PUBLIC_AUTH_MODE=public
volumes:
- decotv-downloads:/app/.cache/ffmpeg-downloads
volumes:
decotv-downloads:
⚠️
NEXT_PUBLIC_AUTH_MODE=public仅建议局域网、NAS、家庭内网、VPN、自用环境开启,不建议公网暴露。/admin和/api/admin/*默认仍需要登录保护;只有同时设置PUBLIC_ALLOW_ADMIN=true才会免登录开放后台和后台 API,该开关风险极高,仅适合完全可信内网。
Q: 登录成功后操作仍提示 401 Unauthorized?
这可能是以下原因:
REDIS_URL、KV_REST_API_URL 等数据库变量X-Forwarded-Proto $scheme,否则应用可能无法按外部访问协议设置 Cookielatest 镜像重启不会自动拉取新版本,升级前需要先执行 docker pull ghcr.io/decohererk/decotv:latestQ: 如何从本地模式迁移到数据库模式?
由于本地模式数据存储在浏览器中,无法直接迁移。建议:
完成部署后为空壳应用,无播放源,需要站长在管理后台的配置文件设置中填写配置文件(后续会支持订阅)
配置文件示例如下:
{
"cache_time": 7200,
"api_site": {
"dyttzy": {
"api": "http://xxx.com/api.php/provide/vod",
"name": "示例资源",
"detail": "http://xxx.com"
}
// ...更多站点
},
"custom_category": [
{
"name": "华语",
"type": "movie",
"query": "华语"
}
]
}
cache_time:接口缓存时间(秒)。api_site:你可以增删或替换任何资源站,字段说明:
key:唯一标识,保持小写字母/数字。api:资源站提供的 vod JSON API 根地址。name:在人机界面中展示的名称。detail:(可选)部分无法通过 API 获取剧集详情的站点,需要提供网页详情根 URL,用于爬取。custom_category:自定义分类配置,用于在导航中添加个性化的影视分类。以 type + query 作为唯一标识。支持以下字段:
name:分类显示名称(可选,如不提供则使用 query 作为显示名)type:分类类型,支持 movie(电影)或 tv(电视剧)query:搜索关键词,用于在豆瓣 API 中搜索相关内容custom_category 支持的自定义分类已知如下:
也可输入如 "哈利波特" 效果等同于豆瓣搜索
DecoTV 支持标准的苹果 CMS V10 API 格式。
可借助 watchtower 自动更新镜像容器
dockge/komodo 等 docker compose UI 也有自动更新功能
| 变量 | 说明 | 可选值 | 默认值 |
|---|---|---|---|
| USERNAME | 管理员账号 | 任意字符串 | 无默认,数据库模式必填,本地模式可省略 |
| PASSWORD | 管理员密码 | 任意字符串 | 无默认,必填 |
| NEXT_PUBLIC_AUTH_MODE | 访问模式 | password、public | password |
| PUBLIC_ALLOW_ADMIN | public 模式下是否开放后台 | true/false | false |
| SITE_BASE | 站点 URL | 形如 https://example.com | 空 |
| NEXT_PUBLIC_SITE_NAME | 站点名称 | 任意字符串 | DecoTV |
| ANNOUNCEMENT | 站点公告 | 任意字符串 | 本网站仅提供影视信息搜索服务,所有内容均来自第三方网站。本站不存储任何视频资源,不对任何内容的准确性、合法性、完整性负责。 |
| 变量 | 说明 | 可选值 | 默认值 | 备注 |
|---|---|---|---|---|
| NEXT_PUBLIC_STORAGE_TYPE | 存储类型 | localstorage、redis、kvrocks、upstash | localstorage | 不填则默认本地模式,数据存浏览器中 |
| KVROCKS_URL | Kvrocks 数据库连接地址 | redis://host:port | 空 | 当 STORAGE_TYPE=kvrocks 时必填 |
| REDIS_URL | Redis 数据库连接地址 | redis://host:port | 空 | 当 STORAGE_TYPE=redis 时必填 |
| UPSTASH_URL | Upstash Redis REST URL | https://xxx.upstash.io | 空 | 当 STORAGE_TYPE=upstash 时必填 |
| UPSTASH_TOKEN | Upstash Redis REST 令牌 | AUxxxx... | 空 | 当 STORAGE_TYPE=upstash 时必填 |
注意:Upstash 使用 REST API 连接,需要填写
UPSTASH_URL(HTTPS ENDPOINT)和UPSTASH_TOKEN,不是传统的 Redis 连接字符串。
注册需要先配置 redis、upstash 或 kvrocks 存储。部署后由站长在 /admin -> 用户配置 -> 公开注册 中直接控制开关和新用户默认用户组,无需为日常启停重新部署。
| 变量 | 说明 | 可选值 | 默认值 | 备注 |
|---|---|---|---|---|
| NEXT_PUBLIC_ENABLE_REGISTRATION | 旧配置迁移时的初始注册状态 | true/false | false | 后续以管理面板保存的设置为准 |
| DEFAULT_REGISTRATION_GROUP | 旧配置迁移时的初始默认用户组 | 用户组名称 | 空 | 后续在管理面板选择已创建的用户组 |
安全提示:公开注册默认关闭;不设置默认用户组时,新账号默认可使用全部可用视频源。详见 用户注册功能说明
| 变量 | 说明 | 可选值 | 默认值 | 备注 |
|---|---|---|---|---|
| NEXT_PUBLIC_SEARCH_MAX_PAGE | 搜索接口可拉取的最大页数 | 1-50 | 5 | 数值越大越慢 |
| NEXT_PUBLIC_DOUBAN_PROXY_TYPE | 豆瓣数据源请求方式 | 见下方说明 | auto | - |
| NEXT_PUBLIC_DOUBAN_PROXY | 自定义豆瓣数据代理 URL | URL prefix | 空 | custom 模式使用 |
| NEXT_PUBLIC_DOUBAN_IMAGE_PROXY_TYPE | 豆瓣图片代理类型 | 见下方说明 | auto | - |
| NEXT_PUBLIC_DOUBAN_IMAGE_PROXY | 自定义豆瓣图片代理 URL | URL prefix | 空 | custom 模式使用 |
| NEXT_PUBLIC_DISABLE_YELLOW_FILTER | 关闭色情内容过滤 | true/false | false | 不建议开启 |
| NEXT_PUBLIC_FLUID_SEARCH | 是否开启搜索接口流式输出 | true/false | true | - |
| 值 | 说明 |
|---|---|
| auto | 智能自动(默认),服务端按成功率和延迟在多个 provider 间自动降级 |
| direct | 服务器直接请求豆瓣源站 |
| server | 兼容值,等同于服务端智能代理 |
| cors-proxy-zwei | 服务端通过 Zwei 提供的 CORS Proxy 请求豆瓣数据 |
| cmliussss-cdn-tencent | 服务端通过 CMLiussss 提供的腾讯云 CDN 加速请求豆瓣数据 |
| cmliussss-cdn-ali | 服务端通过 CMLiussss 提供的阿里云 CDN 加速请求豆瓣数据 |
| custom | 使用自定义代理(需配置 NEXT_PUBLIC_DOUBAN_PROXY) |
| 值 | 说明 |
|---|---|
| auto | 智能自动(默认),按候选链路逐级重试 |
| direct | 浏览器直接请求豆瓣图片域名 |
| server | 服务器代理请求豆瓣图片 |
| img3 | 使用豆瓣官方精品 CDN(阿里云) |
| cmliussss-cdn-tencent | 使用 CMLiussss 提供的腾讯云 CDN |
| cmliussss-cdn-ali | 使用 CMLiussss 提供的阿里云 CDN |
| custom | 使用自定义代理(需配置 NEXT_PUBLIC_DOUBAN_IMAGE_PROXY) |
auto 模式下,豆瓣数据请求统一走服务端 /api/douban/*:优先使用最近成功且延迟较低的 provider,单个 provider 超时、403/429/5xx、返回 HTML 或非 JSON 时,会记录失败原因并短期负缓存,然后自动尝试下一个 provider。API 成功响应会带 X-DecoTV-Douban-Provider 与 X-DecoTV-Douban-Duration,失败响应会带 providerAttempts 便于排查。
豆瓣封面图片在浏览器端按候选链路重试:用户选择的代理 → 上次 auto 成功节点 → img3.doubanio.com → CMLiussss 阿里云 CDN → CMLiussss 腾讯云 CDN → /api/image-proxy 服务器代理 → 豆瓣原图直连 → poster-fallback.svg。本地设置或后台配置变更后会触发 doubanProxyChanged,只清理豆瓣相关缓存。
DecoTV 接入 弹弹play开放平台 提供的弹幕库。按照开放平台文档,应用取得的 AppId 与 AppSecret 需要妥善保管且不得泄露给他人。为避免将共享凭证写入公开代码或镜像,项目提供服务端中继用于部分公开部署场景。
| 部署方式 | 默认行为 |
|---|---|
| Vercel 等非 Docker Web 部署 | 未配置自有凭证时,通过项目公共中继 https://tv.katelya.eu.org 加载弹弹play官方弹幕 |
| 官方 Docker 镜像 | 不自动接入项目公共中继;可使用后台第三方弹幕节点,或配置自行申请的弹弹play凭证 |
已配置 DANDANPLAY_APP_* 的部署 | 优先在本部署服务端直连弹弹play开放平台 |
| 后台启用了第三方自定义弹幕节点 | 优先使用该第三方节点 |
当视频数据包含 TMDB ID 时,自动匹配会优先使用开放平台的 tmdbId + episode 查询,失败时再按标题回退;获取弹幕使用 withRelated=true 汇集关联来源。弹幕与搜索结果会在服务端/CDN 缓存,减少对开放平台的重复请求。
https://tv.katelya.eu.org 提供弹弹play官方弹幕的公共中继能力。中继服务在服务端完成开放平台认证,下游部署和浏览器不会获得项目使用的 AppSecret。
公共中继主要用于简化 Vercel 等 Web 平台的部署体验。由于公共服务存在可用容量、异常调用检测及平台额度约束,服务可能按实际运行情况进行限流或临时暂停,不保证作为专用弹幕后端长期无限制使用。
需要独立可用性、希望脱离公共中继运行的部署,可在 弹弹play DevCenter 申请凭证,并仅在自己的服务端环境变量中配置:
DANDANPLAY_APP_ID=在DevCenter申请的AppId
DANDANPLAY_APP_SECRET=有效AppSecret
Vercel 部署应将 DANDANPLAY_APP_SECRET 保存为 Sensitive Environment Variable,并在保存后重新部署。Docker 部署应从未提交到 Git 的运行时环境文件注入凭证,例如:
docker run --env-file .env.docker.local -p 3000:3000 decotv
公开 Docker 镜像不会内置共享 AppSecret,也不会默认请求项目公共中继。镜像持有者能够检查镜像内容和运行环境,因此将共享密钥打包进公开镜像无法保证凭证安全。
希望为 Docker 实例统一提供官方弹幕的用户,可以在自己控制的服务器上部署 DecoTV 中继,并为容器指定中继地址:
DANDANPLAY_RELAY_URL=https://your-relay.example.com
Vercel 或其他源码部署也可以使用 DANDANPLAY_RELAY_URL 覆盖默认中继;设为 disabled 时完全禁用中继回退。
不要将真实密钥提交到仓库、写入 NEXT_PUBLIC_* 环境变量、打包进公开镜像或提供给前端生成签名。弹弹play文档说明开放平台将在 2026 年 6 月 25 日 起启用应用分层与额度管理机制;自行部署的中继服务应开启缓存,并根据流量情况配置限流策略。
感谢 弹弹play 为 DecoTV 提供弹幕服务支持!
DecoTV 的网盘搜索采用远程 PanSou 节点转发模式。推荐先部署 fish2018/pansou,确认服务可访问后,在后台 PanSou 配置 中填入服务地址(可选填写 Token)。
快速示例:
https://your-pansou-domain/api/health 可访问。PanSou 配置 页面。https://your-pansou-domain)。如果 PanSou 开启 AUTH_ENABLED=true,可以直接填写 PanSou 用户名/密码,DecoTV 会自动登录换取 JWT;也可以在 API Token / 鉴权密钥 中直接填 JWT,支持填 Bearer xxx 或裸 token。DecoTV 支持把 TMDB 作为与豆瓣互补的第二元数据来源,尤其适合欧美 / 日韩内容和私人影库场景。
快速使用:
TMDB 配置 中填写 TMDB_API_KEY。TMDB_PROXY 或 TMDB_REVERSE_PROXY。TMDB 连通性测试,保存后即可生效。使用建议:
{tmdb-xxxx} 或 Emby / Jellyfin 的 ProviderIds.Tmdb 可以直接命中精准元数据。TMDB_API_KEY,项目会自动降级,不影响原有豆瓣链路和公共资源站播放。DecoTV 支持在后台接入 OpenList、小雅 Alist、Emby、Jellyfin 等私有媒体服务,配置成功后前台会自动显示“我的影库”入口。
OpenList 快速使用:
电影:流浪地球2 (2023) {tmdb-835547}/流浪地球2.mkv
剧集:三体 (2023) {tmdb-1428232}/Season 01/S01E01.mkv
私人影库 配置区块,添加连接并选择 OpenList。小雅 Alist 快速使用:
/。私人影库 配置区块,添加连接并选择 小雅 Alist。/电影。.strm 文件时,服务端会实时刷新阿里云盘直链。Emby / Jellyfin 快速使用:
Emby 或 Jellyfin 连接,填写服务地址、API Key,可选填写用户 ID 和媒体库过滤。补充说明:
/Media,小雅 Alist 默认根目录为 /。AudioStreamIndex 重新加载流并恢复切换前进度;HLS 资源支持无中断音轨切换。下载当前集。FFmpeg 转存下载。ffmpeg/ffprobe,VPS Docker 部署可直接使用。ffmpeg 和 ffprobe。/app/.cache/ffmpeg-downloads,用于保存服务端转存的临时成品文件。FFMPEG_PATH:自定义 ffmpeg 可执行路径。FFPROBE_PATH:自定义 ffprobe 可执行路径。FFMPEG_DOWNLOAD_DIR:服务端转存文件目录。FFMPEG_ALLOW_SERVERLESS=true:仅在你明确具备可执行二进制能力时使用。VPS Docker 持久化示例:
services:
decotv:
image: ghcr.io/decohererk/decotv:latest
ports:
- '3000:3000'
environment:
- PASSWORD=你的管理密码
- FFMPEG_MAX_CONCURRENT_JOBS=2
volumes:
- decotv-downloads:/app/.cache/ffmpeg-downloads
volumes:
decotv-downloads:
如果使用宿主机目录绑定,例如 ./downloads:/app/.cache/ffmpeg-downloads,请确保目录允许容器内 UID 1001 写入:
mkdir -p ./downloads
sudo chown -R 1001:1001 ./downloads
拉取播放列表失败 (502):通常是上游 m3u8 源需要特定 Referer/Origin,请确认源可访问,或切换其他源重试。FFmpeg API request failed (500/501):检查部署环境是否安装 FFmpeg;官方 Docker 镜像应开箱可用,自建镜像请确认 Dockerfile 包含 FFmpeg。EACCES / permission denied:转存目录不可写;使用上方 named volume,或修正宿主机目录权限。FFMPEG_JOB_RETENTION_MS,必要时降低 FFMPEG_MAX_CONCURRENT_JOBS。目前该项目可以配合 OrionTV 在 Android TV 上使用,可以直接作为 OrionTV 后端
已实现播放记录和网页端同步
详细配置指南:
OrionTV 成人内容过滤快速配置:
API 地址: https://your-domain.com/
✅ 自动过滤成人资源源和敏感关键词
API 地址: https://your-domain.com/adult/
✅ 显示所有内容(包括成人资源)
💡 工作原理:
- 路径前缀
/adult/会被自动识别并重写- 例如:
/adult/api/search→/api/search?adult=1- OrionTV 无需额外配置,开箱即用
注意: 此方式仅适用于 Web 端,OrionTV 可能不支持
API 地址: https://your-domain.com
API 地址: https://your-domain.com?adult=1
详细说明请参阅 成人内容过滤使用指南
具体可见 TVBox 配置优化说明 ,详细功能见/admin 管理页面 TVbox 配置
DecoTV 支持用户自助注册功能(可选),适合需要允许用户自行创建账号的场景。
功能特性:
详细使用指南:用户注册功能说明
快速启用:
# 先设置支持多用户的存储
NEXT_PUBLIC_STORAGE_TYPE=redis # 或 upstash、kvrocks
部署完成后,以站长账号进入 /admin 的“用户配置”,选择新用户默认用户组后打开“允许访客自行注册账号”。
⚠️ 安全提示:建议默认关闭注册,仅在需要时临时开启,注册完成后在后台立即关闭。
为了您的安全和避免潜在的法律风险,我们要求在部署时强烈建议关闭公网注册:
PASSWORD:为您的实例设置一个强密码MIT © 2025 DecoTV & Contributors
如果这个项目对你有所帮助,欢迎 Star ⭐ 本项目或请作者喝杯咖啡 ☕
🎨 微信赞赏 |
🌟 如果觉得项目有用,请点个 Star 支持一下!🌟
Made with ❤️ by Decohererk and Contributors