跳转到内容

播放模型

SyncTV 的同步观看由服务端房间状态驱动。客户端不把自己的播放器状态当成事实来源;它接收房间当前播放状态,并在有权限时提交播放控制动作。

状态谁维护用途
当前播放状态SyncTV 服务端当前媒体、播放/暂停、进度、速度和版本
播放信息Provider 和 SyncTV 生成播放 URL、代理 URL、header、字幕、变体和过期时间

当前播放状态回答“房间正在看什么、看到哪里”。播放信息回答“这个客户端现在应该怎么播放这个媒体”。

房间 WebSocket 负责同步播放控制、聊天、WebRTC 信令和资源观察事件。客户端断线重连后,应重新获取关键资源,而不是假设旧订阅仍然存在。

典型顺序:

  1. 客户端进入房间。
  2. 获取当前播放状态和播放信息。
  3. 连接 Realtime。
  4. 收到播放、暂停、seek 或切换媒体事件。
  5. 如果媒体 URL 过期、Provider 凭据变化或资源版本变化,重新获取播放信息。
模式适合场景风险
直连客户端能访问上游 URL,并能设置所需 header浏览器可能不能设置部分 header
SyncTV proxy需要隐藏上游凭据、统一 header、处理 Range 或绕过客户端限制SyncTV 承担出口带宽和代理延迟

Provider 明确返回需要使用的 header。SyncTV proxy 不自动转发客户端原始 header,避免把不该传给上游的信息泄露出去。

同一个播放结果可以同时包含直连模式和 proxy_* 模式。Provider 在生成播放信息时决定这些模式、默认模式、header 暴露策略和签名代理 URL。共享 helper 只负责生成标准 proxy sibling URL,不能替代各 Provider 自己的播放决策。

HTTP 和 gRPC 是传输入口。它们解析路径、query、JSON/protobuf、headers 和流式 body,然后调用 synctv-api/src/impls。权限、播放状态、Provider 调用、缓存、fanout、时长合并和资源生命周期处理在 impls 与 core service 中完成,让两种传输共享同一套行为。

seek 通常依赖 HTTP Range。上游支持 Range 时,SyncTV proxy slice cache 可以缓存固定分片;上游不支持 Range 时,SyncTV 会绕过 slice cache,不把完整大文件写成缓存。

播放时长探测和播放自动切换由本节点 active room 驱动。房间只有在当前进程存在 Realtime 连接时,才会进入该节点的后台播放扫描集合。

这些 worker 在每个节点运行,让后台任务跟随真实连接生命周期。集群中多个节点同时承载同一房间时,数据库负责并发安全:时长探测用任务抢占,自动切换用播放状态事务和乐观版本。

后台任务的输入集合来自 ConnectionRuntime::active_room_ids()。Presence hot-room 统计用于房间列表、管理视图和 metrics;播放生命周期 worker 使用本节点实时连接集合,并通过数据库锁、SKIP LOCKED 和播放状态版本写入收敛。

动态 playlist 的后台任务还需要绑定当前 target。Repository 查询保留 room_id = ANY(active_room_ids) 和当前 room_playback_progress.target_hash join,确保探测、缓存和自动切换围绕房间当前播放项进行。