给个人站加一个影视板块
给个人站加一个影视板块
本站在 /tv 路径下集成了一个完整的影视搜索和播放系统,基于 MoonTVPlus 二次开发。
架构概览
整个 TV 板块是独立运行的 Next.js 应用,通过主站的 proxy 路由嵌入:
用户访问 /tv
→ 主站 iframe(src="/tv-proxy")
→ 主站 rewrite /api/ → /tv-proxy/api/
→ proxy route (/tv-proxy/[[...path]]/route.ts)
→ http://localhost:3002 (MoonTVPlus)
这样设计的理由:MoonTVPlus 自身的 /api/* 路径在主站下会冲突,通过 rewrite 把所有 TV 相关的 API 请求转发到 MoonTVPlus 的实际端口。
项目结构
D:\MyWeb\
├── moontv\ ← MoonTVPlus (Next.js 14, 端口 3002)
│ ├── src\ ← 源码
│ ├── .env.local ← 环境变量
│ └── .data\moontv.db ← SQLite 数据库
├── infinite-canvas\ ← 主站 (Next.js 16, 端口 3000)
│ ├── next.config.ts ← rewrite 和 redirect 规则
│ └── src\app\tv\ ← TV iframe 页面
└── danmu_api\ ← 弹幕服务 (端口 9321)
集成要点
1. Rewrite 规则
主站的 next.config.ts 配置了 24 条 rewrite 规则,覆盖 MoonTVPlus 的所有 API 路径:
rewrites: [
{ source: "/api/login", destination: "/tv-proxy/api/login" },
{ source: "/api/search/:path", destination: "/tv-proxy/api/search/:path" },
{ source: "/api/danmaku/:path", destination: "/tv-proxy/api/danmaku/:path" },
{ source: "/api/image-proxy", destination: "/tv-proxy/api/image-proxy" },
// ... 共 24 条
]
2. Proxy Route
主站新增一个 catch-all 路由来处理代理转发:
/tv-proxy/[[...path]]/route.ts
收到请求后直接 fetch 到 MoonTVPlus 的对应路径,把响应透传给浏览器。
3. iframe 页面
/tv 页面是一个简单的 iframe,指向 /tv-proxy。iframe 的好处是两个应用完全隔离——MoonTVPlus 的样式、路由、状态都不会影响主站。
视频源配置
MoonTVPlus 本身是空壳,不内置任何视频源。通过环境变量订阅 LunaTV 的配置:
CONFIG_SUBSCRIPTION_URL=https://pz.v88.qzz.io?format=2&source=jingjian
这个订阅地址 Base58 编码了 61 个视频源(普通 + 成人),通过管理后台拉取后,所有源就可以搜索了。源数据每日更新。
源有了之后还需要根据实际测速调整权重。用了几部热门电影测试后,把表现最好的源(红牛资源、豪华资源、速播资源)权重调高,被墙或不可用的源(爱奇艺)排除掉。
弹幕服务
MoonTVPlus 的弹幕功能依赖独立的弹幕 API 后端。内置的 Netlify 服务在国内被墙,所以自建了一个:
git clone https://github.com/huangxd-/danmu_api.git
cd danmu_api && npm install
服务启动后在 http://localhost:9321,从腾讯视频、爱奇艺、B站等国内平台实时获取弹幕数据。集成到 start-server.bat 里随网站一起启动。
几个坑
登录重定向:MoonTVPlus 的 basePath 是 /tv-proxy,登录后默认跳转到 /(主站根目录)。需要修改源码中的重定向逻辑,从当前路径推导正确的 basePath。
图片代理:视频源的封面图来自各种 CDN(tu.iqiyizyimg.com、pps.vodfeiss.com 等),很多在国内无法直接访问。通过 MoonTVPlus 的 /api/image-proxy 路由做服务器中转,所有外部图片走服务器代理加载。
PWA 图标:MoonTVPlus 的 manifest.json 引用 /icons/icon-192x192.png,但文件只存在于 MoonTVPlus 的 public/ 目录下。需要在主站加一条 rewrite 把 /icons/* 代理过去。
弹幕中间件拦截:/api/image-proxy 请求会被 MoonTVPlus 的 auth middleware 拦截返回 401,需要把这个路径加到 middleware 的 skip list 里。
Windows 启动脚本:.bat 文件必须用 CRLF 换行符,否则 cmd.exe 闪退。这是个花了一小时才发现的坑。
启动流程
现在的启动顺序是:
1. 清理端口(3000、3002、9321)
2. 启动弹幕服务 danmu_api
3. 启动 MoonTVPlus(端口 3002)
4. 启动主站(端口 3000)
5. 启动 frpc 内网穿透
全部集成在一个 start-server.bat 里一键启动。