参数、批量与稳定性相关
1. 批量部署
1.1 部署模型
FoxPlayer 是单机闭环产品:每台终端各自持有数据库、素材与授权,不依赖中心服务端。批量部署的本质是「把同一套程序与内容复制到多台机器,再逐台完成授权与身份区分」。
推荐两种做法:
| 做法 | 适用 | 要点 |
|---|---|---|
| 母盘/镜像克隆 | 同型号终端、内容一致 | 克隆前清空 license.key,克隆后逐台激活;逐台修改 device_id |
| 逐台安装 + 脚本初始化 | 终端异构、内容不同 | 安装后调用 HTTP API 登录、改密、写配置、传素材、排节目单 |
1.2 部署前检查
- [ ] 终端时间正确(授权到期判断依赖系统时间)
- [ ] 58000–58003 未被其它软件占用
- [ ] 磁盘剩余空间 ≥ 素材总量 × 1.2
- [ ] 已决定是否需要转码(低配终端建议统一转 H.264/AAC)
- [ ] 已准备每台机器的授权码(按机器码申请)
- [ ] 已确定
control_secret(多终端建议一致,便于上层系统统一调用)
1.3 用脚本完成初始化
以下 PowerShell 示例完成「登录 → 改密 → 写配置」;把地址与密码换成实际值:
$base = 'http://192.168.1.50:58000'
# 1) 登录拿 JWT
$login = Invoke-RestMethod -Method Post -Uri "$base/api/auth/login" `
-ContentType 'application/json' `
-Body '{"username":"admin","password":"admin123"}'
$h = @{ Authorization = "Bearer $($login.token)" }
# 2) 修改默认密码(字段名是 old / new)
Invoke-RestMethod -Method Put -Uri "$base/api/auth/password" -Headers $h `
-ContentType 'application/json' `
-Body '{"old":"admin123","new":"请换成强密码"}'
# 3) 写配置(改密后旧 token 失效,需要重新登录)
$login = Invoke-RestMethod -Method Post -Uri "$base/api/auth/login" `
-ContentType 'application/json' `
-Body '{"username":"admin","password":"请换成强密码"}'
$h = @{ Authorization = "Bearer $($login.token)" }
Invoke-RestMethod -Method Put -Uri "$base/api/config" -Headers $h `
-ContentType 'application/json' `
-Body '{"device_id":"FOX-STORE-001","control_secret":"请换成随机长串","startup_volume":"70"}'
PUT /api/config会逐键写入,没有键白名单;只传需要改的键,不要整包回写不认识的字段。端口类配置改完需重启应用。
1.4 逐台区分身份
device_id必须唯一,建议FOX-<项目>-<序号>;它用于状态展示与/api/player/control的设备校验- 机器码由硬件计算,克隆母盘不会导致机器码相同;但授权文件必须逐台申请,不能复制
- 若使用固定 IP,建议在路由器/交换机上做 DHCP 静态绑定,避免后台地址变化
2. 长时间运行与无人值守
| 项 | 建议 |
|---|---|
| 开机自启 | 保持 auto_start=true;Windows 下由 launch_at_startup 注册 |
| 防休眠 | 程序播放期间已申请 wakelock;仍需在系统电源设置中关闭「睡眠/休眠」 |
| 系统更新 | 关闭自动重启类更新,或安排在非营业时间 |
| 看门狗 | 建议外部(中控/计划任务)定时 GET /api/pub/status,连续失败再重启进程 |
| 定时重启 | 可用中控发 restart_app(仅 HTTP 管理通道)或系统计划任务;避免直接断电 |
| 日志 | 5 MB 自动轮转保留一代;长期运行建议外部定期归档 logs/ |
| 磁盘 | 素材与转码产物会持续占用空间,建议设置容量告警 |
| 时间同步 | 保持 NTP 同步;时间漂移会影响授权到期判断与日志排查 |
3. 权限与安全
3.1 必做项
- 改默认密码:
admin/admin123只用于首次登录。 - 配置
control_secret:一旦非空,TCP/UDP/WebSocket 与/api/pub/control都必须带匹配 token;未配置时局域网内任意主机都能切内容。 - 只在内网暴露:58000–58003 不要映射到公网;确需远程访问时走 VPN 或反向代理,并开启
trust_proxy_headers仅限可信代理。 - 限制 CORS:
cors_origins默认为空(不发跨域头)。只在确有跨域前端时填写白名单,不要填*。 - 按需启用 HTTPS:同时配置
https_cert_path与https_key_path;只配一个会回退 HTTP 并记录告警。 - 保护授权文件:
license.key与机器绑定,泄露不会直接可用,但仍应按敏感文件管理。
3.2 认证与限流
| 项 | 实现 |
|---|---|
| 登录 | 用户名 + 密码,成功返回 JWT |
| JWT | HS256,24 小时过期,payload 含 user 与 ver |
| 真登出 | 登出/改密使 tokenVersion 自增,旧 token 立即失效 |
| 密码存储 | PBKDF2-HMAC-SHA256,10 万次迭代,随机盐 |
| 登录限流 | 同一 IP 10 分钟内失败 5 次即锁定 |
| 管理接口 | 除登录、机器码、公开接口外均需 Authorization: Bearer |
| 系统指令 | shutdown/restart/quit_app/restart_app/setConfig 仅允许 HTTP 管理通道 |
3.3 通道鉴权矩阵
| 通道 | 管理接口 | 播放指令 |
|---|---|---|
| HTTP 58000 | JWT | /api/player/control 需 JWT;/api/pub/control 需 token 或 JWT(配置 control_secret 后) |
| TCP 58001 | 不提供 | control_secret 非空时,指令顶层需 token |
| UDP 58002 | 不提供 | 同上 |
| WebSocket 58003 | 不提供 | 同上 |
4. 性能与稳定性
4.1 解码
- 默认解码优先级
MFT,D3D11,FFmpeg;低配机器可改为纯FFmpeg,高端机器可保留硬解优先 - 在「系统设置 → 播放」修改
decoder_override,保存后实时应用 - 4K/HEVC 10bit 对硬件要求高;无法硬解时优先转码,不要盲目提高缓存
4.2 转码
- 转码由
ffmpeg_cube执行,单任务队列,去重,60 分钟超时 - 输出
*.transcoded.*,先写.tmp再原子改名;启动时清理孤儿产物 - 默认
player_use_transcoded=false(播放器用源文件),monitor_use_transcoded=true(监视页用转码文件) - 推荐参数:H.264(
libx264)+ AAC,yuv420p,CRF 23,码率按屏幕分辨率调整 - 转码是 CPU 密集任务,建议在非营业时间批量执行
4.3 播放稳定性
- 视频切换采用 gapless 预排队 + 5 秒兜底;若现场仍有卡顿,检查素材关键帧间隔与码率
- 解码失败自动跳项;连续失败到末尾会停止,日志中会留下具体文件与错误
- 节目单建议控制在可维护规模;超长节目单会增加数据库与内存开销
- 数据库使用 WAL,突然断电后重启会自动恢复;仍建议定期备份
5. 离线部署
FoxPlayer 的运行不依赖公网:
- 播放、素材、节目单、授权校验全部本地完成
- Web 后台资源内置,无需外网 CDN
- 转码使用随包的
ffmpeg_cube后端;若后端缺失,转码失败但不影响播放 - 授权为离线签名校验,不需要联网激活
- 升级需要人工拷贝安装包;没有内置自动更新
离线交付时,建议随包附带:安装包、本文档、节目单模板、授权码清单、默认 control_secret(单独交付,不入公开资料)。
6. 故障排查
| 现象 | 优先检查 | 处理 |
|---|---|---|
| 后台打不开 | 进程是否在、端口是否被占、http_enabled |
看日志「HTTP 服务器已启动」;netstat -ano \| findstr 58000;重启应用 |
| 局域网访问不了 | 防火墙、IP、是否只绑回环 | 放行 58000;确认使用终端 IP 而非 127.0.0.1 |
| 播放黑屏 | 素材是否存在、编码是否支持、授权是否有效 | 查 media/;转码为 H.264/AAC;查授权状态 |
| 有画面无声音 | 系统音量、输出设备、音频透传 | 关闭音频透传试一次;检查默认输出设备 |
| 切歌无反应 | control_secret 未带 token、指令名拼错、状态不允许 |
看响应 message;对照指令表;查操作日志 |
| 重复指令无响应 | 200 ms 去重窗口内同文件重复 | 间隔后再发;这是预期行为 |
| 上传 415 | 扩展名不在白名单 | 转格式后再传 |
| 上传失败但无提示 | 超过大小上限 / 磁盘满 | 查 max_upload_size_mb 与磁盘剩余 |
| 授权突然失效 | 系统时间跳变、机器码变化(换网卡/改主机名)、授权到期 | 校正时间;重新申请授权 |
| 登录被锁 | 同 IP 连续失败 5 次 | 等待 10 分钟窗口过期;或重置管理员 |
| 日志过大 | 未轮转 / 外部未归档 | 程序自动 5 MB 轮转;外部定期归档 |
| 托盘图标消失 | 资源管理器重启 | 重新启动应用;或发 window_show |
6.1 排障顺序
GET /api/pub/status:能否返回 JSON,state是什么- Web 后台仪表盘:当前项、节目单是否为空、音量
- 数据目录
logs/foxplayer.log:搜error/warn/ 文件名 GET /api/logs:最近指令与结果,确认「指令到了但被忽略」还是「根本没到」- 授权页/接口:
GET /api/auth/license看状态与剩余天数
事实依据:config_service.dart、auth_service.dart、command_service.dart、transcode_service.dart