Media Sources
SyncTV does not store media files. It resolves external media into playback results, then lets clients play directly or through the SyncTV proxy. The resolving layer is called a Provider.
What Providers Do
Section titled “What Providers Do”| Capability | Meaning |
|---|---|
| Browse and search | List media from Alist, Emby/Jellyfin, Bilibili, remote services, or other backends |
| Resolve playback | Return playback URLs, proxy URLs, headers, subtitles, variants, or metadata |
| Manage credentials | Store tokens, cookies, API keys, or account credentials for upstream services |
| Expose behavior | Tell clients whether direct play, proxying, Range, livestreaming, or backend features are available |
A Provider returns a playback decision, not only a URL. Clients should use the headers and proxy mode returned by the Provider instead of inventing User-Agent, Referer, Cookie, or Range rules.
A playback result can return upstream and proxy modes together, such as direct/proxy_direct, dash/proxy_dash, HLS quality modes, and their proxy siblings. Each Provider performs signing and mode selection during generate_playback because Bilibili DASH, Alist HLS, Emby/Jellyfin transcoding, RTMP, and live proxy all have different URLs, headers, manifests, subtitles, and resource lifecycles.
generate_playback is the Provider playback decision boundary. Providers create direct/proxy modes, default_mode, headers, signed proxy URLs, manifest/subtitle rewriting, danmaku, thumbnails, and lifecycle metadata there. Shared helpers only perform mechanical proxy_* sibling URL generation; each Provider chooses when to use them, which mode is default, and which headers are exposed.
Provider cache stores VersionedPlayback: the raw PlaybackResult, proxy
lookup version, and expiry. It supports cache hits and provider-proxy URL
lookup; the signed response shape still comes from the Provider rewrite
callback. Cache hits and fresh responses must expose the same usable modes,
resolver actions, manifest/segment routes, and auxiliary URLs.
When adding or refactoring a Provider, keep signing timing, URL expiry, default mode, proxy siblings, manifest/segment rewriting, and live resource lifecycle inside that Provider’s generate_playback and proxy resolver. Shared code should express mechanical steps that are genuinely common across Providers.
HTTP, gRPC, and management APIs treat PlaybackResult as the source of truth. They translate transport parameters and encode responses while Provider policy stays in the core provider layer.
Playback Content Contract
Section titled “Playback Content Contract”| Provider | Required coverage |
|---|---|
| Direct URL | upstream mode, proxy_* sibling, proxy default for sources with headers, HLS manifest segment rewriting, Range. |
| Alist | direct/transcode modes, proxy_* siblings, thumbnail, subtitle, HLS segment, stream proxy resolver. |
| Emby/Jellyfin | upstream/transcode modes, proxy siblings, allowed upstream token headers, direct stream, HLS/transcode, subtitle proxy. |
| Bilibili | anonymous playback, DASH/MPD proxy default, proxy manifest segments, subtitles, danmaku, thumbnails, cache metadata, CDN headers. |
| RTMP | publish key, stream info, HLS playlist/segment, FLV, provider-proxy URL, idle cleanup. |
| live proxy | external RTMP/HTTP-FLV pull, HLS/FLV provider-proxy URL, publisher registration, idle cleanup unregister. |
Every URL returned to clients needs a real request test. When adding a mode, add the resolver, cache hit/expiry handling, URL expiry handling, and manual E2E coverage at the same time.
Common Sources
Section titled “Common Sources”| Source | Good for | Watch out for |
|---|---|---|
| Direct URL | A stable URL already reachable by clients | Browser header restrictions |
| Alist | Cloud drive and file browsing | Upstream auth, directory permissions, Range support |
| Emby/Jellyfin | Existing media libraries | Transcoding, subtitles, bitrate, upstream user permissions |
| Bilibili | Platform video resolving | Cookie, Referer, UA, and upstream policy changes |
| Remote Provider | Isolating media resolving into another service | Auth, network, and version compatibility |
| RTMP/live | Room livestreaming | Multi-replica HLS backend or publisher-node proxy |
Security Boundary
Section titled “Security Boundary”Provider credentials are sensitive. Configure security.credential_encryption_key in production, and keep tokens, cookies, and API keys out of logs, shell history, and public configuration.
End-to-End Verification Boundary
Section titled “End-to-End Verification Boundary”After changing Provider, proxy, signing, manifest, subtitle, RTMP, or live proxy behavior, verify with a built synctv binary, the synctv CLI, and curl. Cover Direct URL, Alist, Emby, Jellyfin, Bilibili anonymous playback, RTMP, live proxy, HLS, FLV, Range, cache miss/hit paths, URL expiry, and cleanup.
The verification target is the full PlaybackResult: every mode, URL, manifest, indexed segment, subtitle, danmaku, thumbnail, and proxy sibling should be requested. Add CLI coverage before accepting a provider workflow that can only be exercised through direct database writes or ad hoc internal calls.
Next Steps
Section titled “Next Steps”- Add media by source: Add Media.
- Understand direct/proxy playback: Playback Model.
- Configure Provider behavior: Media Providers.