Skip to main content

Class: ContentUriResolver

Defined in: packages/player/src/content-uri.ts:82

Rewrites Android content:// URIs into fd:// URLs mpv can open, once per URI, for the life of the player.

Remarks

Why one descriptor per URI and not one per open. A source resolver's answers must be deterministic: mpv opens each playlist entry twice — once speculatively on the prefetch path, once for real — and reuses the prefetched stream only when the two URLs match byte-for-byte (mpv 0.41.0 player/loadfile.c:1223; see SourceResolver's remarks). A fresh descriptor per call would produce a different URL per call, so every prefetch would be dropped and every track would open cold — the exact failure the resolver documentation warns about, with a leaked descriptor on top. Minting once and caching is what makes the rewrite invisible to the prefetcher.

Why fd:// and not fdclose://. fdclose:// has mpv close the descriptor when the stream ends (stream/stream_file.c:313). That is incompatible with a URL that has to stay valid for the entry's whole lifetime: the same fd://n is opened again on a replay, on loop, on a jumpTo back, and on the play-time pass after a prefetch mpv decided to drop. mpv rewinds the descriptor on every open (stream_file.c:373-374, lseek(fd, 0, SEEK_END) then SEEK_SET), so reopening is correct — provided nobody closed it. Ownership therefore stays here, and destroy is what releases it.

The one edge, stated plainly. mpv reads the descriptor with read() (stream_file.c:126), which advances the descriptor's own file offset, so two streams open on one descriptor at the same time would interleave their reads. That needs the same content:// URI at two adjacent queue positions — mpv prefetching entry n+1 while entry n plays — since nothing else has two streams open at once. A duplicated track elsewhere in the queue, a replay, a loop: all sequential, all fine. Deduplicate adjacent identical content:// entries if your queue can produce them.

Constructors

Constructor

new ContentUriResolver(opener: ContentUriOpener): ContentUriResolver;

Defined in: packages/player/src/content-uri.ts:89

Parameters

ParameterTypeDescription
openerContentUriOpenerThe platform binding; see ContentUriOpener.

Returns

ContentUriResolver

Accessors

openCount

Get Signature

get openCount(): number;

Defined in: packages/player/src/content-uri.ts:139

How many descriptors are open. Tests and diagnostics only.

Returns

number

Methods

destroy()

destroy(): void;

Defined in: packages/player/src/content-uri.ts:131

Close every descriptor. Called by Player.destroy(); idempotent.

Returns

void


resolve()

resolve(uri: string): string;

Defined in: packages/player/src/content-uri.ts:104

The URL mpv should open for uri.

Parameters

ParameterTypeDescription
uristringAny URI. Anything that is not content:// is returned unchanged and costs one prefix comparison.

Returns

string

fd://<n>, stable for the life of this resolver.

Throws

PlayerErrorException with code load-failed when the platform could not open the URI — an expired grant, a deleted row, an uninstalled provider. The caller reports it on the typed error channel and lets mpv fail on the logical URI, so the failure is never silent.