718 lines
19 KiB
Markdown
718 lines
19 KiB
Markdown
# 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 后流式转发给客户端,不下载、不落盘。
|