Skip to content

Playback and Proxy

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.

  1. The client requests the current room playback or a playback for a media item.
  2. SyncTV uses room state, media, user, Provider credentials, and client profile to build Playback.
  3. The Provider returns one or more PlaybackInfo entries with URL, format, headers, subtitles, expiry, and metadata.
  4. The client chooses direct URL, proxy URL, transcode variant, HLS, FLV, or subtitle URL.
  5. When URL expiry, media switch, credential change, or client capability changes, the client requests fresh playback info.
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.

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.

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 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

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.

Seeking usually depends on HTTP Range:

Range: bytes=1048576-2097151

Proxy 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.

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.

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.

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.

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