跳转到内容

播放与代理

播放问题经常发生在客户端、SyncTV、Provider 和上游媒体服务器的边界。Provider 明确返回播放信息和上游 header,客户端按播放结果执行;底层 proxy 不猜测客户端 header。

  1. 客户端请求房间当前播放或指定媒体的播放信息。
  2. SyncTV 根据房间状态、媒体、用户、Provider 凭据和客户端能力生成 Playback
  3. Provider 返回一个或多个 PlaybackInfo,每个模式包含 URL、format、header、字幕、过期时间和 metadata。
  4. 客户端选择合适模式:直连、proxy、转码、HLS、FLV 或字幕 URL。
  5. URL 过期、媒体切换、Provider 凭据变化或客户端能力变化后,客户端重新获取播放信息。
模式 适合场景 风险
直连 客户端能访问上游,并能设置必要 header 浏览器限制 header、CORS、暴露上游地址
SyncTV proxy 上游只能被服务端访问,或需要服务端统一 header/凭据 SyncTV 承担带宽和延迟,需规划容量
Provider 转码或变体 上游提供多清晰度、多编码或字幕 客户端必须按能力选择,不能固定第一个 URL
直播 HLS/FLV RTMP 推流转播放 多副本需要 HLS backend 或 publisher proxy

Alist 播放 URL 可能绑定特定 User-Agent。Bilibili 常依赖 User-AgentReferer、Cookie 和 Range。直连与代理表现不一致时,对比 Provider 返回给客户端的 header 与代理发往上游的 header;客户端受浏览器限制时选择代理 URL。

每个 Provider 负责解释 PlaybackProxyMode、判断认证信息暴露风险,并在生成 PlaybackResult 时决定具体线路。Auto 的结果可以随 Provider、媒体类型和媒体变体变化。外层 API 负责找到 Provider 并透传策略结果。

配置模式 Provider 生成行为
Auto Provider 根据每个媒体变体的 URL、header、签名和会话要求选择实际模式
Prefer 生成代理与直连线路,默认选择代理
Only 只生成代理线路
DirectPrefer 生成直连与代理线路,默认选择直连
DirectOnly 只生成直连线路

Auto 以认证信息保护为主要规则:公开资源使用 DirectPrefer;认证 header、URL 认证参数、签名 URL 和 Provider 会话使用 Only。Provider 可以为协议、转码或服务端传输需求返回更严格的结果。Bilibili 视频、PGC 和直播使用签名资源,因此 Auto 返回 Only。NAS 和云盘来源依赖 Provider 会话,因此 Auto 返回 Only。Direct URL 会逐项检查媒体、字幕和弹幕资源,混合来源可以同时包含公开直连变体和受保护代理变体。

Provider 在请求上游资源前计算线路选择。只代理模式跳过直连 URL 获取或直连变体构建,只直连模式跳过代理资源构建。这个顺序减少上游请求、签名生成、转码准备和缓存写入。

客户端使用 POST /api/providers/playback-proxy-policy 查询具体 DiscoveredSource。响应包含:

  • supported_modes:该来源支持的表单选项。
  • current_mode:来源当前保存的配置。
  • auto_policies:每个媒体变体的 Auto 实际模式和原因。

客户端根据响应动态生成选择器和提示,也可以对已保存来源查询同一策略。Provider 新增媒体变体时同步更新策略返回值和播放生成测试。

每个 Provider 管理自己生成的播放资源,包括媒体、字幕、普通弹幕、实时弹幕、缩略图、HLS playlist 与 segment、DASH manifest 与子资源,以及直播 FLV 或 HLS 资源。

Provider 资源 URL 使用以下路径:

/api/playback-providers/{roomId}/{provider}/...

路径中的房间 ID 属于签名 claim。签名播放查询包含 siguidexp。重写后的 HLS 资源还包含已签名的 targetUrl。DASH 资源路由在路径中携带签名字段,上游资源查询保持独立。这个布局保留上游查询,并让公开路径只保留一个房间标识。

Provider service 决定资源路由、上游 URL、header、直连或代理投递方式,以及 playlist 重写规则。HTTP 与 gRPC adapter 调用同一个 room actor 业务操作。共享传输层负责流式转发、Range、重定向、超时和缓存行为。

PlaybackDanmaku.delivery 告诉客户端每个弹幕资源的加载方式。DOCUMENT 使用静态文档加载器。EVENT_STREAM 使用实时事件流加载器。客户端根据这个字段选择加载器。

客户端应根据环境和能力选择播放结果:

客户端条件 处理
浏览器不能设置 Referer 或自定义 header 优先选择 proxy URL
原生客户端可设置 header 且能访问上游 可使用直连 URL
移动端不支持某些 codec/container PlaybackClientProfile 中声明能力,选择转码或兼容模式
URL 有 expires_at 到期前重新获取播放信息
字幕有独立 header 使用字幕 URL 自带 header;proxy 字幕时 header 会合并

客户端通过 PlaybackClientProfile.supported_live_transports 声明播放器支持的直播传输。当前协议定义 PLAYBACK_LIVE_TRANSPORT_HLSPLAYBACK_LIVE_TRANSPORT_FLV。Provider 在请求上游播放信息前选择传输,并让上游请求参数、PlaybackMedia.format 和实际 URL 保持一致。

客户端配置 当前声明 Provider 结果
Web HLS 请求 HLS 上游资源,返回 m3u8 媒体
原生桌面和移动端 FLV 请求 HTTP-FLV 上游资源,返回 flv 媒体
旧客户端或空列表 HLS 默认能力 按 HLS 兼容路径生成播放信息

直播 Provider 将最终传输类型写入播放缓存键。HLS 和 FLV 使用独立缓存条目,因此客户端能力变化会触发对应上游资源生成。新增直播 Provider 或传输类型时,需要同时覆盖能力选择、上游参数、返回 format、缓存隔离和客户端实际播放测试。

媒体 seek 通常依赖 HTTP Range:

Range: bytes=1048576-2097151

SyncTV proxy slice cache 的边界:

  • 只缓存可 Range 切片的媒体字节。
  • 不做 full-body cache。
  • 上游不支持 Range 时直接 bypass。
  • 文件后端可以跨进程重启保留数据,但没有跨进程共享索引或分布式锁。
  • 多副本可以用共享存储,但不要把 slice cache 当作强一致分布式缓存。

Provider 可以为确定不支持 Range 的小型资源选择 full-response cache,例如字幕和静态弹幕。首次响应会记录状态、Content-Length 和内容类型等 metadata;只有状态成功且声明大小不超过 16 MiB 时才进入全量缓存并使用填充锁。未知大小、超限或其他不可缓存响应仍直接流式返回,大小限制不限制向客户端转发的数据量;后续请求根据 metadata 直接 bypass,避免让不会被缓存的资源串行请求。

配置细节见 Proxy slice cache

新客户端使用 Realtime 资源观察订阅播放信息:

  • playbackState:当前播放位置、状态和版本。
  • playback:当前媒体的播放 URL、headers、字幕和过期时间。

断线重连时,重新获取 playbackState,并用当前 playbackClientProfile 观察 playback。播放信息是当前播放源可直接交给播放器使用的数据,生命周期跟随其中的 URL。

完整协议见 Realtime 协议

原生客户端可以在播放同步设置中动态开启 P2P 媒体分发。符合条件的点播 PlaybackMedia 会包含 p2p_delivery;客户端通过 WebRTC DataChannel 从同一房间、同一资源 swarm 的其他观众获取媒体分片,并保留原始 HTTP 地址作为回退路径。

项目 行为
资源范围 Provider 为静态点播资源生成房间隔离的 swarm;直播省略 p2p_delivery
媒体格式 客户端根据所选 PlaybackMedia.format 处理普通文件、HLS 和 DASH
直连与代理 Provider 确认两种模式字节一致时,两者使用同一个 swarm
权限 房间成员或游客需要 use_p2p_media
动态开关 关闭后客户端离开 swarm、停止 P2P 连接并继续通过 HTTP 播放
本地缓存 可选择 64、128、256、512 或 1024 MiB,默认 128 MiB;最近使用的分片可跨播放会话复用,连续 10 分钟未访问后自动过期

播放器的 P2P 指标展示已连接 Peer、总下载和上传速度、HTTP 下载、P2P 下载与上传、累计流量、缓存大小及命中率。Peer 暂时不可用、ICE 连接失败或分片传输超时时,播放请求会自动使用来源 HTTP。

WebRTC 和直播不是普通点播 proxy:

能力 边界
WebRTC 为语音聊天和 P2P 媒体分发提供独立会话,依赖 ICE/STUN/TURN 配置及对应的 use_voice_chatuse_p2p_media 权限
RTMP 推流 推流入口,通常由主播或房间管理员使用
HTTP-FLV 低延迟直播播放路径,受长连接和客户端慢速读取影响
HLS playlist/segment 文件路径,多副本需要本地 proxy、共享文件或 S3 backend

WebRTC 配置见 WebRTC 配置,直播见 直播配置

现象 可能层级 检查
播放器立刻 403 Provider 凭据或 header Provider 返回 header、上游状态码
seek 后失败 Range 或 slice cache 上游 Accept-RangesContent-Range、proxy 日志
只有浏览器失败 CORS 或 header 限制 选择 proxy,检查浏览器 Network
只有代理失败 SyncTV 到上游网络或 header 服务端网络、DNS、proxy header
多副本直播偶发失败 HLS 存储模型 publisher 节点、共享存储、S3 或 gRPC proxy
播放 URL 一段时间后失效 expires_at 订阅或重新拉取播放信息