Playback and Proxy
Boundary
Section titled “Boundary”Playback issues often sit between the client, SyncTV, Provider, and upstream media server. Providers explicitly return playback information and upstream headers, clients follow that result, and the proxy does not guess client headers.
Playback Flow
Section titled “Playback Flow”- The client requests the current room playback or a playback for a media item.
- SyncTV uses room state, media, user, Provider credentials, and client profile to build
Playback. - The Provider returns one or more
PlaybackInfoentries with URL, format, headers, subtitles, expiry, and metadata. - The client chooses direct URL, proxy URL, transcode variant, HLS, FLV, or subtitle URL.
- When URL expiry, media switch, credential change, or client capability changes, the client requests fresh playback info.
Direct and Proxy Playback
Section titled “Direct and Proxy Playback”| Mode | Best for | Risk |
|---|---|---|
| Direct | Client can access upstream and set headers | Browser header limits, CORS, upstream exposure |
| SyncTV proxy | Upstream is server-only or requires server-controlled headers | SyncTV carries bandwidth and latency |
| Provider variants | Multiple qualities, codecs, subtitles, or transcoding | Client must choose by capability |
| HLS/FLV live | RTMP publish to playback | Multi-replica deployments need HLS backend or publisher proxy |
Alist playback URLs may be bound to a specific User-Agent. Bilibili commonly depends on User-Agent, Referer, cookies, and Range. When direct and proxy playback behave differently, compare the headers returned to the client with those sent upstream by the proxy. Browser clients that cannot set the required headers should select the proxy URL.
Playback Route Policy
Section titled “Playback Route Policy”Each Provider interprets PlaybackProxyMode, evaluates credential exposure, and selects concrete routes while generating PlaybackResult. The effective Auto result can vary by Provider, media type, and media variant. The outer API resolves the Provider and transports its policy result.
| Configured mode | Provider generation behavior |
|---|---|
Auto |
The Provider selects an effective mode for each media variant from its URL, headers, signature, and session requirements |
Prefer |
Generate proxy and direct routes, with proxy selected by default |
Only |
Generate proxy routes only |
DirectPrefer |
Generate direct and proxy routes, with direct selected by default |
DirectOnly |
Generate direct routes only |
Credential protection is the primary Auto rule. Public resources use DirectPrefer. Credential headers, URL credentials, signed URLs, and Provider sessions use Only. A Provider can return a stricter result for protocol, transcoding, or server-transport requirements. Bilibili video, PGC, and live playback use signed resources, so their effective Auto mode is Only. NAS and cloud sources depend on Provider sessions, so their effective Auto mode is Only. Direct URL inspects media, subtitle, and danmaku resources individually, allowing public direct variants and protected proxy variants in one source.
Providers calculate route selection before requesting upstream resources. Proxy-only generation skips direct URL acquisition and direct variant construction. Direct-only generation skips proxy resource construction. This order reduces upstream requests, signing work, transcoding preparation, and cache writes.
Clients query a concrete DiscoveredSource through POST /api/providers/playback-proxy-policy. The response contains:
supported_modes: form options supported by this source.current_mode: the source’s stored configuration.auto_policies: each media variant’s effective Auto mode and reason.
Clients build selectors and hints from this response. The same endpoint accepts an accessible persisted source for media-level inspection. A new Provider media variant must update both the policy response and playback generation tests.
Playback-Provider Resource Contract
Section titled “Playback-Provider Resource Contract”Each Provider owns the playback resources that it creates. This includes media, subtitles, danmaku documents, real-time danmaku streams, thumbnails, HLS playlists and segments, DASH manifests and child resources, and live FLV or HLS resources.
Provider resource URLs use this path:
/api/playback-providers/{roomId}/{provider}/...The path room ID is part of the signed claim. A signed playback query contains sig, uid, and exp. A rewritten HLS resource also contains a signed targetUrl. DASH resource routes carry their signature fields in the path, while the upstream resource query remains separate. This layout keeps the upstream query intact and keeps the room identity in one public location.
The Provider service decides the resource route, upstream URL, headers, direct or proxy delivery, and playlist rewrite rules. HTTP and gRPC adapters call the same room-actor business operation. The shared transport layer forwards streams, Range requests, redirects, timeouts, and cache behavior.
PlaybackDanmaku.delivery tells the client how to load each danmaku resource. DOCUMENT uses the static document loader. EVENT_STREAM uses the real-time event-stream loader. Clients must use this field instead of Provider names, format strings, or URL patterns.
Client Selection Strategy
Section titled “Client Selection Strategy”| Client condition | Handling |
|---|---|
Browser cannot set Referer or custom headers |
Prefer proxy URL |
| Native client can set headers and access upstream | Direct URL can be used |
| Mobile client lacks codec/container support | Declare capabilities in PlaybackClientProfile |
URL has expires_at |
Request fresh playback info before expiry |
| Subtitle has separate headers | Use subtitle-specific headers or proxy subtitle URL |
Live Transport Negotiation
Section titled “Live Transport Negotiation”Clients declare player-supported live transports through PlaybackClientProfile.supported_live_transports. The protocol currently defines PLAYBACK_LIVE_TRANSPORT_HLS and PLAYBACK_LIVE_TRANSPORT_FLV. A Provider selects the transport before requesting upstream playback information and keeps the upstream parameters, PlaybackMedia.format, and returned URL aligned.
| Client profile | Current declaration | Provider result |
|---|---|---|
| Web | HLS | Request upstream HLS and return m3u8 media |
| Native desktop and mobile | FLV | Request upstream HTTP-FLV and return flv media |
| Legacy client or empty list | Default HLS capability | Generate playback through the HLS compatibility path |
Live Providers include the selected transport in their playback cache keys. HLS and FLV use separate cache entries, so a client-capability change generates the matching upstream resource. A new live Provider or transport must cover capability selection, upstream parameters, returned format, cache isolation, and real-client playback tests.
Range and Slice Cache
Section titled “Range and Slice Cache”Seeking usually depends on HTTP Range:
Range: bytes=1048576-2097151Proxy slice cache boundaries:
- Caches only Range slices.
- Does not cache full response bodies.
- Bypasses upstreams that do not support Range.
- File backend can survive process restarts, but has no cross-process index or distributed lock.
- Shared storage in multi-replica mode is possible, but this is not a strongly consistent distributed cache.
A Provider can select full-response caching for small resources that are known not to support Range, such as subtitles and static danmaku. The first response records status, Content-Length, content type, and related metadata. Only successful responses with a declared size of at most 16 MiB enter the full-response cache and use a fill lock. Responses with an unknown or larger size continue streaming to the client without a response-size limit. Later requests use the metadata to bypass the lock for resources that cannot be cached.
See Proxy Slice Cache.
Playback Info and Realtime
Section titled “Playback Info and Realtime”New clients observe playback resources over Realtime:
playbackState: current position, state, and version.playback: playback URLs, headers, subtitles, and expiry.
On reconnect, fetch playbackState and observe playback with the current playbackClientProfile. Playback info is player-ready data for the current source and expires with its URLs.
See Realtime Protocol.
P2P Media Delivery
Section titled “P2P Media Delivery”Native clients can enable P2P media delivery dynamically from playback sync settings. Eligible on-demand PlaybackMedia entries contain p2p_delivery. The client obtains media pieces from viewers in the same room and resource swarm over WebRTC DataChannels, with the original HTTP URL retained as the fallback path.
| Item | Behavior |
|---|---|
| Resource scope | Providers create room-isolated swarms for static on-demand resources; live playback omits p2p_delivery |
| Media formats | The client uses the selected PlaybackMedia.format to handle progressive files, HLS, and DASH |
| Direct and proxy | Both modes share a swarm when the Provider confirms byte equivalence |
| Permission | Room members or guests need use_p2p_media |
| Runtime toggle | Disabling P2P leaves the swarm, closes P2P connections, and continues playback over HTTP |
| Local cache | Select 64, 128, 256, 512, or 1024 MiB; the default is 128 MiB. Recently used pieces remain reusable across playback sessions and expire after ten minutes without access |
Player diagnostics report connected peers, aggregate download and upload rates, HTTP download, P2P download and upload, transferred bytes, cache size, and cache hit rate. Playback requests automatically use the HTTP origin when peers, ICE connectivity, or piece transfers are temporarily unavailable.
WebRTC and Livestreaming
Section titled “WebRTC and Livestreaming”| Capability | Boundary |
|---|---|
| WebRTC | Independent voice-chat and P2P-media sessions using ICE/STUN/TURN and their respective use_voice_chat and use_p2p_media permissions |
| RTMP publish | Publisher entry, usually used by streamer or room admin |
| HTTP-FLV | Low-latency live playback, sensitive to long connections and slow clients |
| HLS | Playlist/segment files; multi-replica requires local proxy, shared file, or S3 backend |
WebRTC configuration is in WebRTC Configuration. Livestreaming is in Livestream Configuration.
Troubleshooting Matrix
Section titled “Troubleshooting Matrix”| Symptom | Likely layer | Check |
|---|---|---|
| Player gets 403 immediately | Provider credential or header | Provider headers and upstream status |
| Seek fails | Range or slice cache | Accept-Ranges, Content-Range, proxy logs |
| Browser only fails | CORS or header restrictions | Use proxy and inspect browser Network |
| Proxy only fails | Server-to-upstream network or headers | DNS, server network, proxy headers |
| Multi-replica live randomly fails | HLS storage model | Publisher node, shared storage, S3, gRPC proxy |
| URL stops working later | expires_at |
Observe or fetch a new playback |