init
This commit is contained in:
717
docs/first-version-plan.md
Normal file
717
docs/first-version-plan.md
Normal file
@@ -0,0 +1,717 @@
|
||||
# SyncTV 第一版方案
|
||||
|
||||
## 1. 产品定位
|
||||
|
||||
SyncTV 第一版是一个无注册、无用户体系的同步观影客户端,面向 App 和 Windows 应用。
|
||||
|
||||
核心目标:
|
||||
|
||||
- 输入房间 Code 即可进入房间。
|
||||
- 不做账号、昵称、好友、聊天、历史用户等用户体系。
|
||||
- 不支持本地视频。
|
||||
- 只支持网络播放源:普通链接、OSS、WebDAV、直播流。
|
||||
- 客户端负责解码播放,避免网页播放器格式支持弱的问题。
|
||||
- 后端负责房间状态、同步信令、播放源解析、临时凭据保存,以及必要时的流式转发。
|
||||
- 支持断线重连,并恢复到房间当前播放进度。
|
||||
|
||||
第一版优先把三件事做好:
|
||||
|
||||
- 能播。
|
||||
- 同步准。
|
||||
- 断线能回来。
|
||||
|
||||
## 2. 第一版功能范围
|
||||
|
||||
### 2.1 创建和进入房间
|
||||
|
||||
用户打开应用后可以创建房间,或输入已有房间 Code 加入房间。
|
||||
|
||||
房间可以先没有播放源。第一个加入房间成功的设备自动成为房主。
|
||||
|
||||
房主可以配置:
|
||||
|
||||
- 播放源类型。
|
||||
- 播放源地址或配置。
|
||||
- 是否为直播流。
|
||||
- 连接方式,默认客户端直连,可手动切换为服务端代理。
|
||||
|
||||
创建新房间时服务端生成房间 Code,例如:
|
||||
|
||||
```text
|
||||
A7K29Q
|
||||
```
|
||||
|
||||
### 2.2 加入房间
|
||||
|
||||
客户端只需要输入房间 Code。
|
||||
|
||||
加入后客户端自动获取:
|
||||
|
||||
- 播放源信息。
|
||||
- 当前播放状态。
|
||||
- 当前播放进度。
|
||||
- 是否直播。
|
||||
- 当前房主设备信息。
|
||||
|
||||
不需要用户登录,也不需要设置昵称。
|
||||
|
||||
只有房主可以配置或更换播放源。所有房间成员都可以执行播放、暂停、跳转进度、回到直播等播放控制。
|
||||
|
||||
播放源连接方式由房主在配置时选择。默认是客户端直连源站,代理模式必须由房主主动打开。
|
||||
|
||||
### 2.3 播放控制同步
|
||||
|
||||
点播场景支持:
|
||||
|
||||
- 播放。
|
||||
- 暂停。
|
||||
- 跳转进度。
|
||||
- 当前进度同步。
|
||||
- 缓冲后恢复。
|
||||
|
||||
直播场景支持:
|
||||
|
||||
- 播放。
|
||||
- 暂停。
|
||||
- 回到直播。
|
||||
- 直播延迟同步。
|
||||
|
||||
### 2.4 断线重连
|
||||
|
||||
客户端 WebSocket 断开后自动重连。
|
||||
|
||||
重连时携带:
|
||||
|
||||
- 房间 Code。
|
||||
- 本地设备 ID。
|
||||
|
||||
服务端返回最新房间快照,客户端重新计算应播放位置并恢复。
|
||||
|
||||
房间无人在线后保留一段时间,建议第一版保留 30 分钟。超过后销毁房间和临时播放源凭据。
|
||||
|
||||
## 3. 非目标
|
||||
|
||||
第一版不做:
|
||||
|
||||
- 注册。
|
||||
- 登录。
|
||||
- 昵称。
|
||||
- 用户资料。
|
||||
- 好友。
|
||||
- 聊天。
|
||||
- 弹幕。
|
||||
- 房间列表。
|
||||
- 历史记录。
|
||||
- 本地视频同步。
|
||||
- 内置影视内容。
|
||||
- 完整资源站。
|
||||
|
||||
## 4. 技术选型建议
|
||||
|
||||
### 4.1 客户端
|
||||
|
||||
客户端改为分端开发。
|
||||
|
||||
Windows 客户端建议:
|
||||
|
||||
- Python。
|
||||
- PySide6。
|
||||
- python-vlc。
|
||||
- PyInstaller 打包 Windows exe。
|
||||
- 系统播放器逻辑和同步逻辑分离。
|
||||
|
||||
移动 App 建议:
|
||||
|
||||
- HBuilder/uni-app。
|
||||
- UI 和房间同步逻辑使用 Vue/uni-app。
|
||||
- 播放器通过 App 原生插件接 VLC。
|
||||
- Android 原生插件封装 libVLC。
|
||||
- iOS 原生插件封装 MobileVLCKit / VLCKit。
|
||||
|
||||
分端开发的原因:
|
||||
|
||||
- 避免重型桌面工具链问题。
|
||||
- Windows 端优先把强播放能力跑通。
|
||||
- App 端通过 HBuilder 快速开发,同时保留原生 VLC 播放能力。
|
||||
- 客户端共享后端协议,不共享 UI 代码。
|
||||
|
||||
选择播放器时需要重点验证:
|
||||
|
||||
- mp4。
|
||||
- mkv。
|
||||
- flv。
|
||||
- m3u8。
|
||||
- dash。
|
||||
- 常见编码格式。
|
||||
- 直播流。
|
||||
- HTTP Header 自定义。
|
||||
- Cookie / Authorization Header。
|
||||
- WebDAV URL 播放。
|
||||
- 字幕和音轨扩展能力。
|
||||
|
||||
### 4.2 后端
|
||||
|
||||
第一版服务端原则:
|
||||
|
||||
- 尽量轻。
|
||||
- 尽量少模块。
|
||||
- 尽量少状态。
|
||||
- 默认不接触视频流。
|
||||
- 只有房主手动开启代理时才做流式转发。
|
||||
- 不做用户系统。
|
||||
- 不做数据库表设计。
|
||||
- 不做文件存储。
|
||||
|
||||
推荐:
|
||||
|
||||
- Go。
|
||||
- 标准库 net/http 或 Gin/Fiber/Echo。
|
||||
- WebSocket。
|
||||
- Redis。
|
||||
- Docker + Nginx。
|
||||
|
||||
第一版不建议上 PostgreSQL。房间状态、连接状态、临时播放源和过期时间都放 Redis,开发更快,清理也简单。
|
||||
|
||||
Go 更适合服务端保持轻量:单二进制部署,内存占用低,并发连接和流式转发能力好。第一版可以优先使用标准库 net/http,减少框架依赖。
|
||||
|
||||
### 4.3 服务模块
|
||||
|
||||
后端建议只拆最少模块:
|
||||
|
||||
- RoomService:房间创建、加入、房主判定、房间快照、过期清理。
|
||||
- SyncGateway:WebSocket 连接、播放控制广播、心跳、重连。
|
||||
- SourceService:播放源保存、直连信息下发、代理 URL 生成。
|
||||
- StreamProxy:房主手动开启代理时,对 WebDAV/OSS/普通私有链接做流式转发,不落盘存储。
|
||||
|
||||
第一版可以先不单独拆 CredentialService、SourceResolver 等细模块,避免服务端过早变重。等代理来源和鉴权方式变多后再拆。
|
||||
|
||||
## 5. 播放源设计
|
||||
|
||||
第一版支持四类来源。
|
||||
|
||||
| 类型 | 示例 | 第一版处理方式 |
|
||||
| --- | --- | --- |
|
||||
| 普通链接 | mp4、m3u8、flv、dash | 默认客户端直连,可手动开启代理 |
|
||||
| OSS | 阿里云 OSS、S3 兼容对象存储 | 默认客户端直连,可手动开启代理 |
|
||||
| WebDAV | WebDAV 文件 URL | 默认客户端直连,可手动开启代理 |
|
||||
| 直播流 | m3u8、flv、其他播放器支持协议 | 默认客户端直连,可手动开启代理 |
|
||||
|
||||
房主配置播放源时需要有一个明确的连接方式控件:
|
||||
|
||||
- 默认:客户端直连。
|
||||
- 可选:服务端代理。
|
||||
|
||||
这个控件可以做成分段按钮或开关,不做自动切换。代理模式涉及服务器带宽成本和隐私边界,必须让房主显式选择。
|
||||
|
||||
### 5.1 普通链接
|
||||
|
||||
普通链接是最简单的来源。
|
||||
|
||||
后端只保存 URL 和基础元信息,客户端直接播放。
|
||||
|
||||
需要支持:
|
||||
|
||||
- 普通 HTTP/HTTPS URL。
|
||||
- m3u8。
|
||||
- flv。
|
||||
- dash。
|
||||
- 带必要 Header 的 URL。
|
||||
|
||||
### 5.2 OSS
|
||||
|
||||
OSS 有两种使用方式。
|
||||
|
||||
方式一:用户直接输入公开 URL 或签名 URL。
|
||||
|
||||
- 实现简单。
|
||||
- 客户端直接播放。
|
||||
- 后端只保存 URL。
|
||||
- 适合第一版快速落地。
|
||||
|
||||
方式二:房主输入 OSS 配置,服务端保存临时凭据,并返回代理播放 URL。
|
||||
|
||||
- 更安全。
|
||||
- 不把 Secret 直接广播给所有客户端。
|
||||
- 服务端只做流式转发,不下载、不落盘。
|
||||
- 房间销毁后清理配置。
|
||||
- 适合稍微完整的第一版。
|
||||
|
||||
建议第一版支持方式一和方式二。方式一是默认模式;方式二需要房主手动开启,会增加服务器带宽压力,但不会增加硬盘存储压力。
|
||||
|
||||
### 5.3 WebDAV
|
||||
|
||||
WebDAV 是第一版需要重点设计的来源,因为它通常需要账号密码。
|
||||
|
||||
常见 WebDAV 鉴权方式:
|
||||
|
||||
- Basic Auth。
|
||||
- Digest Auth。
|
||||
- Cookie。
|
||||
- Token。
|
||||
|
||||
播放器播放 WebDAV 文件时,客户端通常必须具备以下能力之一:
|
||||
|
||||
- URL 中包含凭据。
|
||||
- 播放请求附带 Authorization Header。
|
||||
- 访问服务端流式代理地址。
|
||||
|
||||
所以“WebDAV 的 key 不给客户端还能不能用”的答案是:
|
||||
|
||||
> 如果客户端要直接连接 WebDAV,凭据或等价的临时授权信息必须给客户端;不给就不能直连播放。
|
||||
>
|
||||
> 如果使用服务端流式代理,客户端不需要拿到原始 WebDAV 凭据;服务端拿到凭据后直接向 WebDAV 拉流,并边读边转发给客户端,不下载、不落盘。
|
||||
|
||||
#### 5.3.1 极简方案:凭据下发客户端
|
||||
|
||||
创建房间时,房主输入:
|
||||
|
||||
- WebDAV 文件 URL。
|
||||
- 用户名。
|
||||
- 密码或 Token。
|
||||
|
||||
服务端保存房间播放源,并在成员加入房间时下发给客户端。
|
||||
|
||||
客户端用这些凭据直接播放。
|
||||
|
||||
优点:
|
||||
|
||||
- 实现最简单。
|
||||
- 后端不承担视频流量。
|
||||
- 播放性能最好。
|
||||
- 成本最低。
|
||||
|
||||
缺点:
|
||||
|
||||
- 所有加入房间的客户端都能拿到 WebDAV 凭据。
|
||||
- 如果房间 Code 泄露,凭据也可能泄露。
|
||||
- 对安全和隐私不友好。
|
||||
|
||||
适用场景:
|
||||
|
||||
- 早期内测。
|
||||
- 用户之间互相信任。
|
||||
- WebDAV 凭据本身是临时的。
|
||||
- 产品明确提示风险。
|
||||
|
||||
#### 5.3.2 代理模式:服务端保存凭据并流式转发
|
||||
|
||||
创建房间时,房主提交 WebDAV 配置给后端。
|
||||
|
||||
后端:
|
||||
|
||||
- 加密保存 WebDAV 凭据。
|
||||
- 验证文件是否可访问。
|
||||
- 为房间成员生成代理播放 URL。
|
||||
- 使用 WebDAV 凭据向源站发起请求。
|
||||
- 将源站响应以流式方式转发给客户端。
|
||||
- 不把视频文件下载到服务器硬盘。
|
||||
- 不做长期缓存。
|
||||
- 房间过期后删除凭据。
|
||||
|
||||
客户端播放:
|
||||
|
||||
```text
|
||||
https://api.example.com/rooms/A7K29Q/source/stream?token=short-lived-token
|
||||
```
|
||||
|
||||
服务端收到请求后使用 WebDAV 凭据去拉取源文件,再把内容边读边转发给客户端。
|
||||
|
||||
优点:
|
||||
|
||||
- 客户端拿不到原始 WebDAV 密码。
|
||||
- 可以做房间权限、过期、限速、防盗链。
|
||||
- 房间销毁后授权自然失效。
|
||||
- 不承担硬盘存储压力。
|
||||
|
||||
缺点:
|
||||
|
||||
- 后端要承担视频流量,带宽成本高。
|
||||
- 需要支持 Range 请求,否则拖动进度会很差。
|
||||
- 大文件和高并发时压力明显。
|
||||
- 直播和大码率视频对服务端要求更高。
|
||||
- 需要处理连接中断、源站限速、响应头透传等转发细节。
|
||||
|
||||
这个方案安全性更好,不占用硬盘,但基础设施带宽成本更高。
|
||||
|
||||
#### 5.3.3 第一版建议
|
||||
|
||||
第一版建议做两个模式,但默认始终是直连模式:
|
||||
|
||||
1. 直连模式:客户端直连 WebDAV。
|
||||
- 房主输入 WebDAV URL 和凭据。
|
||||
- 后端临时保存并下发给房间客户端。
|
||||
- 明确这是共享房间凭据,适合可信房间。
|
||||
- 这是默认模式。
|
||||
|
||||
2. 代理模式:服务端流式转发 WebDAV。
|
||||
- 房主输入 WebDAV URL 和凭据。
|
||||
- 房主必须手动打开代理模式。
|
||||
- 后端保存凭据。
|
||||
- 客户端只拿代理播放 URL。
|
||||
- 后端支持 Range 请求。
|
||||
- 后端不下载、不落盘,只做流式转发。
|
||||
- 后端承担带宽和连接压力。
|
||||
|
||||
普通 URL 和 OSS 也可以使用同样的代理模式。只要服务端能拿到访问源站所需的 URL、Header、Cookie 或 Secret,就可以向源站发起请求并流式转发给客户端。
|
||||
|
||||
## 6. 房间状态模型
|
||||
|
||||
Redis 中建议保存房间快照。
|
||||
|
||||
点播房间示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"roomCode": "A7K29Q",
|
||||
"sourceType": "webdav",
|
||||
"sourceId": "src_123",
|
||||
"isLive": false,
|
||||
"playbackState": "playing",
|
||||
"positionMs": 128400,
|
||||
"serverUpdatedAt": 1780000000000,
|
||||
"ownerDeviceId": "dev_abc",
|
||||
"onlineCount": 2,
|
||||
"expireAt": 1780001800000
|
||||
}
|
||||
```
|
||||
|
||||
直播房间示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"roomCode": "A7K29Q",
|
||||
"sourceType": "url",
|
||||
"sourceId": "src_456",
|
||||
"isLive": true,
|
||||
"playbackState": "playing",
|
||||
"liveSyncMode": "latency",
|
||||
"targetLatencyMs": 3000,
|
||||
"serverUpdatedAt": 1780000000000,
|
||||
"ownerDeviceId": "dev_abc",
|
||||
"onlineCount": 2,
|
||||
"expireAt": 1780001800000
|
||||
}
|
||||
```
|
||||
|
||||
## 7. 同步协议
|
||||
|
||||
### 7.1 WebSocket 事件
|
||||
|
||||
客户端到服务端:
|
||||
|
||||
- createRoom
|
||||
- joinRoom
|
||||
- leaveRoom
|
||||
- play
|
||||
- pause
|
||||
- seek
|
||||
- syncProgress
|
||||
- syncToLive
|
||||
- heartbeat
|
||||
- reconnectRoom
|
||||
|
||||
服务端到客户端:
|
||||
|
||||
- roomCreated
|
||||
- roomJoined
|
||||
- roomSnapshot
|
||||
- playbackChanged
|
||||
- progressSynced
|
||||
- liveSynced
|
||||
- controllerChanged
|
||||
- roomExpired
|
||||
- error
|
||||
|
||||
### 7.2 点播同步
|
||||
|
||||
控制端执行播放控制时发送事件。
|
||||
|
||||
播放事件示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "play",
|
||||
"roomCode": "A7K29Q",
|
||||
"positionMs": 128400,
|
||||
"clientSentAt": 1780000000000
|
||||
}
|
||||
```
|
||||
|
||||
服务端写入:
|
||||
|
||||
```json
|
||||
{
|
||||
"playbackState": "playing",
|
||||
"positionMs": 128400,
|
||||
"serverUpdatedAt": 1780000000120
|
||||
}
|
||||
```
|
||||
|
||||
其他客户端收到后计算目标进度:
|
||||
|
||||
```text
|
||||
targetPositionMs = positionMs + (clientNowServerTime - serverUpdatedAt)
|
||||
```
|
||||
|
||||
误差处理建议:
|
||||
|
||||
- 小于 500ms:不处理。
|
||||
- 500ms 到 2000ms:短时间微调倍速。
|
||||
- 大于 2000ms:直接 seek。
|
||||
|
||||
控制端每 3 秒上报一次当前状态,用于校准。
|
||||
|
||||
### 7.3 直播同步
|
||||
|
||||
直播不以 positionMs 为核心,而以直播延迟为核心。
|
||||
|
||||
建议同步字段:
|
||||
|
||||
```json
|
||||
{
|
||||
"isLive": true,
|
||||
"targetLatencyMs": 3000,
|
||||
"playbackState": "playing"
|
||||
}
|
||||
```
|
||||
|
||||
客户端尽量保持距离直播边缘 3 秒左右。
|
||||
|
||||
直播控制:
|
||||
|
||||
- play:开始拉流。
|
||||
- pause:暂停本地播放。
|
||||
- syncToLive:回到直播边缘或目标延迟。
|
||||
|
||||
直播流由于源站、CDN、客户端缓冲策略不同,很难做到毫秒级同步。第一版目标应是让多个客户端处于接近的直播延迟。
|
||||
|
||||
## 8. 断线重连恢复
|
||||
|
||||
### 8.1 客户端本地保存
|
||||
|
||||
客户端本地保存:
|
||||
|
||||
```json
|
||||
{
|
||||
"deviceId": "dev_abc",
|
||||
"lastRoomCode": "A7K29Q",
|
||||
"lastConnectedAt": 1780000000000
|
||||
}
|
||||
```
|
||||
|
||||
deviceId 是本地随机生成的设备标识。
|
||||
|
||||
它不是账号,也不是用户 ID,只用于:
|
||||
|
||||
- 断线重连。
|
||||
- 控制权恢复。
|
||||
- 同一设备重复连接识别。
|
||||
|
||||
### 8.2 重连流程
|
||||
|
||||
1. WebSocket 断开。
|
||||
2. 客户端进入重连状态。
|
||||
3. 客户端带 roomCode 和 deviceId 重连。
|
||||
4. 服务端检查房间是否还存在。
|
||||
5. 服务端返回 roomSnapshot。
|
||||
6. 客户端重新解析播放源。
|
||||
7. 点播房间根据 positionMs 和 serverUpdatedAt 恢复。
|
||||
8. 直播房间恢复到目标直播延迟。
|
||||
|
||||
### 8.3 房主和控制权处理
|
||||
|
||||
建议第一版规则:
|
||||
|
||||
- 第一个加入房间成功的设备成为房主。
|
||||
- 只有房主可以配置或更换播放源。
|
||||
- 所有房间成员都可以播放、暂停、跳转进度、回到直播。
|
||||
- 房主短暂断线 30 秒内,房主身份保留。
|
||||
- 房主超过 30 秒未恢复,允许当前房间内最早在线的设备成为新房主。
|
||||
- 房间无人后进入保留期,保留期间房主身份和房间状态仍然存在。
|
||||
|
||||
这个规则避免了用户体系,同时保留了“谁能换片”的边界。
|
||||
|
||||
## 9. 客户端架构
|
||||
|
||||
客户端建议拆成:
|
||||
|
||||
- RoomController:创建房间、加入房间、房间状态。
|
||||
- SocketClient:WebSocket 连接、重连、事件收发。
|
||||
- PlayerController:播放、暂停、seek、倍速、直播控制。
|
||||
- SyncEngine:进度计算、误差校正、直播延迟同步。
|
||||
- SourceManager:播放源初始化、凭据处理、URL 刷新。
|
||||
- LocalDeviceStore:本地 deviceId 和 lastRoomCode。
|
||||
|
||||
## 10. 后端架构
|
||||
|
||||
后端第一版建议保持单体服务,不拆微服务。
|
||||
|
||||
最小结构:
|
||||
|
||||
- HTTP API:创建房间、加入房间、配置播放源、获取房间快照。
|
||||
- WebSocket Gateway:播放、暂停、seek、直播同步、心跳、断线重连。
|
||||
- Redis Store:房间状态、连接状态、播放源配置、过期时间。
|
||||
- Stream Proxy:可选代理入口,只有房主开启代理模式时使用。
|
||||
|
||||
代码模块:
|
||||
|
||||
- RoomService:房间创建、房间加入、房主判定、快照维护。
|
||||
- PlaybackService:播放状态写入和广播。
|
||||
- SourceService:播放源保存、直连信息下发、代理 URL 生成。
|
||||
- StreamProxyService:WebDAV/OSS/私有链接流式转发,不落盘存储。
|
||||
|
||||
暂时不做:
|
||||
|
||||
- 用户数据库。
|
||||
- PostgreSQL。
|
||||
- 微服务拆分。
|
||||
- 消息队列。
|
||||
- 文件存储。
|
||||
- 复杂权限系统。
|
||||
|
||||
Redis Key 示例:
|
||||
|
||||
```text
|
||||
room:A7K29Q
|
||||
room:A7K29Q:connections
|
||||
source:src_123
|
||||
device:dev_abc:last
|
||||
```
|
||||
|
||||
## 11. WebDAV 凭据结论
|
||||
|
||||
WebDAV 凭据问题可以概括为一句话:
|
||||
|
||||
> 客户端直连 WebDAV 时,客户端必须拿到凭据或等价授权;代理模式下客户端只拿我们服务端的播放 URL,原始凭据由服务端持有。
|
||||
|
||||
两种可选做法:
|
||||
|
||||
| 方案 | 客户端拿到什么 | 后端流量成本 | 安全性 | 实现难度 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| 直连模式 | 原始凭据或 Basic Auth Header | 低 | 低 | 低 |
|
||||
| 代理模式 | 服务端代理 URL | 高 | 高 | 中高 |
|
||||
|
||||
代理模式的关键点:
|
||||
|
||||
- 服务端拿到用户的 key、Cookie、Header 或账号密码。
|
||||
- 服务端向 WebDAV/OSS/私有源站发起请求。
|
||||
- 服务端把响应流转发给客户端。
|
||||
- 服务端不下载完整文件。
|
||||
- 服务端不做硬盘存储。
|
||||
- 服务端必须正确支持 Range、Content-Type、Content-Length、Accept-Ranges 等响应头。
|
||||
- 服务端需要承担带宽、并发连接和转发稳定性压力。
|
||||
|
||||
第一版建议:
|
||||
|
||||
- 同时支持直连模式和代理模式。
|
||||
- 房主配置播放源时通过按钮或开关选择连接方式。
|
||||
- 默认连接方式是客户端直连。
|
||||
- 代理模式必须由房主主动开启。
|
||||
- 直连模式适合可信房间和低成本场景。
|
||||
- 代理模式适合不想把 key 暴露给房间成员的场景。
|
||||
|
||||
## 12. 第一版里程碑
|
||||
|
||||
### Milestone 1:最小可跑通
|
||||
|
||||
- Windows 客户端。
|
||||
- 轻量 Node.js 服务端。
|
||||
- Redis 房间状态。
|
||||
- 房间创建和加入。
|
||||
- 普通 URL 播放。
|
||||
- 播放、暂停、seek 同步。
|
||||
- WebSocket 断线重连。
|
||||
|
||||
### Milestone 2:播放源扩展
|
||||
|
||||
- m3u8 直播流。
|
||||
- OSS 签名 URL。
|
||||
- WebDAV 直连模式。
|
||||
- HTTP Header 支持。
|
||||
|
||||
### Milestone 3:同步体验打磨
|
||||
|
||||
- 周期性进度校准。
|
||||
- 小误差倍速追赶。
|
||||
- 大误差 seek。
|
||||
- 直播回到实时。
|
||||
|
||||
### Milestone 4:移动端
|
||||
|
||||
- App 客户端。
|
||||
- 复用房间和同步协议。
|
||||
- 验证播放器内核能力。
|
||||
|
||||
### Milestone 5:代理能力增强
|
||||
|
||||
- WebDAV/OSS 最小流式代理。
|
||||
- 凭据加密存储。
|
||||
- 代理 URL 短期 Token。
|
||||
- Range 请求和拖动进度优化。
|
||||
- 源站 Header 透传和错误处理。
|
||||
- 房间过期自动清理。
|
||||
|
||||
## 13. 关键风险
|
||||
|
||||
### 13.1 播放器能力风险
|
||||
|
||||
不同平台播放器能力不一致,尤其是:
|
||||
|
||||
- iOS 对部分格式限制更多。
|
||||
- Android 机型和系统版本差异大。
|
||||
- Windows mpv/libVLC 能力较强,但集成和打包需要验证。
|
||||
|
||||
第一阶段应优先做播放内核 PoC。
|
||||
|
||||
### 13.2 WebDAV 兼容风险
|
||||
|
||||
不同 WebDAV 服务差异很大:
|
||||
|
||||
- 鉴权方式不同。
|
||||
- 是否支持 Range 请求不同。
|
||||
- 是否支持文件直链不同。
|
||||
- 是否限制 User-Agent 或 Header。
|
||||
|
||||
第一版应先支持最常见的 Basic Auth + Range。
|
||||
|
||||
### 13.3 服务端流式代理成本风险
|
||||
|
||||
如果服务端代理 WebDAV 或 OSS 视频流,所有视频流量都会走后端。
|
||||
|
||||
这会带来:
|
||||
|
||||
- 高带宽成本。
|
||||
- 高并发压力。
|
||||
- 大文件拖动复杂度。
|
||||
- 直播流转发压力。
|
||||
- 但不会带来硬盘存储压力,因为代理模式只做流式转发,不下载、不落盘。
|
||||
|
||||
因此代理模式适合安全要求更高的房间,但需要配套限流、超时、Range 支持和错误恢复。
|
||||
|
||||
### 13.4 直播同步风险
|
||||
|
||||
直播流本身缓冲和 CDN 延迟不稳定。
|
||||
|
||||
第一版不要承诺毫秒级同步直播,目标是保持相近的直播延迟。
|
||||
|
||||
## 14. 推荐第一版决策
|
||||
|
||||
建议第一版采用:
|
||||
|
||||
- Windows 和 App 分端开发。
|
||||
- Windows 优先跑通。
|
||||
- Windows 客户端使用 Python + PySide6 + python-vlc,并用 PyInstaller 打包。
|
||||
- App 使用 HBuilder/uni-app + 原生 VLC 插件。
|
||||
- 后端 Go + WebSocket + Redis。
|
||||
- 服务端保持单体和轻量,不上 PostgreSQL,不拆微服务。
|
||||
- 普通 URL、OSS、WebDAV、m3u8 直播优先。
|
||||
- 播放源支持直连和服务端流式代理。
|
||||
- 默认客户端直连,代理模式由房主手动开启。
|
||||
- 第一个加入房间的设备为房主。
|
||||
- 只有房主能配置或更换播放源。
|
||||
- 所有人都可以播放、暂停、跳转进度、回到直播。
|
||||
- 房间无人后 30 分钟销毁。
|
||||
|
||||
最终第一版交付目标:
|
||||
|
||||
> 用户创建或加入房间,第一个加入者成为房主并配置网络播放源;默认由客户端直接获取源站内容,房主也可以手动开启服务端代理;其他设备输入 Code 加入后自动播放同一来源,并同步播放、暂停、跳转;断线后自动回到房间当前进度;支持普通链接、OSS、WebDAV 和直播流;代理模式下服务端拿到 key 后流式转发给客户端,不下载、不落盘。
|
||||
Reference in New Issue
Block a user