105 lines
5.2 KiB
Markdown
105 lines
5.2 KiB
Markdown
# 华莱士门店电视广告机:一期实现方案
|
||
|
||
## 一期目标
|
||
|
||
交付一个 Android APK,安装在门店电视或广告屏上后始终横屏全屏运行。终端首次开机显示绑定二维码;门店通过小程序扫码完成设备与门店绑定;绑定完成后,终端按后台下发的顺序循环播放图片和视频广告。
|
||
|
||
一期不做终端侧人工操作、广告编辑或门店管理,这些能力全部由后台或小程序承接。
|
||
|
||
## 终端状态
|
||
|
||
1. **初始化**:生成并持久化唯一设备标识 `sn`。Android App 优先读取 DCloud 的 `plus.device.uuid`;它不可用时才生成应用级随机编号并保存在本地。
|
||
2. **待绑定**:二维码内容为完整 HTTPS 绑定链接,例如 `https://screen.example.com/bind?sn=WLS-xxx`。每 10 秒查询一次绑定状态。
|
||
3. **拉取节目单**:绑定成功后,获取门店信息、终端授权信息和广告节目单。
|
||
4. **播放中**:图片按 `duration` 停留,视频播放至结束;每项播放完毕后切换到下一项。
|
||
5. **刷新节目单**:完整播放一轮后重新拉取节目单;后台也可在响应中返回 `refresh_interval`,用于定时刷新。
|
||
6. **异常/离线**:保留最近一次有效节目单和媒体缓存;网络恢复后自动同步。没有可播放素材时显示简洁的门店品牌待机页。
|
||
|
||
## 建议接口约定
|
||
|
||
### 查询绑定状态
|
||
|
||
`GET /screen/v1/devices/{sn}/binding`
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"data": {
|
||
"bound": true,
|
||
"store_id": "WALLACE-001",
|
||
"token": "terminal-token"
|
||
}
|
||
}
|
||
```
|
||
|
||
### 获取节目单
|
||
|
||
`GET /screen/v1/playlists/current?sn={sn}`
|
||
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"data": {
|
||
"revision": "20260820-01",
|
||
"refresh_interval": 300,
|
||
"items": [
|
||
{
|
||
"id": "creative-001",
|
||
"type": "image",
|
||
"url": "https://cdn.example.com/creative-001.jpg",
|
||
"duration": 8,
|
||
"checksum": "sha256..."
|
||
},
|
||
{
|
||
"id": "creative-002",
|
||
"type": "video",
|
||
"url": "https://cdn.example.com/creative-002.mp4"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
规则:`type` 仅允许 `image`、`video`;图片的 `duration` 单位为秒且必须大于 0;视频由其实际时长决定切换。节目单必须携带版本号和素材校验值,便于终端判断是否需要下载更新。
|
||
|
||
## 当前 Mock 实现
|
||
|
||
- 配置位于 `config/terminal.ts`,当前 `useMock: true`。
|
||
- 终端会生成 `WLS-` 前缀的 `sn`,并将 `bindPageUrl` 与 `sn` 拼成二维码内容。
|
||
- 待绑定页提供“模拟完成绑定”按钮,且默认 15 秒后自动模拟绑定,方便电视端演示。
|
||
- Mock 节目单为“图片 → 视频 → 图片”,完整播放一轮后重新读取节目单。
|
||
- Mock 阶段二维码图片由公共二维码服务渲染;正式发布前应替换为内置二维码组件,避免依赖第三方二维码服务。
|
||
- 后端就绪时,将 `useMock` 改为 `false`,并在 `services/terminal.ts` 的两个方法中接入绑定状态、节目单正式接口。
|
||
|
||
## 终端实现划分
|
||
|
||
- `services/device`:生成、读取和存储设备 `sn`;Android 优先使用系统稳定标识并派生应用设备号。
|
||
- `services/binding`:绑定状态轮询、终端令牌管理和门店信息读取。
|
||
- `services/playlist`:节目单请求、数据校验、版本比对和本地持久化。
|
||
- `services/media-cache`:下载媒体、校验 checksum、清理过期缓存,并始终保留当前节目单。
|
||
- `components/ScreenPlayer`:统一渲染图片、视频、加载失败占位和下一项预加载。
|
||
- `pages/index`:按终端状态装配“待绑定”和“播放”两个状态视图,不提供业务导航。
|
||
|
||
## 播放与可靠性规则
|
||
|
||
1. 切换前预加载下一张图片或下一个视频,避免黑屏。
|
||
2. 视频监听 `ended`、`error`、超时三种事件;失败时记录并跳过,不能阻塞整个节目单。
|
||
3. 单个素材连续失败 3 次后,本轮播放忽略该素材;下一次节目单更新后重新尝试。
|
||
4. 所有网络请求采用指数退避重试;无网络时继续播放已缓存内容。
|
||
5. 进入播放页后隐藏状态栏和导航栏,禁用旋转回竖屏,按 16:9 容器等比裁切显示。
|
||
6. 终端只展示必要状态:未绑定二维码、加载中、无可播放内容;不暴露接口地址、令牌或调试信息。
|
||
|
||
## 实施顺序
|
||
|
||
1. 对接绑定状态接口,完成设备号、二维码和轮询状态页。
|
||
2. 对接节目单接口,完成图片/视频顺序播放和整轮刷新。
|
||
3. 加入媒体预加载、离线缓存、失败跳过和网络恢复。
|
||
4. 在目标电视设备上验证横屏全屏、自启动、断网恢复、连续播放和 APK 签名发布。
|
||
|
||
## 需后台确认
|
||
|
||
- 绑定二维码最终使用的正式域名/小程序跳转规则。
|
||
- 设备与门店解绑、换店、禁用设备的接口和状态码。
|
||
- 节目单素材 CDN、视频格式上限、有效期和审核策略。
|
||
- 需要 Android 开机自启动和受控保活:APK 侧需由原生 Android Receiver/厂商白名单或 MDM 触发开机拉起;电视/机顶盒侧推荐纳入 MDM 的 kiosk(单应用)策略。仅申请 `RECEIVE_BOOT_COMPLETED` 权限不足以保证各品牌设备可自启动,必须在目标设备实测并按厂商策略配置。
|